鸿蒙实战开辟:视频播放器实现(上)

海哥  金牌会员 | 2024-6-14 21:23:53 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 976|帖子 976|积分 2928

鸿蒙实战开辟:视频播放器实现(上) 
鸿蒙实战开辟:视频播放器实现(中)
鸿蒙实战开辟:视频播放器实现(下) 
ArkTS 提供了 @ohos.multimedia.media 模块来处理音视频相干媒体业务,它提供了音视频播放和录制的功能,通过 AVPlayer 类,可以实现音视频的播放。下面我们利用AVPlayer实现一个简朴的视频播放器。
AVPlayer的工作流程

在正式进入播放器开辟前,我们先来认识一下AVPlayer的工作流程,下图是根据官方的状态变化示意图重新绘制的流程图:



  • 我们要实现一个播放器,首先需要利用createAVPlayer()创建一个播放器实例,此时播放器会进入idle状态,也就是闲置状态。如果我们调用了reset()来重置播放器,此时播放器也会进入闲置状态
  • 在闲置状态,给播放器设置播放源,即设置播放器的 url 或 的 fdSrc,播放器就会进入initialized状态,也就是初始化状态。在初始化状态,需要给播放器设置播放窗口,才气显示视频画面。
  • 在初始化状态调用prepare()方法,播放器会进入prepared状态,也就是预备状态,此时播放器的资源已预备就绪。如果在播放器的制止状态调用了prepare()方法,播放器会重新进入prepared状态。
  • 在预备状态调用play()方法,播放器就会进入playing状态,即正在播放状态。如果在播放器的制止、播放完成状态调用play()方法,播放器会重新进入播放状态。
  • 在播放状态中调用了pause()方法,播放器就会进入paused状态,即暂停状态。如果此时调用了play()方法,播放器会进入playing状态,继承播放媒体资源。
  • 当媒体资源播放至结尾时,如果用户没有设置循环播放(loop = 1),播放器就会进入completed状态,即完成状态。如果这个时候调用play()会进入playing状态重播媒体资源。
  • 在prepared、playing、paused、completed状态是调用stop()方法,播放器就会进入stopped状态,即制止状态,此时的播放器会释放内存资源。在这个时候,可以调用prepare()方法让播放器进入预备状态,重新播放媒体资源。也可以调用reset()方法重置播放器,让其回到闲置状态,大概调用release()方法彻底销毁播放器。
了解完播放器的工作流程后,我们就正式开始播放器的开辟。
视频播放器实现

实现播放器的焦点,就是监听播放器状态,在对应的状态中执行下一步的动作。
1、创建播放器

首先我们建一个播放器工具类,在工具类中利用media.createAVPlayer() 方法创建一个AVPlayer播放器实例。
  1. import media from '@ohos.multimedia.media'
  2. export class VideoAVPlayerClass {
  3.   // 创建的播放器应该存在我们的工具类上,这样才能被导出使用
  4.   static player: media.AVPlayer | null = null
  5.   
  6.   // 创建播放器的方法
  7.   static async  init() {
  8.     // 创建播放器实例
  9.     VideoAVPlayerClass.player = await media.createAVPlayer()
  10.    
  11.   }
  12. }
复制代码

2、监听状态

