avplayer播放视频demo

1.获取本地和网络视频

2.通过AVPlayer进行播放视频

3.通过手势调试屏幕亮度和视频播放音量

HarmonyOS
2024-05-28 20:14:34
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
juliedan

使用的核心API

XComponent

avplayer播放器

PanGesture手势

核心代码解释

视频播放主要包括视频的暂停、播放、切换、倍速播放、拖动进度条设置当前进度、显示当前播放时间、音量调节等功能,本章节主要针对播放管理类(下面简称:AVPlayer)进行讲解,具体细节请参考gitee源码,效果如图所示:

播放的全流程包含:创建AVPlayer,设置播放资源,设置播放参数(音量/倍速),播放控制(播放/暂停/上一个视频/下一个视频),重置,销毁资源。状态机变化如图所示:

视频播放之前需要初始化XComponent组件用于展示视频画面。XComponent组件初始化成功之后在onLoad()中获取surfaceID用于与AVPlayer实例关联。

使用AVPlayer前需要通过createAVPlayer()构建一个实例对象,并为AVPlayer实例绑定状态机,状态机具体请参考AVPlayerState。

AVPlayer实例需设置播放路径和XComponent中获取的surfaceID,设置播放路径之后AVPlayer状态机变为initialized状态,在此状态下调用prepare(),进入prepared状态。

在prepared状态下可获取当前播放路径对应视频的总时长,并执行play()进行视频播放。

视频播放后,变为playing状态,可通过“播放/暂停”按钮切换播放状态,当视频暂停时状态机变为paused状态。

可拖动进度条设置视频播放位置,也可滑动音量调节区域设置视频播放音量、设置播放速度。

视频播放完成之后,进入completed状态,需调用reset()对视频进行重置,此时变为idle转态,在idle状态下设置下一个视频的播放地址,又会进入initialized状态。

/** 
 * Creates a videoPlayer object. 
 * 创建一个 videoPlayer 对象。 
 */ 
async createAVPlayer() { 
  //异步方式创建音视频播放实例,通过注册回调函数获取返回值avPlayer 
  let avPlayer: media.AVPlayer = await media.createAVPlayer(); 
  this.avPlayer = avPlayer; 
  //为AVPlayer实例绑定状态机 
  this.bindState(); 
} 
 
/** 
 * AVPlayer binding event. 
 */ 
