鸿蒙实现视频播放功能

1、鸿蒙视频功能介绍

鸿蒙提供了两种方式实现视频播放功能:

  • 使用video组件实现视频播放
  • 使用AVPlayer组件实现视频播放

2、AVPlayer组件实现视频播放

2.1、播放功能的逻辑处理

import media from '@ohos.multimedia.media'
 
export class VideoAVPlayerClass {
   
   
  // 创建的播放器应该存在我们的工具类上,这样才能被导出使用
  static player: media.AVPlayer | null = null
 
  // 当前播放器播放视频的总时长
  static duration: number = 0
 
  // 当前播放器播放的时长
  static time: number = 0
 
  // 当前播放器是否播放
  static isPlay: boolean = false
 
    // 当前播放器的播放列表
  static playList: videoItemType[] = []
  
  // 当前播放的视频索引
  static playIndex: number = 0
 
  // surfaceID用于播放画面显示,具体的值需要通过XComponent接口获取
  static surfaceId: string = ''
 
  // 播放器上记录上下文
  static context: Context|null = null
  
  
  // 创建播放器的方法
  static async init(initParams: InitParams) {
   
   
 
    // 存储属性SurfaceID,用于设置播放窗口,显示画面
    VideoAVPlayerClass.surfaceId = initParams.surfaceId
 
    // 将上下文 context 存储到播放器类上
    VideoAVPlayerClass.context = initParams.context
 
    // 创建播放器实例
    VideoAVPlayerClass.player = await media.createAVPlayer()
 
    // ----------------------- 事件监听 --------------------------------------------------------------
 
    // 用于进度条,监听进度条长度,刷新资源时长
    VideoAVPlayerClass.avPlayer.on('durationUpdate', (duration: number) => {
   
   
        console.info('AVPlayer state durationUpdate called. current time: ', duration);
        // 获取视频总时长
        VideoAVPlayerClass.duration = duration
    })
 
    // 用于进度条,监听进度条当前位置,刷新当前时间
    VideoAVPlayerClass.avPlayer.on('timeUpdate', (time) =>{
   
   
      console.info('AVPlayer state timeUpdate called. current time: ', time);
      // 获取当前播放时长
      VideoAVPlayerClass.time = time
 
      // 更新信息到页面
      VideoAVPlayerClass.updateState()
    })
 
    // 监听seek生效的事件
    VideoAVPlayerClass.avPlayer.on('seekDone', (seekDoneTime: number) => {
   
   
      console.info(`AVPlayer seek succeeded, seek time is ${
     
     seekDoneTime}`);
      VideoAVPlayerClass.avPlayer.play()
      VideoAVPlayerClass.isPlay = true
    })
 
    // 监听视频播放错误事件,当avPlayer在操作过程中出现错误时调用reset接口触发重置流程
    VideoAVPlayerClass.avPlayer.on('error', (err) => {
   
   
      console.error(`Invoke avPlayer failed, code is ${
     
     err.code}, message is ${
     
     err.message}`);
      // 调用reset重置资源,触发idle状态
      VideoAVPlayerClass.avPlayer.reset()
    })
 
    // 监听播放状态机AVPlayerState切换的事件
    VideoAVPlayerClass.avPlayer.on('stateChange', async (state: media.AVPlayerState, reason: media.StateChangeReason) => {
   
   
      switch (state) {
   
   
      // 成功调用reset接口后触发该状态机上报
        case 'idle':
          console.info('AVPlayer state idle called.');
          break
 
       // avplayer 设置播放源后触发该状态上报
        case 'initialized':
          console.info('AVPlayerstate initialized called.');
          // 设置显示画面,当播放的资源为纯音频时无需设置
          VideoAVPlayerClass.avPlayer.surfaceId = VideoAVPlayerClass.surfaceId
          break
 
      // prepare调用成功后上报该状态机
        case 'prepared':
          console.info('AVPlayer state prepared called.');
          break
 
      // play成功调用后触发该状态机上报
        case 'playing':
          console.info('AVPlayer state playing called.');
          break
 
      // pause成功调用后触发该状态机上报
        case 'paused':
          console.info('AVPlayer state paused called.');
          break
 
      // 播放结束后触发该状态机上报
        case 'completed':
          console.info('AVPlayer state completed called.');
 
          // 当前视频播放完成,自动播放下一个视频哦
          if (VideoAVPlayerClass.autoPlayList && VideoAVPlayerClass.playIndex < VideoAVPlayerClass.playList.length) {
   
   
            VideoAVPlayerClass.playIndex++
            VideoAVPlayerClass.playIndex = (VideoAVPlayerClass.playIndex + VideoAVPlayerClass.playList.length) % VideoAVPlayerClass.playList.length
            VideoAVPlayerClass.singlePlay(VideoAVPlayerClass.playList[VideoAVPlayerClass.playIndex])
            VideoAVPlayerClass.isPlay = true
          } else {
   
   
            VideoAVPlayerClass.isPlay = false
            // 停止播放
            VideoAVPlayerClass.avPlayer.stop()
          }
          
          break
 
      // stop接口成功调用后触发该状态机上报
        case 'stopped':
          console.info('AVPlayer state stopped called.');
        // 调用reset接口初始化avplayer状态
          VideoAVPlayerClass.avPlayer.reset()
          break
 
        case 'released':
          console.info('AVPlayer state released called.');
          break;
 
        default:
          console.info('AVPlayer state unknown called.');
          break;
      }
    })
  }
 
  // 视频播放
  static async play() {
   
   
    VideoAVPlayerClass.avPlayer.play()
    VideoAVPlayerClass.isPlay = true
    VideoAVPlayerClass.updateState()
  }
 
  // 视频暂停
  static pause() {
   
   
    VideoAVPlayerClass.avPlayer.pause()
    VideoAVPlayerClass.isPlay = false
    VideoAVPlayerClass.updateState()
  }
 
  // 切换视频
  static singlePlay(video?: videoItemType) {
   
   
 
    if (video) {
   
   
      let index = VideoAVPlayerClass.playList.findIndex((item: videoItemType) => item.id === video.id)
 
      if (index > -1) {
   
   
        // 当前要播放的视频在播放列表里
        VideoAVPlayerClass.playIndex = index
      } else {
   
   
        // 当前要播放的视频不在播放列表里
        VideoAVPlayerClass.playList.push(video)
        VideoAVPlayerClass.playIndex = VideoAVPlayerClass.playList.length - 1
      }
    }
 
    VideoAVPlayerClass.changePlay()
 
  }
 
  static async changePlay() {
   
   
    // 将播放状态置为闲置
    await VideoAVPlayerClass.avPlayer.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bst@微胖子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值