当前位置:   article > 正文

鸿蒙实战开发:视频播放器实现(上)_鸿蒙 avplayer用法

鸿蒙 avplayer用法

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

鸿蒙实战开发:视频播放器实现(中)

鸿蒙实战开发:视频播放器实现(下) 

ArkTS 提供了 @ohos.multimedia.media 模块来处理音视频相关媒体业务,它提供了音视频播放和录制的功能,通过 AVPlayer 类,可以实现音视频的播放。下面我们使用AVPlayer实现一个简单的视频播放器。

AVPlayer的工作流程

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

  1. 我们要实现一个播放器,首先需要使用createAVPlayer()创建一个播放器实例,此时播放器会进入idle状态,也就是闲置状态。如果我们调用了reset()来重置播放器,此时播放器也会进入闲置状态
  2. 在闲置状态,给播放器设置播放源,即设置播放器的 url 或 的 fdSrc,播放器就会进入initialized状态,也就是初始化状态。在初始化状态,需要给播放器配置播放窗口,才能显示视频画面。
  3. 在初始化状态调用prepare()方法,播放器会进入prepared状态,也就是准备状态,此时播放器的资源已准备就绪。如果在播放器的停止状态调用了prepare()方法,播放器会重新进入prepared状态。
  4. 在准备状态调用play()方法,播放器就会进入playing状态,即正在播放状态。如果在播放器的停止、播放完成状态调用play()方法,播放器会重新进入播放状态。
  5. 在播放状态中调用了pause()方法,播放器就会进入paused状态,即暂停状态。如果此时调用了play()方法,播放器会进入playing状态,继续播放媒体资源。
  6. 当媒体资源播放至结尾时,如果用户没有设置循环播放(loop = 1),播放器就会进入completed状态,即完成状态。如果这个时候调用play()会进入playing状态重播媒体资源。
  7. 在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. static async init() {
  7. // 创建播放器实例
  8. VideoAVPlayerClass.player = await media.createAVPlayer()
  9. }
  10. }

2、监听状态