因为播放器的实现焦点,就是监听播放器状态,然后在对应的状态中执行下一步动作。同时,我们也需要根据播放器的状态来设置页面的展示,因此需要监听播放器的状态。
  1. import media from '@ohos.multimedia.media'
  2. export class VideoAVPlayerClass {
  3.   // 创建的播放器应该存在我们的工具类上,这样才能被导出使用
  4.   static player: media.AVPlayer | null = null
  5.   
  6.   // 创建播放器的方法
  7.   static async  init() {
  8.     // 创建播放器实例
  9.     VideoAVPlayerClass.player = await media.createAVPlayer()
  10.     // ----------------------- 事件监听 --------------------------------------------------------------
  11.     // 用于进度条,监听进度条长度,刷新资源时长
  12.     VideoAVPlayerClass.avPlayer.on('durationUpdate', (duration: number) => {
  13.       console.info('AVPlayer state durationUpdate called. current time: ', duration);
  14.     })
  15.     // 用于进度条,监听进度条当前位置,刷新当前时间
  16.     VideoAVPlayerClass.avPlayer.on('timeUpdate', (time) =>{
  17.       console.info('AVPlayer state timeUpdate called. current time: ', time);
  18.     })
  19.     // 监听seek生效的事件
  20.     VideoAVPlayerClass.avPlayer.on('seekDone', (seekDoneTime: number) => {
  21.       console.info(`AVPlayer seek succeeded, seek time is ${seekDoneTime}`);
  22.       VideoAVPlayerClass.avPlayer.play()
  23.       VideoAVPlayerClass.isPlay = true
  24.     })
  25.     // 监听视频播放错误事件,当avPlayer在操作过程中出现错误时调用reset接口触发重置流程
  26.     VideoAVPlayerClass.avPlayer.on('error', (err) => {
  27.       console.error(`Invoke avPlayer failed, code is ${err.code}, message is ${err.message}`);
  28.       // 调用reset重置资源,触发idle状态
  29.       VideoAVPlayerClass.avPlayer.reset()
  30.     })
  31.     // 监听播放状态机AVPlayerState切换的事件
  32.     VideoAVPlayerClass.avPlayer.on('stateChange', async (state: media.AVPlayerState, reason: media.StateChangeReason) => {
  33.       switch (state) {
  34.       // 成功调用reset接口后触发该状态机上报
  35.         case 'idle':
  36.           console.info('AVPlayer state idle called.');
  37.           break
  38.        // avplayer 设置播放源后触发该状态上报
  39.         case 'initialized':
  40.           console.info('AVPlayerstate initialized called.');
  41.           break
  42.       // prepare调用成功后上报该状态机
  43.         case 'prepared':
  44.           console.info('AVPlayer state prepared called.');
  45.           break
  46.       // play成功调用后触发该状态机上报
  47.         case 'playing':
  48.           console.info('AVPlayer state playing called.');
  49.           break
  50.       // pause成功调用后触发该状态机上报
  51.         case 'paused':
  52.           console.info('AVPlayer state paused called.');
  53.           break
  54.       // 播放结束后触发该状态机上报
  55.         case 'completed':
  56.           console.info('AVPlayer state completed called.');
  57.           break
  58.       // stop接口成功调用后触发该状态机上报
  59.         case 'stopped':
  60.           console.info('AVPlayer state stopped called.');
  61.         // 调用reset接口初始化avplayer状态
  62.           VideoAVPlayerClass.avPlayer.reset()
  63.           break
  64.         case 'released':
  65.           console.info('AVPlayer state released called.');
  66.           break;
  67.         default:
  68.           console.info('AVPlayer state unknown called.');
  69.           break;
  70.       }
  71.     })
  72.   }
  73. }
复制代码

在当前的实现中,我们紧张监听了播放器的durationUpdate、timeUpdate、seekDone、stateChange事件。
3、设置播放源

