HarmonyOS鸿蒙版播放器

概述

目睹播放器是基于鸿蒙HarmonyOS的多媒体视频播放器SDK。为开发者提供了简单易用的帮助开发者方便快捷、低门槛的实现多媒体播放功能的开发。 它支持 HLS、MP4、FLV 等多种流媒体播放格式,视频支持 h264 格式、音频支持 AAC 格式。

开发准备

环境要求 (下载请联系商务)

  • DevEco Studio 5.0.3及以上版本
  • HarmonyOS 5.0.0(API 12)以上版本
  • 开发模型基于 stageMode 模型

集成SDK

  1. 将mdplayer-v2.x.x.har 放入library包下
  2. 项目包管理文件 entry/src/oh-package.json5dependencies 添加如下内容:
    {
     ...
     "dependencies": {
       "@mudu/player": "file:./library/mdplayer-v2.x.x.har"
     }
     ...
    }
    
  3. 具体模块使用导入
    import { MuduVideoView } from '@mudu/player'
    
  4. 配置APP权限, 模块文件entry/src/main/module.json5requestPermissions添加:
     { 
     ...
     "requestPermissions": [
       {
         "name": "ohos.permission.INTERNET"
       },
       {
         "name": "ohos.permission.GET_NETWORK_INFO"
       }
     ]
     ...
     }
    

快速开始

