HarmonyOS鸿蒙版播放器
概述
目睹播放器是基于鸿蒙HarmonyOS的多媒体视频播放器SDK。为开发者提供了简单易用的帮助开发者方便快捷、低门槛的实现多媒体播放功能的开发。 它支持 HLS、MP4、FLV 等多种流媒体播放格式,视频支持 h264 格式、音频支持 AAC 格式。
开发准备
环境要求 (下载请联系商务)
- DevEco Studio 5.0.3及以上版本
- HarmonyOS 5.0.0(API 12)以上版本
- 开发模型基于 stageMode 模型
集成SDK
- 将mdplayer-v2.x.x.har 放入library包下
- 项目包管理文件
entry/src/oh-package.json5
中dependencies
添加如下内容:{ ... "dependencies": { "@mudu/player": "file:./library/mdplayer-v2.x.x.har" } ... }
- 具体模块使用导入
import { MuduVideoView } from '@mudu/player'
- 配置APP权限, 模块文件
entry/src/main/module.json5
中requestPermissions
添加:{ ... "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);
定义初始化回调
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() } }
导入并配置
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()
}
```