我们提供一个changePlay方法,在这个方法中完成播放源的设置,在设置播放源前,应该先将播放器的状态重置为闲置状态。
  1. import media from '@ohos.multimedia.media'
  2. export class VideoAVPlayerClass {
  3.   // 创建的播放器应该存在我们的工具类上,这样才能被导出使用
  4.   static player: media.AVPlayer | null = null
  5.   
  6.   // 创建播放器的方法
  7.   static async  init() {
  8.     // 创建播放器实例
  9.     VideoAVPlayerClass.player = await media.createAVPlayer()
  10.     // ----------------------- 事件监听 --------------------------------------------------------------
  11.     // 用于进度条,监听进度条长度,刷新资源时长
  12.     VideoAVPlayerClass.avPlayer.on('durationUpdate', (duration: number) => {
  13.       console.info('AVPlayer state durationUpdate called. current time: ', duration);
  14.     })
  15.     // 用于进度条,监听进度条当前位置,刷新当前时间
  16.     VideoAVPlayerClass.avPlayer.on('timeUpdate', (time) =>{
  17.       console.info('AVPlayer state timeUpdate called. current time: ', time);
  18.     })
  19.     // 监听seek生效的事件
  20.     VideoAVPlayerClass.avPlayer.on('seekDone', (seekDoneTime: number) => {
  21.       console.info(`AVPlayer seek succeeded, seek time is ${seekDoneTime}`);
  22.       VideoAVPlayerClass.avPlayer.play()
  23.       VideoAVPlayerClass.isPlay = true
  24.     })
  25.     // 监听视频播放错误事件,当avPlayer在操作过程中出现错误时调用reset接口触发重置流程
  26.     VideoAVPlayerClass.avPlayer.on('error', (err) => {
  27.       console.error(`Invoke avPlayer failed, code is ${err.code}, message is ${err.message}`);
  28.       // 调用reset重置资源,触发idle状态
  29.       VideoAVPlayerClass.avPlayer.reset()
  30.     })
  31.     // 监听播放状态机AVPlayerState切换的事件
  32.     VideoAVPlayerClass.avPlayer.on('stateChange', async (state: media.AVPlayerState, reason: media.StateChangeReason) => {
  33.       switch (state) {
  34.       // 成功调用reset接口后触发该状态机上报
  35.         case 'idle':
  36.           console.info('AVPlayer state idle called.');
  37.           break
  38.        // avplayer 设置播放源后触发该状态上报
  39.         case 'initialized':
  40.           console.info('AVPlayerstate initialized called.');
  41.           break
  42.       // prepare调用成功后上报该状态机
  43.         case 'prepared':
  44.           console.info('AVPlayer state prepared called.');
  45.           break
  46.       // play成功调用后触发该状态机上报
  47.         case 'playing':
  48.           console.info('AVPlayer state playing called.');
  49.           break
  50.       // pause成功调用后触发该状态机上报
  51.         case 'paused':
  52.           console.info('AVPlayer state paused called.');
  53.           break
  54.       // 播放结束后触发该状态机上报
  55.         case 'completed':
  56.           console.info('AVPlayer state completed called.');
  57.           break
  58.       // stop接口成功调用后触发该状态机上报
  59.         case 'stopped':
  60.           console.info('AVPlayer state stopped called.');
  61.         // 调用reset接口初始化avplayer状态
  62.           VideoAVPlayerClass.avPlayer.reset()
  63.           break
  64.         case 'released':
  65.           console.info('AVPlayer state released called.');
  66.           break;
  67.         default:
  68.           console.info('AVPlayer state unknown called.');
  69.           break;
  70.       }
  71.     })
  72.   }
  73.   
  74.   static async changePlay() {
  75.     // 将播放状态置为闲置
  76.     await VideoAVPlayerClass.avPlayer.reset()
  77.     VideoAVPlayerClass.avPlayer.url = VideoAVPlayerClass.playList[VideoAVPlayerClass.playIndex].url
  78.   }
  79. }
复制代码

4、设置播放窗口