async bindState() { 
  if (this.avPlayer === null) { 
    return; 
  } 
  this.avPlayer.on(Events.STATE_CHANGE, async (state: media.AVPlayerState) => { 
    let avplayerStatus: string = state; 
    if (this.avPlayer === null) { 
      return; 
    } 
    //当前视频的播放状态avplayerStatus 是 prepared/playing/paused/completed/initialized/idle 
    switch (avplayerStatus) { 
      case AvplayerStatus.IDLE: 
        //重置进度条 
        this.resetProgress(); 
        //媒体URL,只允许在idle状态下设置,静态属性 
        if (this.iUrl) { 
          this.avPlayer.url = this.iUrl; 
        } else { 
          //媒体文件描述,只允许在idle状态下设置,静态属性 
          this.avPlayer.fdSrc = this.url; 
        } 
        break; 
      case AvplayerStatus.INITIALIZED: 
        // surfaceId视频窗口ID,默认无窗口,只允许在initialized状态下设置,静态属性。 
        // 使用场景:视频播放的窗口渲染,纯音频播放不用设置。 
        this.avPlayer.surfaceId = this.surfaceId; 
        this.avPlayer.prepare(); 
        break; 
      case AvplayerStatus.PREPARED: 
        //视频拉伸至与窗口等大 
        this.avPlayer.videoScaleType = 0; 
        //根据视频大小设置播放页面大小 
        this.setVideoSize(); 
        this.avPlayer.play(); 
        //获取视频时长 
        this.duration = this.avPlayer.duration; 
        break; 
      case AvplayerStatus.PLAYING: 
        this.avPlayer.setVolume(this.playerThis.volume); 
        //设置亮度 
        this.setBright(); 
        //设置播放状态,来判断是否屏幕常亮 
        this.status = CommonConstants.STATUS_START; 
        //根据播放状态设置屏幕是否常亮 
        this.watchStatus(); 
        break; 
      case AvplayerStatus.PAUSED: 
        this.status = CommonConstants.STATUS_PAUSE; 
        this.watchStatus(); 
        break; 
      case AvplayerStatus.COMPLETED: 
        this.titleThis.playSpeed = 1; 
        //播放完后视频时长归0 
        this.duration = PlayConstants.PLAYER_DURATION; 
        //loop视频循环播放属性,设置为'true'表示循环播放 
        if (!this.loop) { 
          //连续播放时获取下一个视频 
          let curIndex = this.index + PlayConstants.PLAYER_NEXT; 
          //获取视频集合列表 
          let globalVideoList = GlobalContext.getContext().getObject('globalVideoList') as VideoBean[]; 
          this.index = (curIndex === globalVideoList.length) ? 
          PlayConstants.PLAYER_FIRST : curIndex; 
          if (this.iUrl) { 
            this.iUrl = globalVideoList[this.index].iSrc; 
          } else { 
            this.url = globalVideoList[this.index].src; 
          } 
        } 
        //异步方式重置音视频录制。通过Promise获取返回值。 
        this.avPlayer.reset(); 
        break; 
      case AvplayerStatus.RELEASED: 
        //录制资源释放。此时不能再进行任何操作。在任何其他状态下,均可以通过调用release()方法进入released状态 
        this.avPlayer.release(); 
        this.status = CommonConstants.STATUS_STOP; 
        this.watchStatus(); 
        Logger.info('[PlayVideoModel] state released called') 
        break; 
      default: 
        Logger.info('[PlayVideoModel] unKnown state: ' + state); 
        break; 
    } 
  }); 
  //监听资源播放当前时间,单位为毫秒(ms),用于刷新进度条当前位置,默认间隔1s时间上报,因用户操作(seek)产生的时间变化会立刻上报。 
  this.avPlayer.on(Events.TIME_UPDATE, (time: number) => { 
    //刷新进度条 
    this.initProgress(time); 
  }); 
  this.avPlayer.on(Events.ERROR, () => { 
    this.playError(); 
  }) 
}

手势控制

播放页面通过绑定平移手势(PanGesture),上下滑动调节屏幕亮度,左右滑动调节视频音量

Column() { 
  PlayTitle({ playVideoModel: this.playVideoModel }) 
    .width(CommonConstants.FULL_PERCENT) 
    .height(PlayConstants.HEIGHT) 
  Column() 
    .width(CommonConstants.FULL_PERCENT) 
    .height(PlayConstants.COLUMN_HEIGHT_ONE) 
    .gesture( 
      PanGesture(this.panOptionBright) 
        //手势上下滑动亮度改变 
        .onActionStart((event?: GestureEvent) => { 
          this.playVideoModel.onBrightActionStart(event); 
        }) 
        .onActionUpdate((event?: GestureEvent) => { 
          this.playVideoModel.onBrightActionUpdate(event); 
        }) 
        .onActionEnd(() => { 
          this.playVideoModel.onActionEnd(); 
        }) 
    ) 
  Column() { 
  } 
  .width(CommonConstants.FULL_PERCENT) 
  .height(PlayConstants.PLAY_PLAYER_HEIGHT) 
 
  Column() 
    //手势左右滑动音量改变 
    .width(CommonConstants.FULL_PERCENT) 
    .height(PlayConstants.COLUMN_HEIGHT_TWO) 
    .gesture( 
      PanGesture(this.panOptionVolume) 
        .onActionStart((event?: GestureEvent) => { 
          this.playVideoModel.onVolumeActionStart(event); 
        }) 
        .onActionUpdate((event?: GestureEvent) => { 
          this.playVideoModel.onVolumeActionUpdate(event); 
        }) 
        .onActionEnd(() => { 
          this.playVideoModel.onActionEnd(); 
        }) 
    ) 
  PlayControl({ playVideoModel: this.playVideoModel }) 
    .width(CommonConstants.FULL_PERCENT) 
    .height(PlayConstants.HEIGHT) 
  PlayProgress({ playVideoModel: this.playVideoModel }) 
    .width(CommonConstants.FULL_PERCENT) 
    .height(PlayConstants.PLAY_PROGRESS_HEIGHT) 
} 
.height(CommonConstants.FULL_PERCENT) 
.width(CommonConstants.FULL_PERCENT) 
.zIndex(1)