因为播放器的实现核心,就是监听播放器状态,然后在对应的状态中执行下一步动作。同时,我们也需要根据播放器的状态来设置页面的展示,因此需要监听播放器的状态。

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

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

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. static async init(initParams: InitParams) {
  9. // 存储属性SurfaceID,用于设置播放窗口,显示画面
  10. VideoAVPlayerClass.surfaceId = initParams.surfaceId
  11. // 创建播放器实例
  12. VideoAVPlayerClass.player = await media.createAVPlayer()
  13. // ----------------------- 事件监听 --------------------------------------------------------------
  14. // 用于进度条,监听进度条长度,刷新资源时长
  15. VideoAVPlayerClass.avPlayer.on('durationUpdate', (duration: number) => {
  16. console.info('AVPlayer state durationUpdate called. current time: ', duration);
  17. })
  18. // 用于进度条,监听进度条当前位置,刷新当前时间
  19. VideoAVPlayerClass.avPlayer.on('timeUpdate', (time) =>{
  20. console.info('AVPlayer state timeUpdate called. current time: ', time);
  21. })
  22. // 监听seek生效的事件
  23. VideoAVPlayerClass.avPlayer.on('seekDone', (seekDoneTime: number) => {
  24. console.info(`AVPlayer seek succeeded, seek time is ${seekDoneTime}`);
  25. VideoAVPlayerClass.avPlayer.play()
  26. VideoAVPlayerClass.isPlay = true
  27. })
  28. // 监听视频播放错误事件,当avPlayer在操作过程中出现错误时调用reset接口触发重置流程
  29. VideoAVPlayerClass.avPlayer.on('error', (err) => {
  30. console.error(`Invoke avPlayer failed, code is ${err.code}, message is ${err.message}`);
  31. // 调用reset重置资源,触发idle状态
  32. VideoAVPlayerClass.avPlayer.reset()
  33. })
  34. // 监听播放状态机AVPlayerState切换的事件
  35. VideoAVPlayerClass.avPlayer.on('stateChange', async (state: media.AVPlayerState, reason: media.StateChangeReason) => {
  36. switch (state) {
  37. // 成功调用reset接口后触发该状态机上报
  38. case 'idle':
  39. console.info('AVPlayer state idle called.');
  40. break
  41. // avplayer 设置播放源后触发该状态上报
  42. case 'initialized':
  43. console.info('AVPlayerstate initialized called.');
  44. // 设置显示画面,当播放的资源为纯音频时无需设置
  45. VideoAVPlayerClass.avPlayer.surfaceId = VideoAVPlayerClass.surfaceId
  46. break
  47. // prepare调用成功后上报该状态机
  48. case 'prepared':
  49. console.info('AVPlayer state prepared called.');
  50. break
  51. // play成功调用后触发该状态机上报
  52. case 'playing':
  53. console.info('AVPlayer state playing called.');
  54. break
  55. // pause成功调用后触发该状态机上报
  56. case 'paused':
  57. console.info('AVPlayer state paused called.');
  58. break
  59. // 播放结束后触发该状态机上报
  60. case 'completed':
  61. console.info('AVPlayer state completed called.');
  62. break
  63. // stop接口成功调用后触发该状态机上报
  64. case 'stopped':
  65. console.info('AVPlayer state stopped called.');
  66. // 调用reset接口初始化avplayer状态
  67. VideoAVPlayerClass.avPlayer.reset()
  68. break
  69. case 'released':
  70. console.info('AVPlayer state released called.');
  71. break;
  72. default:
  73. console.info('AVPlayer state unknown called.');
  74. break;
  75. }
  76. })
  77. }
  78. static async changePlay() {
  79. // 将播放状态置为闲置
  80. await VideoAVPlayerClass.avPlayer.reset()
  81. VideoAVPlayerClass.avPlayer.url = VideoAVPlayerClass.playList[VideoAVPlayerClass.playIndex].url
  82. }
  83. }

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. static async init(initParams: InitParams) {
  11. // 存储属性SurfaceID,用于设置播放窗口,显示画面
  12. VideoAVPlayerClass.surfaceId = initParams.surfaceId
  13. // 创建播放器实例
  14. VideoAVPlayerClass.player = await media.createAVPlayer()
  15. // ----------------------- 事件监听 --------------------------------------------------------------
  16. // 用于进度条,监听进度条长度,刷新资源时长
  17. VideoAVPlayerClass.avPlayer.on('durationUpdate', (duration: number) => {
  18. console.info('AVPlayer state durationUpdate called. current time: ', duration);
  19. // 获取视频总时长
  20. VideoAVPlayerClass.duration = duration
  21. })
  22. // 用于进度条,监听进度条当前位置,刷新当前时间
  23. VideoAVPlayerClass.avPlayer.on('timeUpdate', (time) =>{
  24. console.info('AVPlayer state timeUpdate called. current time: ', time);
  25. })
  26. // 监听seek生效的事件
  27. VideoAVPlayerClass.avPlayer.on('seekDone', (seekDoneTime: number) => {
  28. console.info(`AVPlayer seek succeeded, seek time is ${seekDoneTime}`);
  29. VideoAVPlayerClass.avPlayer.play()
  30. VideoAVPlayerClass.isPlay = true
  31. })
  32. // 监听视频播放错误事件,当avPlayer在操作过程中出现错误时调用reset接口触发重置流程
  33. VideoAVPlayerClass.avPlayer.on('error', (err) => {
  34. console.error(`Invoke avPlayer failed, code is ${err.code}, message is ${err.message}`);
  35. // 调用reset重置资源,触发idle状态
  36. VideoAVPlayerClass.avPlayer.reset()
  37. })
  38. // 监听播放状态机AVPlayerState切换的事件
  39. VideoAVPlayerClass.avPlayer.on('stateChange', async (state: media.AVPlayerState, reason: media.StateChangeReason) => {
  40. switch (state) {
  41. // 成功调用reset接口后触发该状态机上报
  42. case 'idle':
  43. console.info('AVPlayer state idle called.');
  44. break
  45. // avplayer 设置播放源后触发该状态上报
  46. case 'initialized':
  47. console.info('AVPlayerstate initialized called.');
  48. // 设置显示画面,当播放的资源为纯音频时无需设置
  49. VideoAVPlayerClass.avPlayer.surfaceId = VideoAVPlayerClass.surfaceId
  50. break
  51. // prepare调用成功后上报该状态机
  52. case 'prepared':
  53. console.info('AVPlayer state prepared called.');
  54. break
  55. // play成功调用后触发该状态机上报
  56. case 'playing':
  57. console.info('AVPlayer state playing called.');
  58. break
  59. // pause成功调用后触发该状态机上报
  60. case 'paused':
  61. console.info('AVPlayer state paused called.');
  62. break
  63. // 播放结束后触发该状态机上报
  64. case 'completed':
  65. console.info('AVPlayer state completed called.');
  66. break
  67. // stop接口成功调用后触发该状态机上报
  68. case 'stopped':
  69. console.info('AVPlayer state stopped called.');
  70. // 调用reset接口初始化avplayer状态
  71. VideoAVPlayerClass.avPlayer.reset()
  72. break
  73. case 'released':
  74. console.info('AVPlayer state released called.');
  75. break;
  76. default:
  77. console.info('AVPlayer state unknown called.');
  78. break;
  79. }
  80. })
  81. }
  82. static async changePlay() {
  83. // 将播放状态置为闲置
  84. await VideoAVPlayerClass.avPlayer.reset()
  85. VideoAVPlayerClass.avPlayer.url = VideoAVPlayerClass.playList[VideoAVPlayerClass.playIndex].url
  86. }
  87. }

  • 获取当前播放时长