用AVPlayer播放视频,需要设置播放窗谈锋能显示画面,从XComponent组件获取surfaceId后设置给播放器实例的surfaceId属性。
首先在播放器类中定义一个surfaceId变量来存储从XComponent组件获取的surfaceId,然后在init()方法中将surfaceId存储到播放器类上,在播放器的初始化状态设置播放器的播放窗口。
  1. import media from '@ohos.multimedia.media'
  2. export class VideoAVPlayerClass {
  3.   // 创建的播放器应该存在我们的工具类上,这样才能被导出使用
  4.   static player: media.AVPlayer | null = null
  5.   // surfaceID用于播放画面显示,具体的值需要通过XComponent接口获取
  6.   static surfaceId: string = ''
  7.   
  8.   // 创建播放器的方法
  9.   static async init(initParams: InitParams) {
  10.     // 存储属性SurfaceID,用于设置播放窗口,显示画面
  11.     VideoAVPlayerClass.surfaceId = initParams.surfaceId
  12.     // 创建播放器实例
  13.     VideoAVPlayerClass.player = await media.createAVPlayer()
  14.     // ----------------------- 事件监听 --------------------------------------------------------------
  15.     // 用于进度条,监听进度条长度,刷新资源时长
  16.     VideoAVPlayerClass.avPlayer.on('durationUpdate', (duration: number) => {
  17.       console.info('AVPlayer state durationUpdate called. current time: ', duration);
  18.     })
  19.     // 用于进度条,监听进度条当前位置,刷新当前时间
  20.     VideoAVPlayerClass.avPlayer.on('timeUpdate', (time) =>{
  21.       console.info('AVPlayer state timeUpdate called. current time: ', time);
  22.     })
  23.     // 监听seek生效的事件
  24.     VideoAVPlayerClass.avPlayer.on('seekDone', (seekDoneTime: number) => {
  25.       console.info(`AVPlayer seek succeeded, seek time is ${seekDoneTime}`);
  26.       VideoAVPlayerClass.avPlayer.play()
  27.       VideoAVPlayerClass.isPlay = true
  28.     })
  29.     // 监听视频播放错误事件,当avPlayer在操作过程中出现错误时调用reset接口触发重置流程
  30.     VideoAVPlayerClass.avPlayer.on('error', (err) => {
  31.       console.error(`Invoke avPlayer failed, code is ${err.code}, message is ${err.message}`);
  32.       // 调用reset重置资源,触发idle状态
  33.       VideoAVPlayerClass.avPlayer.reset()
  34.     })
  35.     // 监听播放状态机AVPlayerState切换的事件
  36.     VideoAVPlayerClass.avPlayer.on('stateChange', async (state: media.AVPlayerState, reason: media.StateChangeReason) => {
  37.       switch (state) {
  38.       // 成功调用reset接口后触发该状态机上报
  39.         case 'idle':
  40.           console.info('AVPlayer state idle called.');
  41.           break
  42.        // avplayer 设置播放源后触发该状态上报
  43.         case 'initialized':
  44.           console.info('AVPlayerstate initialized called.');
  45.           // 设置显示画面,当播放的资源为纯音频时无需设置
  46.           VideoAVPlayerClass.avPlayer.surfaceId = VideoAVPlayerClass.surfaceId
  47.           break
  48.       // prepare调用成功后上报该状态机
  49.         case 'prepared':
  50.           console.info('AVPlayer state prepared called.');
  51.           break
  52.       // play成功调用后触发该状态机上报
  53.         case 'playing':
  54.           console.info('AVPlayer state playing called.');
  55.           break
  56.       // pause成功调用后触发该状态机上报
  57.         case 'paused':
  58.           console.info('AVPlayer state paused called.');
  59.           break
  60.       // 播放结束后触发该状态机上报
  61.         case 'completed':
  62.           console.info('AVPlayer state completed called.');
  63.           break
  64.       // stop接口成功调用后触发该状态机上报
  65.         case 'stopped':
  66.           console.info('AVPlayer state stopped called.');
  67.         // 调用reset接口初始化avplayer状态
  68.           VideoAVPlayerClass.avPlayer.reset()
  69.           break
  70.         case 'released':
  71.           console.info('AVPlayer state released called.');
  72.           break;
  73.         default:
  74.           console.info('AVPlayer state unknown called.');
  75.           break;
  76.       }
  77.     })
  78.   }
  79.   
  80.   static async changePlay() {
  81.     // 将播放状态置为闲置
  82.     await VideoAVPlayerClass.avPlayer.reset()
  83.     VideoAVPlayerClass.avPlayer.url = VideoAVPlayerClass.playList[VideoAVPlayerClass.playIndex].url
  84.   }
  85. }
复制代码

5、获取播放信息

在页面中,需要展示当前播放视频的视频时长、播放时长以及播放器状态,因此我们需要获取视频的播放信息。我们先获取视频时长、当前播放时长、视频是否播放这三个播放信息。


  • 获取视频时长