框架

│──entry/src/main/ets // 代码区

│ ├──common

│ │ ├──bean

│ │ │ └──VideoBean.ets // 视频bean对象

│ │ ├──constants

│ │ │ ├──CommonConstants.ets // 公共常量类

│ │ │ ├──HomeConstants.ets // 首页常量类

│ │ │ └──PlayConstants.ets // 视频播放页面常量类

│ │ └──util

│ │ ├──DateFormatUtil.ets // 日期工具类

│ │ ├──Logger.ets // 日志工具类

│ │ └──ScreenUtil.ets // 屏幕工具类

│ ├──controller

│ │ └──VideoController // 视频控制类

│ ├──entryability

│ │ └──EntryAbility.ts // 程序入口类

│ ├──pages

│ │ ├──HomePage.ets // 首页页面

│ │ └──PlayPage.ets // 视频播放页面

│ ├──view

│ │ ├──HomeTabContent.ets // 首页Tab页面

│ │ ├──HomeTabContentButton.ets // 首页按钮子组件

│ │ ├──HomeTabContentDialog.ets // 添加网络视频弹框子组件

│ │ ├──HomeTabContentList.ets // 视频列表子组件

│ │ ├──HomeTabContentListItem.ets // 视频对象子组件

│ │ ├──PlayControl.ets // 播放控制子组件

│ │ ├──PlayPlayer.ets // 视频播放子组件

│ │ ├──PlayProgress.ets // 播放进度子组件

│ │ ├──PlayTitle.ets // 播放标题子组件

│ │ └──PlayTitleDialog.ets // 播放速度设置子组件

│ └──viewmodel

适配的版本信息

DevEco Studio Version: 4.1.1.400

SDK:HarmoneyOS 4.0.0.43

分享
微博
QQ
微信
回复
2024-05-29 21:13:14
相关问题
AVPlayer实现视频播放
300浏览 • 1回复 待解决
使用AVPlayer实现视频播放
354浏览 • 1回复 待解决
AVplayer开发音频播放功能
498浏览 • 1回复 待解决
AVPlayer实现音频播放(c++侧)
447浏览 • 1回复 待解决
创建多个视频组件无法播放
938浏览 • 1回复 待解决
求鸿蒙视频编码解码的具体demo
5533浏览 • 1回复 待解决
如何实现RTSP视频播放
271浏览 • 1回复 待解决
视频播放黑屏,下面是代码
8242浏览 • 1回复 待解决
鸿蒙开发如何播放本地视频
8063浏览 • 1回复 待解决
怎么基于Java实现视频播放
1625浏览 • 1回复 待解决
播放器】硬解码支持的Demo
679浏览 • 1回复 待解决
鸿蒙卡片服务可以播放视频吗。
4075浏览 • 1回复 待解决
Java Player视频播放不了的问题
7410浏览 • 2回复 待解决
视频播放实例最多创建多少个
889浏览 • 1回复 待解决
TV 中如何用Java播放本地视频
8137浏览 • 2回复 待解决
video player播放在线视频失败
8346浏览 • 1回复 待解决