新建一个ETS文件
import media from '@ohos.multimedia.media';
import common from '@ohos.app.ability.common';
export default class AVPlayerManager {
public avPlayer: media.AVPlayer = null;
// 注册avplayer回调函数
setAVPlayerCallback(avPlayer: media.AVPlayer, surfaceId: string) {
// seek操作结果回调函数
avPlayer.on('seekDone', (seekDoneTime: number) => {
console.info(`AVPlayer seek succeeded, seek time is ${seekDoneTime}`);
})
// error回调监听函数,当avPlayer在操作过程中出现错误时调用reset接口触发重置流程
avPlayer.on('error', (err) => {
console.error(`Invoke avPlayer failed, code is ${err.code}, message is ${err.message}`);
avPlayer.reset(); // 调用reset重置资源,触发idle状态
})
// 状态机变化回调函数
avPlayer.on('stateChange', async (state: string, reason: media.StateChangeReason) => {
switch (state) {
case 'idle': // 成功调用reset接口后触发该状态机上报
console.info('==AVPlayer state idle called.');
avPlayer.release(); // 调用release接口销毁实例对象
break;
case 'initialized': // avplayer 设置播放源后触发该状态上报
console.info('==AVPlayer state initialized called.');
avPlayer.surfaceId = surfaceId; // 设置显示画面,当播放的资源为纯音频时无需设置
avPlayer.prepare();
break;
case 'prepared': // prepare调用成功后上报该状态机
console.info('==AVPlayer state prepared called.');
break;
case 'playing': // play成功调用后触发该状态机上报
console.info('==AVPlayer state playing called.');
break;
case 'paused': // pause成功调用后触发该状态机上报
console.info('==AVPlayer state paused called.');
break;
case 'completed': // 播放结束后触发该状态机上报
console.info('==AVPlayer state completed called.');
avPlayer.stop(); //调用播放结束接口
break;
case 'stopped': // stop接口成功调用后触发该状态机上报
console.info('==AVPlayer state stopped called.');
// avPlayer.reset(); // 调用reset接口初始化avplayer状态
break;
case 'released':
console.info('==AVPlayer state released called.');
break;
default:
console.info('==AVPlayer state unknown called.');
break;
}
})
}
// 以下demo为使用资源管理接口获取打包在HAP内的媒体资源文件并通过fdSrc属性进行播放示例
async avPlayerFdSrcDemo(surfaceId: string) {
// 创建avPlayer实例对象
this.avPlayer = await media.createAVPlayer();
// 创建状态机变化回调函数
this.setAVPlayerCallback(this.avPlayer, surfaceId);
// 通过UIAbilityContext的resourceManager成员的getRawFd接口获取媒体资源播放地址
// 返回类型为{fd,offset,length},fd为HAP包fd地址,offset为媒体资源偏移量,length为播放长度
let context = getContext(this) as common.UIAbilityContext;
let fileDescriptor = await context.resourceManager.getRawFd('harmonyos.mp4');
let avFileDescriptor: media.AVFileDescriptor =
{
fd: fileDescriptor.fd, offset: fileDescriptor.offset, length: fileDescriptor.length
};
// 为fdSrc赋值触发initialized状态机上报
this.avPlayer.fdSrc = avFileDescriptor;
}
// 视频播放
videoPlay() {
if (this.avPlayer.state === 'prepared' || this.avPlayer.state === 'paused' || this.avPlayer.state === 'completed') {
this.avPlayer.play()
}else {
this.avPlayer.prepare()
this.avPlayer.play()
}
}
// 视频暂停
videoPause() {
if (this.avPlayer.state === 'playing') {
this.avPlayer.pause()
}
}
//视频停止
videoStop() {
if (this.avPlayer.state === 'playing') {
this.avPlayer.stop()
}
}
}
视频播放UI
import media from '@ohos.multimedia.media';
import AVPlayerManager from '../datamodel/AVPlayerManager';
@Entry
@Component
struct AvplayerPage {
@State XComponentFlag: boolean = true;
@State avPlayManage: AVPlayerManager = new AVPlayerManager();
private xComponentController: XComponentController = new XComponentController();
private surfaceId: string = '';
@Builder xComponentBuilder() {
XComponent({
id: 'xComponent',
type: 'surface',
controller: this.xComponentController }) // 装载视频容器
.visibility(this.XComponentFlag ? Visibility.Visible : Visibility.Hidden)
.onLoad(() => {
this.surfaceId = this.xComponentController.getXComponentSurfaceId()
this.avPlayManage.avPlayerFdSrcDemo(this.surfaceId)
})
.width('100%')
.height('60%')
}
@Builder buttonBuilder(item: string, action: () => void) {
Button(item)
.stateEffect(true)
.backgroundColor('#ffffff')
.fontColor('#000000')
.fontSize(25)
.padding(3)
.type(ButtonType.Normal)
.onClick(action)
}
build() {
Column() {
this.xComponentBuilder()
Flex({ wrap: FlexWrap.Wrap, justifyContent: FlexAlign.SpaceAround, alignItems: ItemAlign.Center }) {
this.buttonBuilder('播放', () => {
this.avPlayManage.videoPlay()
})
this.buttonBuilder('暂停', () => {
this.avPlayManage.videoPause()
})
this.buttonBuilder('停止', () => {
this.avPlayManage.videoStop()
})
}
}
.width('100%')
.height('100%')
}
}
新建一个页面
import { VideoOptions } from '../datamodel/VideoModel';
@Entry
@Component
struct VideoPage {
@State playRate: number = 1
private videoPlayController: VideoController = new VideoController()
@State muted: boolean = false
@State autoPlay: boolean = true
@State controls: boolean = true
@State startStatus: boolean = true
@State loop: boolean = true
@State videoOptions: VideoOptions = {
src: $rawfile('harmonyos.mp4'), //待带播放的视频资源 对于rawfile目录资源,通过"$rawfile('filename')"形式引用。
previewUri: $r('app.media.harmonyos'), //视频封面
currentProgressRate: this.playRate, //播放速率
controller: this.videoPlayController //视频播放控制器
}
@Builder buttonBuilder(item: string, action: () => void) {
Button(item)
.stateEffect(true)
.backgroundColor('#ffffff')
.fontColor('#000000')
.fontSize(25)
.padding(3)
.type(ButtonType.Normal)
.onClick(action.bind(this))
}
build() {
Column({ space: 20 }) {
Text('Video实现视频播放')
.fontSize(30)
.fontWeight(FontWeight.Bold)
//Video组件
Video(this.videoOptions)
.muted(this.muted) // 是否静音
.autoPlay(this.autoPlay) // 是否自动播放
.controls(this.controls) // 控制视频播放的控制栏是否显示
.objectFit(ImageFit.Contain) // 视频显示模式
.loop(this.loop) // 是否单个视频循环播放
.height("60%")
.onStart(() => {
// 播放时触发该事件
console.info('onStart');
})
.onPause(() => {
// 暂停时触发该事件
console.info('onPause');
})
.onFinish(() => {
console.info('onFinish');
})
.onError(() => {
// 播放失败时触发该事件
console.error('onError');
})
.onFullscreenChange((e) => {
console.info('视频进入和退出全屏时触发该事件:' + e.fullscreen)
})
.onPrepared((e) => {
console.info('视频准备完成时触发该事件:' + e.duration)
})
.onSeeking((e) => {
console.info('操作进度条过程时上报时间信息:' + e.time)
})
.onSeeked((e) => {
console.info('操作进度条完成后,上报播放时间信息:' + e.time)
})
.onUpdate((e) => {
console.info('播放进度变化时触发该事件:' + e.time)
})
Flex({ wrap: FlexWrap.Wrap, justifyContent: FlexAlign.SpaceAround, alignItems: ItemAlign.Center }) {
this.buttonBuilder('播放', () => {
this.videoPlayController.start()
})
this.buttonBuilder('暂停', () => {
this.videoPlayController.pause()
})
this.buttonBuilder('静音', () => {
this.muted = !this.muted
})
this.buttonBuilder('停止', () => {
this.videoPlayController.stop()
})
this.buttonBuilder('循环播放', () => {
this.loop = !this.loop
})
this.buttonBuilder('全屏播放', () => {
this.videoPlayController.requestFullscreen(true)
})
this.buttonBuilder('退出全屏', () => {
this.videoPlayController.requestFullscreen(false)
})
this.buttonBuilder('控制栏显示', () => {
this.controls = !this.controls
})
}
}
.width('100%')
.height('100%')
}
}