通过监听播放器的durationUpdate事件,可以获取视频资源的总时长。在播放器类中定义一个duration变量来存储视频时长,然后监听durationUpdate事件获取视频时长。
  1. import media from '@ohos.multimedia.media'
  2. export class VideoAVPlayerClass {
  3.   // 创建的播放器应该存在我们的工具类上,这样才能被导出使用
  4.   static player: media.AVPlayer | null = null
  5.   // 当前播放器播放视频的总时长
  6.   static duration: number = 0
  7.   // surfaceID用于播放画面显示,具体的值需要通过XComponent接口获取
  8.   static surfaceId: string = ''
  9.   
  10.   // 创建播放器的方法
  11.   static async init(initParams: InitParams) {
  12.     // 存储属性SurfaceID,用于设置播放窗口,显示画面
  13.     VideoAVPlayerClass.surfaceId = initParams.surfaceId
  14.     // 创建播放器实例
  15.     VideoAVPlayerClass.player = await media.createAVPlayer()
  16.     // ----------------------- 事件监听 --------------------------------------------------------------
  17.     // 用于进度条,监听进度条长度,刷新资源时长
  18.     VideoAVPlayerClass.avPlayer.on('durationUpdate', (duration: number) => {
  19.         console.info('AVPlayer state durationUpdate called. current time: ', duration);
  20.         // 获取视频总时长
  21.         VideoAVPlayerClass.duration = duration
  22.     })
  23.     // 用于进度条,监听进度条当前位置,刷新当前时间
  24.     VideoAVPlayerClass.avPlayer.on('timeUpdate', (time) =>{
  25.       console.info('AVPlayer state timeUpdate called. current time: ', time);
  26.     })
  27.     // 监听seek生效的事件
  28.     VideoAVPlayerClass.avPlayer.on('seekDone', (seekDoneTime: number) => {
  29.       console.info(`AVPlayer seek succeeded, seek time is ${seekDoneTime}`);
  30.       VideoAVPlayerClass.avPlayer.play()
  31.       VideoAVPlayerClass.isPlay = true
  32.     })
  33.     // 监听视频播放错误事件,当avPlayer在操作过程中出现错误时调用reset接口触发重置流程
  34.     VideoAVPlayerClass.avPlayer.on('error', (err) => {
  35.       console.error(`Invoke avPlayer failed, code is ${err.code}, message is ${err.message}`);
  36.       // 调用reset重置资源,触发idle状态
  37.       VideoAVPlayerClass.avPlayer.reset()
  38.     })
  39.     // 监听播放状态机AVPlayerState切换的事件
  40.     VideoAVPlayerClass.avPlayer.on('stateChange', async (state: media.AVPlayerState, reason: media.StateChangeReason) => {
  41.       switch (state) {
  42.       // 成功调用reset接口后触发该状态机上报
  43.         case 'idle':
  44.           console.info('AVPlayer state idle called.');
  45.           break
  46.        // avplayer 设置播放源后触发该状态上报
  47.         case 'initialized':
  48.           console.info('AVPlayerstate initialized called.');
  49.           // 设置显示画面,当播放的资源为纯音频时无需设置
  50.           VideoAVPlayerClass.avPlayer.surfaceId = VideoAVPlayerClass.surfaceId
  51.           break
  52.       // prepare调用成功后上报该状态机
  53.         case 'prepared':
  54.           console.info('AVPlayer state prepared called.');
  55.           break
  56.       // play成功调用后触发该状态机上报
  57.         case 'playing':
  58.           console.info('AVPlayer state playing called.');
  59.           break
  60.       // pause成功调用后触发该状态机上报
  61.         case 'paused':
  62.           console.info('AVPlayer state paused called.');
  63.           break
  64.       // 播放结束后触发该状态机上报
  65.         case 'completed':
  66.           console.info('AVPlayer state completed called.');
  67.           break
  68.       // stop接口成功调用后触发该状态机上报
  69.         case 'stopped':
  70.           console.info('AVPlayer state stopped called.');
  71.         // 调用reset接口初始化avplayer状态
  72.           VideoAVPlayerClass.avPlayer.reset()
  73.           break
  74.         case 'released':
  75.           console.info('AVPlayer state released called.');
  76.           break;
  77.         default:
  78.           console.info('AVPlayer state unknown called.');
  79.           break;
  80.       }
  81.     })
  82.   }
  83.   
  84.   static async changePlay() {
  85.     // 将播放状态置为闲置
  86.     await VideoAVPlayerClass.avPlayer.reset()
  87.     VideoAVPlayerClass.avPlayer.url = VideoAVPlayerClass.playList[VideoAVPlayerClass.playIndex].url
  88.   }
  89. }
复制代码



  • 获取当前播放时长