通过监听播放器的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. static async init(initParams: InitParams) {
  13. // 存储属性SurfaceID,用于设置播放窗口,显示画面
  14. VideoAVPlayerClass.surfaceId = initParams.surfaceId
  15. // 创建播放器实例
  16. VideoAVPlayerClass.player = await media.createAVPlayer()
  17. // ----------------------- 事件监听 --------------------------------------------------------------
  18. // 用于进度条,监听进度条长度,刷新资源时长
  19. VideoAVPlayerClass.avPlayer.on('durationUpdate', (duration: number) => {
  20. console.info('AVPlayer state durationUpdate called. current time: ', duration);
  21. // 获取视频总时长
  22. VideoAVPlayerClass.duration = duration
  23. })
  24. // 用于进度条,监听进度条当前位置,刷新当前时间
  25. VideoAVPlayerClass.avPlayer.on('timeUpdate', (time) =>{
  26. console.info('AVPlayer state timeUpdate called. current time: ', time);
  27. // 获取当前播放时长
  28. VideoAVPlayerClass.time = time
  29. })
  30. // 监听seek生效的事件
  31. VideoAVPlayerClass.avPlayer.on('seekDone', (seekDoneTime: number) => {
  32. console.info(`AVPlayer seek succeeded, seek time is ${seekDoneTime}`);
  33. VideoAVPlayerClass.avPlayer.play()
  34. VideoAVPlayerClass.isPlay = true
  35. })
  36. // 监听视频播放错误事件,当avPlayer在操作过程中出现错误时调用reset接口触发重置流程
  37. VideoAVPlayerClass.avPlayer.on('error', (err) => {
  38. console.error(`Invoke avPlayer failed, code is ${err.code}, message is ${err.message}`);
  39. // 调用reset重置资源,触发idle状态
  40. VideoAVPlayerClass.avPlayer.reset()
  41. })
  42. // 监听播放状态机AVPlayerState切换的事件
  43. VideoAVPlayerClass.avPlayer.on('stateChange', async (state: media.AVPlayerState, reason: media.StateChangeReason) => {
  44. switch (state) {
  45. // 成功调用reset接口后触发该状态机上报
  46. case 'idle':
  47. console.info('AVPlayer state idle called.');
  48. break
  49. // avplayer 设置播放源后触发该状态上报
  50. case 'initialized':
  51. console.info('AVPlayerstate initialized called.');
  52. // 设置显示画面,当播放的资源为纯音频时无需设置
  53. VideoAVPlayerClass.avPlayer.surfaceId = VideoAVPlayerClass.surfaceId
  54. break
  55. // prepare调用成功后上报该状态机
  56. case 'prepared':
  57. console.info('AVPlayer state prepared called.');
  58. break
  59. // play成功调用后触发该状态机上报
  60. case 'playing':
  61. console.info('AVPlayer state playing called.');
  62. break
  63. // pause成功调用后触发该状态机上报
  64. case 'paused':
  65. console.info('AVPlayer state paused called.');
  66. break
  67. // 播放结束后触发该状态机上报
  68. case 'completed':
  69. console.info('AVPlayer state completed called.');
  70. break
  71. // stop接口成功调用后触发该状态机上报
  72. case 'stopped':
  73. console.info('AVPlayer state stopped called.');
  74. // 调用reset接口初始化avplayer状态
  75. VideoAVPlayerClass.avPlayer.reset()
  76. break
  77. case 'released':
  78. console.info('AVPlayer state released called.');
  79. break;
  80. default:
  81. console.info('AVPlayer state unknown called.');
  82. break;
  83. }
  84. })
  85. }
  86. static async changePlay() {
  87. // 将播放状态置为闲置
  88. await VideoAVPlayerClass.avPlayer.reset()
  89. VideoAVPlayerClass.avPlayer.url = VideoAVPlayerClass.playList[VideoAVPlayerClass.playIndex].url
  90. }
  91. }

获取是否播放状态

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

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


最后

有很多小伙伴不知道学习哪些鸿蒙开发技术?不知道需要重点掌握哪些鸿蒙应用开发知识点?而且学习时频繁踩坑,最终浪费大量时间。所以有一份实用的鸿蒙(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学习资料

总结

总的来说,华为鸿蒙不再兼容安卓,对中年程序员来说是一个挑战,也是一个机会。只有积极应对变化,不断学习和提升自己,他们才能在这个变革的时代中立于不败之地。 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/神奇cpp/article/detail/894804
推荐阅读
相关标签
  

闽ICP备14008679号