全局播放器内核设置:
此播放器包含不同播放器内核,请在初始化之前进行配置,不设置默认为系统播放器。切换方法如下:
1、系统播放器:
MDPlayerContext.getContext().setObject(MDPlayerContextType.PLAYER_TYPE, MDPlayerType.SYSTEM_PLAYER);
2、ijk播放器:
MDPlayerContext.getContext().setObject(MDPlayerContextType.PLAYER_TYPE, MDPlayerType.IJK_PLAYER);
  1. 定义初始化回调

     import { IVideoPlayerController } from '@mudu/player'
    
     @Component
     export struct xxx {
       ...
       //初始化回调方法,返回 IVideoPlayerController 为播放组件控制接口
       init: (iVideoPlayer: IVideoPlayerController, xid: string) => void
              = (iVideoPlayer: IVideoPlayerController, xid: string) => {
    
         this.mPlayerController = iVideoPlayer
         this.xComponentId = xid
    
         this.play()
       }
     }
    
  2. 导入并配置 MuduVideoView 视图 ``` import { MuduVideoView } from '@mudu/player'

build() { ... MuduVideoView({init: this.init}) .width(this.videoWidth) .height(this.videoHeight) ... }


3. 设置播放地址并开始播放

// 开始播放 play() { if (this.mPlayerController) { this.mPlayerController.setUp(this.videoModel.getUrl()) this._videoJudgeToPlay() } } // 判断继续播放的流程 private _videoJudgeToPlay() {

if (!this.mPlayerController) return
if (MDPlayerContext.getContext().getObject(MDPlayerContextType.X_COMPONENT_ID) !== this.mPlayerController.xComponentId) {
  this.mPlayerController.play()
} else {
  if (this.mPlayerController.playStatus == MDPlayStatus.PAUSE) {
    this.mPlayerController.resumePlay()
  } else {
    this.mPlayerController.play()
  }
}

}


4. 暂停播放

pause() { this.mPlayerController?.pause() }


5. 退出释放

stop() { if (this.mPlayerController) { this.mPlayerController.stop() this.mPlayerController.release() } }


6. 播放控制事件监听

//添加事件监听 private _emitterInit() {

//初始化事件,包括播放完成,播放出错等需要重新初始化的事件
emitter.on(VideoControlIds.Init, (data: emitter.EventData) => {
  if (this.xComponentId && this.xComponentId == data?.data?.xid) {
    this.handleInit()
  }
})
//播放完成事件,同Init
emitter.on(VideoControlIds.Complete, (data: emitter.EventData) => {
  if (this.xComponentId && this.xComponentId == data?.data?.xid) {
    this.handleInit()
  }
})
//开始播放事件
emitter.on(VideoControlIds.Playing, (data: emitter.EventData) => {
  if (this.xComponentId && this.xComponentId == data?.data?.xid) {
    this.handlePlaying()
  } else {
    this.handleInit()
  }
})
//暂停事件
emitter.on(VideoControlIds.Pause, (data: emitter.EventData) => {
  if (this.xComponentId && this.xComponentId == data?.data?.xid) {
    this.handlePause()
  }
})

} //移除事件监听 private _emitterOff() { emitter.off(VideoControlIds.Playing) emitter.off(VideoControlIds.Init) emitter.off(VideoControlIds.Complete) emitter.off(VideoControlIds.Pause) }


7. 获取播放进度及总时长

//获取当前进度 let position = this.mPlayerController.getCurrentPosition() //获取总时长 let duration = this.mPlayerController.getDuration()



### 相关类介绍

#### MuduVideoView

| 成员方法        | 功能      |
|:------------|:--------|
| init        | 初始化回调函数 |
| version     | 获取版本号   |
| setLogLevel | 设置日志等级  |

#### IVideoPlayerController 播放控制器
| 成员属性         | 功能                     |
|:-------------|:-----------------------|
| surfaceId    | XComponent组件内surfaceId |
| xComponentId | XComponent组件Id         |
| videoUrl     | 播放地址                   |
| playStatus   | 当前播放状态                 |


| 成员方法               | 功能             |
|:-------------------|:---------------|
| setUp              | 设置视频播放地址       |
| play               | 开始播放           |
| resumePlay         | 恢复播放           |
| pause              | 暂停播放           |
| stop               | 停止播放           |
| release            | 播放器资源释放        |
| on                 | 设置播放事件监听       |
| off                | 删除播放事件监听       |
| seekTo             | 跳转至指定位置        |
| speed              | 设置播放倍速         |
| getDuration        | 获取视频时长         |
| getCurrentPosition | 获取当前播放位置       |
| isPlaying          | 是否在播放中         |
| setScaleType       | 设置画面比例类型       |
| shotFrame          | 截图返回PixelMap对象 |
| saveFrame          | 截图并保存          |

#### MDVideoModel
| 成员属性       | 功能     |
|:-----------|:-------|
| videoUrl   | 视频播放地址 |
| title      | 视频标题   |
| coverImage | 视频封面   |

### 枚举介绍

#### VideoControlIds 播放控制枚举
| 成员属性      | 功能              |
|:----------|:----------------|
| Init      | 初始化(包括播放完成、失败等) |
| Playing   | 开始播放            |
| Pause     | 暂停播放            |

#### MDPlayerEvents 播放器事件枚举
| 成员属性             | 功能      |
|:-----------------|:--------|
| STATE_CHANGE     | 播放状态    |
| TIME_UPDATE      | 进度更新    |
| ERROR            | 错误      |
| DURATION_UPDATE  | 时长更新    |
| SEEK_DONE        | 拖拽结束    |
| SPEED_DONE       | 倍速设置    |
| VOLUME_CHANGE    | 音量变化    |
| BUFFERING_UPDATE | 缓冲数据更新  |

#### MDPlayerEventState 播放器事件stateChange的状态
| 成员属性        | 功能      |
|:------------|:--------|
| IDLE        | 闲置状态    |
| INITIALIZED | 初始化完成   |
| PREPARED    | 准备完成    |
| PLAYING     | 播放中     |
| PAUSED      | 播放暂停    |
| COMPLETED   | 播放完成    |
| STOPPED     | 播放已停止   |
| RELEASED    | 播放器释放   |
| ERROR       | 发生错误    |

#### MDPlayerContextType 播放器上下文类型枚举
| 成员属性              | 功能    |
|:------------------|:------|
| PLAYER_CONTROLLER | 播放控制器 |


#### MDPlayStatus 播放器状态类型
| 成员属性   | 功能     |
|:-------|:-------|
| INIT   | 播放初始化  |
| PLAY   | 播放中    |
| PAUSE  | 播放暂停   |
| STOP   | 播放停止   |



### 后台播放
系统针对后台播放进行强制管控,未接入AVSession的应用在退到后台时,将会被强制暂停音频播放。解决应用在后台恶意播放,而用户无法找到对应应用无法关闭的问题。
(https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/avsession-overview-V5?catalogVersion=V5)

#### 申请后台运行权限
"requestPermissions": [
  ...
  {
    //允许Service Ability在后台持续运行。
    "name": "ohos.permission.KEEP_BACKGROUND_RUNNING"
  }
  ...
]

#### 开启长时任务
import backgroundTaskManager from '@ohos.resourceschedule.backgroundTaskManager'
import wantAgent from '@ohos.app.ability.wantAgent'
import bundleManager from '@ohos.bundle.bundleManager'
import { WantAgent } from '@ohos.wantAgent'
/**
 * 开启后台长时任务
 */
private async _startContinuousTask(){

  let wantAgentObj = await this._getWantAgent()
  backgroundTaskManager.startBackgroundRunning(getContext(this), backgroundTaskManager.BackgroundMode.AUDIO_PLAYBACK, wantAgentObj).then(() => {
    console.info(`Succeeded in operationing startBackgroundRunning.`)
  }).catch((err: BusinessError) => {
    console.error(`Failed to operation startBackgroundRunning. Code is ${err.code}, message is ${err.message}`)
  })
}

/**
 * 停止后台长时任务
 */
private _stopContinuousTask(){
  backgroundTaskManager.stopBackgroundRunning(getContext(this)).then(()=>{
    console.info(`Succeeded in operationing stopBackgroundRunning.`)
  }).catch((err: BusinessError) => {
    console.error(`Failed to operation stopBackgroundRunning. Code is ${err.code}, message is ${err.message}`)
  });
}

private async _getWantAgent():Promise<WantAgent>{

  let bundleFlags = bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_HAP_MODULE
  let bundleInfo = bundleManager.getBundleInfoForSelfSync(bundleFlags)

  let wantAgentInfo: wantAgent.WantAgentInfo = {
    wants: [
      {
        bundleName: bundleInfo.name,
        abilityName: `EntryAbility`
      }
    ],
    actionType: wantAgent.OperationType.START_ABILITY,
    requestCode: 0,
    wantAgentFlags: [wantAgent.WantAgentFlags.UPDATE_PRESENT_FLAG]
  }

  let wantAgentObj = await wantAgent.getWantAgent(wantAgentInfo)
  return Promise.resolve(wantAgentObj)
}


#### 创建AVSession媒体会话
import AVSessionManager from '@ohos.multimedia.avsession';

private async _createSession() {

  let type: AVSessionManager.AVSessionType = 'audio';
  let session = await AVSessionManager.createAVSession(getContext(this), 'SESSION_NAME', type);

  console.info(`session create done : sessionId : ${session.sessionId}`);

  let wantAgentObj = await this._getWantAgent()
  session.setLaunchAbility(wantAgentObj)

  session.activate()
  this.avSession = session
}

private _destroySession(){

  this.avSession?.deactivate(()=>{})
  this.avSession?.destroy()
}

```

results matching ""

    No results matching ""