通过监听播放器的timeUpdate事件,可以获取当前的播放时长。在播放器类中定义一个
timeUpdate变量来存储当前播放时长,然后监听timeUpdate事件获取视频当前播放时长。
  1. import media from '@ohos.multimedia.media'
  2. export class VideoAVPlayerClass {
  3.   // 创建的播放器应该存在我们的工具类上,这样才能被导出使用
  4.   static player: media.AVPlayer | null = null
  5.   // 当前播放器播放视频的总时长
  6.   static duration: number = 0
  7.   // 当前播放器播放的时长
  8.   static time: number = 0
  9.   // surfaceID用于播放画面显示,具体的值需要通过XComponent接口获取
  10.   static surfaceId: string = ''
  11.   
  12.   // 创建播放器的方法
  13.   static async init(initParams: InitParams) {
  14.     // 存储属性SurfaceID,用于设置播放窗口,显示画面
  15.     VideoAVPlayerClass.surfaceId = initParams.surfaceId
  16.     // 创建播放器实例
  17.     VideoAVPlayerClass.player = await media.createAVPlayer()
  18.     // ----------------------- 事件监听 --------------------------------------------------------------
  19.     // 用于进度条,监听进度条长度,刷新资源时长
  20.     VideoAVPlayerClass.avPlayer.on('durationUpdate', (duration: number) => {
  21.         console.info('AVPlayer state durationUpdate called. current time: ', duration);
  22.         // 获取视频总时长
  23.         VideoAVPlayerClass.duration = duration
  24.     })
  25.     // 用于进度条,监听进度条当前位置,刷新当前时间
  26.     VideoAVPlayerClass.avPlayer.on('timeUpdate', (time) =>{
  27.       console.info('AVPlayer state timeUpdate called. current time: ', time);
  28.       // 获取当前播放时长
  29.       VideoAVPlayerClass.time = time
  30.     })
  31.     // 监听seek生效的事件
  32.     VideoAVPlayerClass.avPlayer.on('seekDone', (seekDoneTime: number) => {
  33.       console.info(`AVPlayer seek succeeded, seek time is ${seekDoneTime}`);
  34.       VideoAVPlayerClass.avPlayer.play()
  35.       VideoAVPlayerClass.isPlay = true
  36.     })
  37.     // 监听视频播放错误事件,当avPlayer在操作过程中出现错误时调用reset接口触发重置流程
  38.     VideoAVPlayerClass.avPlayer.on('error', (err) => {
  39.       console.error(`Invoke avPlayer failed, code is ${err.code}, message is ${err.message}`);
  40.       // 调用reset重置资源,触发idle状态
  41.       VideoAVPlayerClass.avPlayer.reset()
  42.     })
  43.     // 监听播放状态机AVPlayerState切换的事件
  44.     VideoAVPlayerClass.avPlayer.on('stateChange', async (state: media.AVPlayerState, reason: media.StateChangeReason) => {
  45.       switch (state) {
  46.       // 成功调用reset接口后触发该状态机上报
  47.         case 'idle':
  48.           console.info('AVPlayer state idle called.');
  49.           break
  50.        // avplayer 设置播放源后触发该状态上报
  51.         case 'initialized':
  52.           console.info('AVPlayerstate initialized called.');
  53.           // 设置显示画面,当播放的资源为纯音频时无需设置
  54.           VideoAVPlayerClass.avPlayer.surfaceId = VideoAVPlayerClass.surfaceId
  55.           break
  56.       // prepare调用成功后上报该状态机
  57.         case 'prepared':
  58.           console.info('AVPlayer state prepared called.');
  59.           break
  60.       // play成功调用后触发该状态机上报
  61.         case 'playing':
  62.           console.info('AVPlayer state playing called.');
  63.           break
  64.       // pause成功调用后触发该状态机上报
  65.         case 'paused':
  66.           console.info('AVPlayer state paused called.');
  67.           break
  68.       // 播放结束后触发该状态机上报
  69.         case 'completed':
  70.           console.info('AVPlayer state completed called.');
  71.           break
  72.       // stop接口成功调用后触发该状态机上报
  73.         case 'stopped':
  74.           console.info('AVPlayer state stopped called.');
  75.         // 调用reset接口初始化avplayer状态
  76.           VideoAVPlayerClass.avPlayer.reset()
  77.           break
  78.         case 'released':
  79.           console.info('AVPlayer state released called.');
  80.           break;
  81.         default:
  82.           console.info('AVPlayer state unknown called.');
  83.           break;
  84.       }
  85.     })
  86.   }
  87.   
  88.   static async changePlay() {
  89.     // 将播放状态置为闲置
  90.     await VideoAVPlayerClass.avPlayer.reset()
  91.     VideoAVPlayerClass.avPlayer.url = VideoAVPlayerClass.playList[VideoAVPlayerClass.playIndex].url
  92.   }
  93. }
复制代码

