简介
媒体子系统是 OpenHarmony 中重要的子系统,可以提供音视频播放能力。媒体子系统为开发者提供一套简单且易于理解的接口,使得开发者能够方便接入系统并使用系统的媒体资源。媒体子系统提供以下常用功能:
- 音视频播放(AVPlayer9+),AudioPlayer6+ 和 VideoPlayer8+ 整合,升级了状态机和错误码,推荐使用
- 音视频录制(AVRecorder9+),AudioRecorder6+ 和 VideoRecorder9+ 整合,推荐使用
- 音频播放(AudioPlayer6+),AVPlayer9+ 发布后停止维护,请使用 AVPlayer9+
- 视频播放(VideoPlayer8+),AVPlayer9+ 发布后停止维护,请使用 AVPlayer9+
- 音频录制(AudioRecorder6+),AVRecorder9+ 发布后停止维护,请使用 AVRecorder9+
- 视频录制(VideoRecorder9+),AVRecorder9+ 发布后停止维护,请使用 AVRecorder9+
从 3.2 开始 OpenHarmony 推出了 AVPlayer 和 AVRecorder 接口,之前的 VideoPlayer、AudioPlayer 这些接口会停止维护,所以我们今天学习下怎么使用 AVPlayer 接口
导入模块
import media from '@ohos.multimedia.media';`
- 创建 avplayer
this.avPlayer = await media.createAVPlayer()`
如上,我们使用的是 promise 接口,对应的接口定义为:
/*** Creates an AVPlayer instance.* @since 9* @syscap SystemCapability.Multimedia.Media.AVPlayer* @param callback Callback used to return AVPlayer instance if the operation is successful; returns null otherwise.* @throws { BusinessError } 5400101 - No memory. Return by callback.*/function createAVPlayer(callback: AsyncCallback<AVPlayer>): void;/*** Creates an AVPlayer instance.* @since 9* @syscap SystemCapability.Multimedia.Media.AVPlayer* @returns A Promise instance used to return AVPlayer instance if the operation is successful; returns null otherwise.* @throws { BusinessError } 5400101 - No memory. Return by promise.*/function createAVPlayer() : Promise<AVPlayer>;` * 注册 avplayer 回调`//注册状态变化回调,不同状态时做不同动作avPlayer.on('stateChange', async (state, reason) => {……})//注册时间变化回调,方便更新进度条时间avPlayer.on('timeUpdate', (time:number) => {……})
- avplayer 播放流程
//视频播放伪代码
async avPlayerDemo() {this.avPlayer.on('stateChange', async (state, reason) => {switch (state) {case 'idle': // 成功调用reset接口后触发该状态机上报console.info(TAG + 'state idle called')this.avPlayer.release() // 释放avplayer对象break;case 'initialized': // avplayer 设置播放源后触发该状态上报console.info(TAG + 'state initialized called ')this.avPlayer.surfaceId = this.surfaceID // 设置显示画面,当播放的资源为纯音频时无需设置this.avPlayer.prepare().then(() => {console.info(TAG+ 'prepare success');}, (err) => {console.error(TAG + 'prepare filed,error message is :' + err.message)})break;case 'prepared': // prepare调用成功后上报该状态机console.info(TAG + 'state prepared called')this.avPlayer.play() // 调用播放接口开始播放break;case 'playing': // play成功调用后触发该状态机上报console.info(TAG + 'state playing called')if (this.count == 0) {this.avPlayer.pause() // 调用暂停播放接口} else {this.avPlayer.seek(10000, media.SeekMode.SEEK_PREV_SYNC) // 前向seek置10秒处,触发seekDone回调函数}break;case 'paused': // pause成功调用后触发该状态机上报console.info(TAG + 'state paused called')if (this.count == 0) {this.count++this.avPlayer.play() // 继续调用播放接口开始播放}break;case 'completed': // 播放结束后触发该状态机上报console.info(TAG + 'state completed called')this.avPlayer.stop() //调用播放结束接口break;case 'stopped': // stop接口成功调用后触发该状态机上报console.info(TAG + 'state stopped called')this.avPlayer.reset() // 调用reset接口初始化avplayer状态break;case 'released':console.info(TAG + 'state released called')break;case 'error':console.info(TAG + 'state error called')break;default:console.info(TAG + 'unkown state :' + state)break;}})// 创建avPlayer实例对象this.avPlayer = await media.createAVPlayer()let fdPath = 'fd://'let pathDir = "/data/storage/el2/base/haps/entry/files" // pathDir在FA模型和Stage模型的获取方式不同,请参考开发步骤首行的说明,根据实际情况自行获取。// path路径的码流可通过"hdc file send D:\xxx\H264_AAC.mp4 /data/app/el2/100/base/ohos.acts.multimedia.media.avplayer/haps/entry/files" 命令,将其推送到设备上let path = pathDir + '/H264_AAC.mp4'let file = await fs.open(path)fdPath = fdPath + '' + file.fd//赋值url后就会进入stateChange callbackthis.avPlayer.url = fdPath
}
- 其他播放控制接口
/*** Prepare audio/video playback, it will request resource for playing.* @since 9* @syscap SystemCapability.Multimedia.Media.AVPlayer* @param callback A callback instance used to return when prepare completed.* @throws { BusinessError } 5400102 - Operation not allowed. Return by callback.* @throws { BusinessError } 5400106 - Unsupport format. Return by callback.*/prepare(callback: AsyncCallback<void>): void;/*** Prepare audio/video playback, it will request resource for playing.* @since 9* @syscap SystemCapability.Multimedia.Media.AVPlayer* @returns A Promise instance used to return when prepare completed.* @throws { BusinessError } 5400102 - Operation not allowed. Return by promise.* @throws { BusinessError } 5400106 - Unsupport format. Return by promise.*/prepare(): Promise<void>;/*** Play audio/video playback.* @since 9* @syscap SystemCapability.Multimedia.Media.AVPlayer* @param callback A callback instance used to return when play completed.* @throws { BusinessError } 5400102 - Operation not allowed. Return by callback.*/play(callback: AsyncCallback<void>): void;/*** Play audio/video playback.* @since 9* @syscap SystemCapability.Multimedia.Media.AVPlayer* @returns A Promise instance used to return when play completed.* @throws { BusinessError } 5400102 - Operation not allowed. Return by promise.*/play(): Promise<void>;/*** Pause audio/video playback.* @since 9* @syscap SystemCapability.Multimedia.Media.AVPlayer* @param callback A callback instance used to return when pause completed.* @throws { BusinessError } 5400102 - Operation not allowed. Return by callback.*/pause(callback: AsyncCallback<void>): void;/*** Pause audio/video playback.* @since 9* @syscap SystemCapability.Multimedia.Media.AVPlayer* @returns A Promise instance used to return when pause completed.* @throws { BusinessError } 5400102 - Operation not allowed. Return by promise.*/pause(): Promise<void>;/*** Stop audio/video playback.* @since 9* @syscap SystemCapability.Multimedia.Media.AVPlayer* @param callback A callback instance used to return when stop completed.* @throws { BusinessError } 5400102 - Operation not allowed. Return by callback.*/stop(callback: AsyncCallback<void>): void;/*** Stop audio/video playback.* @since 9* @syscap SystemCapability.Multimedia.Media.AVPlayer* @returns A Promise instance used to return when stop completed.* @throws { BusinessError } 5400102 - Operation not allowed. Return by promise.*/stop(): Promise<void>;/*** Reset AVPlayer, it will to idle state and can set src again.* @since 9* @syscap SystemCapability.Multimedia.Media.AVPlayer* @param callback A callback instance used to return when reset completed.* @throws { BusinessError } 5400102 - Operation not allowed. Return by callback.*/reset(callback: AsyncCallback<void>): void;/*** Reset AVPlayer, it will to idle state and can set src again.* @since 9* @syscap SystemCapability.Multimedia.Media.AVPlayer* @returns A Promise instance used to return when reset completed.* @throws { BusinessError } 5400102 - Operation not allowed. Return by promise.*/reset(): Promise<void>;/*** Releases resources used for AVPlayer.* @since 9* @syscap SystemCapability.Multimedia.Media.AVPlayer* @param callback A callback instance used to return when release completed.* @throws { BusinessError } 5400102 - Operation not allowed. Return by callback.*/release(callback: AsyncCallback<void>): void;/*** Releases resources used for AVPlayer.* @since 9* @syscap SystemCapability.Multimedia.Media.AVPlayer* @returns A Promise instance used to return when release completed.* @throws { BusinessError } 5400102 - Operation not allowed. Return by promise.*/release(): Promise<void>;/*** Jumps to the specified playback position.* @since 9* @syscap SystemCapability.Multimedia.Media.AVPlayer* @param timeMs Playback position to jump, should be in [0, duration].* @param mode See @SeekMode .*/seek(timeMs: number, mode?:SeekMode): void;`
- 其他回调接口
/*** Register or unregister listens for media playback events.* @since 9* @syscap SystemCapability.Multimedia.Media.AVPlayer* @param type Type of the playback event to listen for.* @param callback Callback used to listen for the playback stateChange event.*/on(type: 'stateChange', callback: (state: AVPlayerState, reason: StateChangeReason) => void): void;off(type: 'stateChange'): void;/*** Register or unregister listens for media playback events.* @since 9* @syscap SystemCapability.Multimedia.Media.AVPlayer* @param type Type of the playback event to listen for.* @param callback Callback used to listen for the playback volume event.*/on(type: 'volumeChange', callback: Callback<number>): void;off(type: 'volumeChange'): void;/*** Register or unregister listens for media playback events.* @since 9* @syscap SystemCapability.Multimedia.Media.AVPlayer* @param type Type of the playback event to listen for.* @param callback Callback used to listen for the playback end of stream*/on(type: 'endOfStream', callback: Callback<void>): void;off(type: 'endOfStream'): void;/*** Register or unregister listens for media playback events.* @since 9* @syscap SystemCapability.Multimedia.Media.AVPlayer* @param type Type of the playback event to listen for.* @param callback Callback used to listen for the playback seekDone event.*/on(type: 'seekDone', callback: Callback<number>): void;off(type: 'seekDone'): void;/*** Register or unregister listens for media playback events.* @since 9* @syscap SystemCapability.Multimedia.Media.AVPlayer* @param type Type of the playback event to listen for.* @param callback Callback used to listen for the playback speedDone event.*/on(type: 'speedDone', callback: Callback<number>): void;off(type: 'speedDone'): void;/*** Register or unregister listens for media playback events.* @since 9* @syscap SystemCapability.Multimedia.Media.AVPlayer* @param type Type of the playback event to listen for.* @param callback Callback used to listen for the playback setBitrateDone event.*/on(type: 'bitrateDone', callback: Callback<number>): void;off(type: 'bitrateDone'): void;/*** LRegister or unregister listens for media playback events.* @since 9* @syscap SystemCapability.Multimedia.Media.AVPlayer* @param type Type of the playback event to listen for.* @param callback Callback used to listen for the playback timeUpdate event.*/on(type: 'timeUpdate', callback: Callback<number>): void;off(type: 'timeUpdate'): void;/*** Register or unregister listens for media playback events.* @since 9* @syscap SystemCapability.Multimedia.Media.AVPlayer* @param type Type of the playback event to listen for.* @param callback Callback used to listen for the playback durationUpdate event.*/on(type: 'durationUpdate', callback: Callback<number>): void;off(type: 'durationUpdate'): void;/*** Register or unregister listens for video playback buffering events.* @since 9* @syscap SystemCapability.Multimedia.Media.AVPlayer* @param type Type of the playback buffering update event to listen for.* @param callback Callback used to listen for the buffering update event, return BufferingInfoType and the value.*/on(type: 'bufferingUpdate', callback: (infoType: BufferingInfoType, value: number) => void): void;off(type: 'bufferingUpdate'): void;/*** Register or unregister listens for start render video frame events.* @since 9* @syscap SystemCapability.Multimedia.Media.AVPlayer* @param type Type of the playback event to listen for.* @param callback Callback used to listen for the playback event return .*/on(type: 'startRenderFrame', callback: Callback<void>): void;off(type: 'startRenderFrame'): void;/*** Register or unregister listens for video size change event.* @since 9* @syscap SystemCapability.Multimedia.Media.AVPlayer* @param type Type of the playback event to listen for.* @param callback Callback used to listen for the playback event return video size.*/on(type: 'videoSizeChange', callback: (width: number, height: number) => void): void;off(type: 'videoSizeChange'): void;/*** Register or unregister listens for audio interrupt event, refer to {@link #audio.InterruptEvent}* @since 9* @syscap SystemCapability.Multimedia.Media.AVPlayer* @param type Type of the playback event to listen for.* @param callback Callback used to listen for the playback event return audio interrupt info.*/on(type: 'audioInterrupt', callback: (info: audio.InterruptEvent) => void): void;off(type: 'audioInterrupt'): void;/*** Register or unregister listens for available bitrate list collect completed events for HLS protocol stream playback.* This event will be reported after the {@link #prepare} called.* @since 9* @syscap SystemCapability.Multimedia.Media.AVPlayer* @param type Type of the playback event to listen for.* @param callback Callback used to listen for the playback event return available bitrate list.*/on(type: 'availableBitrates', callback: (bitrates: Array<number>) => void): void;off(type: 'availableBitrates'): void;
简单样例
- 界面
build() {Stack({ alignContent: Alignment.Center }) {if (this.isShowMenu) {Column() {//视频名称PlayTitle({ title: this.displayName, handleBack: this.handleBack })Row() {//播放控件PreVideo({ handleClick: this.handlePrevClick })PlayButton({ isPlaying: $isPlaying })NextVideo({ handleClick: this.handleNextClick })}.margin({ top: '40%' })Blank()//时间刻度Row() {Text(getTimeString(this.currentTime)).fontSize(25).fontColor(Color.White)Blank()Text(this.fileAsset ? getTimeString(this.fileAsset.duration) : '00:00').fontSize(25).fontColor(Color.White)}.width('95%')//进度条Slider({ value: this.fileAsset ? this.currentTime / this.fileAsset.duration * 100 : 0 }).width('92%').selectedColor(Color.White).onChange((value: number) => {Logger.info(TAG, 'seek time change')this.currentTime = this.fileAsset.duration * value / 100this.videoPlayer.seek(this.currentTime)})}.height('100%').zIndex(2)}Row() {XComponent({id: 'componentId',type: 'surface',controller: this.mxcomponentController}).onLoad(() => {Logger.info(TAG, 'onLoad is called')this.playVideo()}).width('100%').aspectRatio(this.ratio)}.height('100%').width('100%').justifyContent(FlexAlign.Center)}.width('100%').height('100%').backgroundColor(Color.Black).onClick(() => {this.isShowMenu = !this.isShowMenu})}
- 播放
//根据视频文件获取视频源尺寸并生成surface//视频文件的路径在/storage/media/100/local/files/Videosasync prepareVideo() {this.ratio = this.fileAsset.width / this.fileAsset.heightthis.mxcomponentController.setXComponentsurfaceSize({surfaceWidth: this.fileAsset.width,surfaceHeight: this.fileAsset.height})this.surfaceId = this.mxcomponentController.getXComponentsurfaceId()this.fd = await this.fileAsset.open('Rw')Logger.info(TAG, `fd://' ${this.fd} `)return 'fd://' + this.fd}//初始化视频文件并初始化avplayerasync playVideo() {Logger.info(TAG, 'playVideo')try{await this.getMediaList()let fdPath = await this.prepareVideo()this.videoPlayer.on('timeUpdate', (time:number) => {console.info('timeUpdate success,and new time is :' + time)this.currentTime = time;})await this.videoPlayer.initVideoPlayer(fdPath, this.surfaceId)this.isPlaying = true}catch(error) {Logger.info(TAG, `playVideo error ${JSON.stringify(error)}`)}}
为了能让大家更好的学习鸿蒙(HarmonyOS NEXT)开发技术,这边特意整理了《鸿蒙开发学习手册》(共计890页),希望对大家有所帮助:https://qr21.cn/FV7h05
《鸿蒙开发学习手册》:
如何快速入门:https://qr21.cn/FV7h05
- 基本概念
- 构建第一个ArkTS应用
- ……
开发基础知识:https://qr21.cn/FV7h05
- 应用基础知识
- 配置文件
- 应用数据管理
- 应用安全管理
- 应用隐私保护
- 三方应用调用管控机制
- 资源分类与访问
- 学习ArkTS语言
- ……
基于ArkTS 开发:https://qr21.cn/FV7h05
- Ability开发
- UI开发
- 公共事件与通知
- 窗口管理
- 媒体
- 安全
- 网络与链接
- 电话服务
- 数据管理
- 后台任务(Background Task)管理
- 设备管理
- 设备使用信息统计
- DFX
- 国际化开发
- 折叠屏系列
- ……
鸿蒙开发面试真题(含参考答案):https://qr18.cn/F781PH
鸿蒙开发面试大盘集篇(共计319页):https://qr18.cn/F781PH
1.项目开发必备面试题
2.性能优化方向
3.架构方向
4.鸿蒙开发系统底层方向
5.鸿蒙音视频开发方向
6.鸿蒙车载开发方向
7.鸿蒙南向开发方向