获取是否播放状态
页面需要根据是否播放状态来展示播放/暂停按钮,因此我们需要记录是否播放状态。在播放器类中定义isPlay变量来记录是否播放状态,默认是暂停状态。
  1. import media from '@ohos.multimedia.media'
  2. export class VideoAVPlayerClass {
  3.   // 创建的播放器应该存在我们的工具类上,这样才能被导出使用
  4.   static player: media.AVPlayer | null = null
  5.   // 当前播放器播放视频的总时长
  6.   static duration: number = 0
  7.   // 当前播放器播放的时长
  8.   static time: number = 0
  9.   // 当前播放器是否播放
  10.   static isPlay: boolean = false
  11.   // surfaceID用于播放画面显示,具体的值需要通过XComponent接口获取
  12.   static surfaceId: string = ''
  13.   
  14.   // 创建播放器的方法
  15.   static async init(initParams: InitParams) {
  16.     // 存储属性SurfaceID,用于设置播放窗口,显示画面
  17.     VideoAVPlayerClass.surfaceId = initParams.surfaceId
  18.     // 创建播放器实例
  19.     VideoAVPlayerClass.player = await media.createAVPlayer()
  20.     // ----------------------- 事件监听 --------------------------------------------------------------
  21.     // 用于进度条,监听进度条长度,刷新资源时长
  22.     VideoAVPlayerClass.avPlayer.on('durationUpdate', (duration: number) => {
  23.         console.info('AVPlayer state durationUpdate called. current time: ', duration);
  24.         // 获取视频总时长
  25.         VideoAVPlayerClass.duration = duration
  26.     })
  27.     // 用于进度条,监听进度条当前位置,刷新当前时间
  28.     VideoAVPlayerClass.avPlayer.on('timeUpdate', (time) =>{
  29.       console.info('AVPlayer state timeUpdate called. current time: ', time);
  30.       // 获取当前播放时长
  31.       VideoAVPlayerClass.time = time
  32.     })
  33.     // 监听seek生效的事件
  34.     VideoAVPlayerClass.avPlayer.on('seekDone', (seekDoneTime: number) => {
  35.       console.info(`AVPlayer seek succeeded, seek time is ${seekDoneTime}`);
  36.       VideoAVPlayerClass.avPlayer.play()
  37.       VideoAVPlayerClass.isPlay = true
  38.     })
  39.     // 监听视频播放错误事件,当avPlayer在操作过程中出现错误时调用reset接口触发重置流程
  40.     VideoAVPlayerClass.avPlayer.on('error', (err) => {
  41.       console.error(`Invoke avPlayer failed, code is ${err.code}, message is ${err.message}`);
  42.       // 调用reset重置资源,触发idle状态
  43.       VideoAVPlayerClass.avPlayer.reset()
  44.     })
  45.     // 监听播放状态机AVPlayerState切换的事件
  46.     VideoAVPlayerClass.avPlayer.on('stateChange', async (state: media.AVPlayerState, reason: media.StateChangeReason) => {
  47.       switch (state) {
  48.       // 成功调用reset接口后触发该状态机上报
  49.         case 'idle':
  50.           console.info('AVPlayer state idle called.');
  51.           break
  52.        // avplayer 设置播放源后触发该状态上报
  53.         case 'initialized':
  54.           console.info('AVPlayerstate initialized called.');
  55.           // 设置显示画面,当播放的资源为纯音频时无需设置
  56.           VideoAVPlayerClass.avPlayer.surfaceId = VideoAVPlayerClass.surfaceId
  57.           break
  58.       // prepare调用成功后上报该状态机
  59.         case 'prepared':
  60.           console.info('AVPlayer state prepared called.');
  61.           break
  62.       // play成功调用后触发该状态机上报
  63.         case 'playing':
  64.           console.info('AVPlayer state playing called.');
  65.           break
  66.       // pause成功调用后触发该状态机上报
  67.         case 'paused':
  68.           console.info('AVPlayer state paused called.');
  69.           break
  70.       // 播放结束后触发该状态机上报
  71.         case 'completed':
  72.           console.info('AVPlayer state completed called.');
  73.           break
  74.       // stop接口成功调用后触发该状态机上报
  75.         case 'stopped':
  76.           console.info('AVPlayer state stopped called.');
  77.         // 调用reset接口初始化avplayer状态
  78.           VideoAVPlayerClass.avPlayer.reset()
  79.           break
  80.         case 'released':
  81.           console.info('AVPlayer state released called.');
  82.           break;
  83.         default:
  84.           console.info('AVPlayer state unknown called.');
  85.           break;
  86.       }
  87.     })
  88.   }
  89.   
  90.   static async changePlay() {
  91.     // 将播放状态置为闲置
  92.     await VideoAVPlayerClass.avPlayer.reset()
  93.     VideoAVPlayerClass.avPlayer.url = VideoAVPlayerClass.playList[VideoAVPlayerClass.playIndex].url
  94.   }
  95. }
复制代码

至此,我们实现了播放器的一些根本设置,还不能实现视频的播放,视频的播放功能实现将在下一篇分享

最后

有很多小同伴不知道学习哪些鸿蒙开辟技术?不知道需要重点掌握哪些鸿蒙应用开辟知识点?而且学习时频繁踩坑,终极浪费大量时间。所以有一份实用的鸿蒙(HarmonyOS NEXT)资料用来跟着学习黑白常有必要的。 
为了可以或许资助各人快速掌握鸿蒙(HarmonyOS NEXT)应用开辟技术知识。在此给各人分享一下我联合鸿蒙最新资料整理出来的鸿蒙南北向开辟学习路线以及整理的最新版鸿蒙学习文档资料。
这份鸿蒙(HarmonyOS NEXT)资料包罗了鸿蒙开辟必掌握的焦点知识要点,内容包罗了ArkTS、ArkUI开辟组件、Stage模型、多端部署、分布式应用开辟、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、Harmony南向开辟、鸿蒙项目实战等等)鸿蒙(HarmonyOS NEXT)技术知识点。
渴望这一份鸿蒙学习资料可以或许给各人带来资助,有需要的小同伴自行领取,限时开源,先到先得~无套路领取!!
如果你是一名有经验的资深Android移动开辟、Java开辟、前端开辟、对鸿蒙感爱好以及转行人员,可以直接领取这份资料
 获取这份完备版高清学习路线,请点击→纯血版全套鸿蒙HarmonyOS学习资料
鸿蒙(HarmonyOS NEXT)最新学习路线




  •  HarmonOS基础技能



  • HarmonOS就业必备技能 

  •  HarmonOS多媒体技术



  • 鸿蒙NaPi组件进阶



  • HarmonOS高级技能



  • 初识HarmonOS内核 

  • 实战就业级设备开辟

 有了路线图,怎么能没有学习资料呢,小编也预备了一份团结鸿蒙官方发布条记整理收纳的一套体系性的鸿蒙(OpenHarmony )学习手册(共计1236页)鸿蒙(OpenHarmony )开辟入门讲授视频,内容包罗:ArkTS、ArkUI、Web开辟、应用模型、资源分类…等知识点。
获取以上完备版高清学习路线,请点击→纯血版全套鸿蒙HarmonyOS学习资料
《鸿蒙 (OpenHarmony)开辟入门讲授视频》


《鸿蒙生态应用开辟V2.0白皮书》


《鸿蒙 (OpenHarmony)开辟基础到实战手册》

OpenHarmony北向、南向开辟情况搭建

 《鸿蒙开辟基础》



  • ArkTS语言
  • 安装DevEco Studio
  • 运用你的第一个ArkTS应用
  • ArkUI声明式UI开辟
  • .……

 《鸿蒙开辟进阶》



  • Stage模型入门
  • 网络管理
  • 数据管理
  • 电话服务
  • 分布式应用开辟
  • 通知与窗口管理
  • 多媒体技术
  • 安全技能
  • 任务管理
  • WebGL
  • 国际化开辟
  • 应用测试
  • DFX面向未来筹划
  • 鸿蒙体系移植和裁剪定制
  • ……

《鸿蒙进阶实战》



  • ArkTS实践
  • UIAbility应用
  • 网络案例
  • ……

 获取以上完备鸿蒙HarmonyOS学习资料,请点击→纯血版全套鸿蒙HarmonyOS学习资料
总结

总的来说,华为鸿蒙不再兼容安卓,对中年步伐员来说是一个寻衅,也是一个时机。只有积极应对变化,不断学习和提升本身,他们才气在这个厘革的期间中立于不败之地。 



免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

海哥

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表