鸿蒙 HarmonyOS--视频播放Video

华为官方这边提供了两种视频播放的方式,一种是Video组件,它是已经封装好的视频播放组件,提供了一些比较基础的能力,一些比较复杂的能力建议使用AVPlayer。这篇文章介绍的是Video视频播放。

Video组件支持播放本地视频、沙箱路径视频和网络视频。本地视频放在resource里的rawfile目录下,使用的时候用$rawfile()来引用视频资源,如果是网络视频需要配置网络权限。

默认控制器

Video默认控制器支持视频的开始、暂停、进度调整、全屏显示四项基本功能,但是进度条样式是黑色的,不够美观,也不能通过点击视频区域暂停视频,如果想要更好的体验感,可以自定义控制器。

less 复制代码
@Entry
@Component
struct VideoGuide {
  private controller: VideoController | undefined;
  //视频资源
  @State videoSrc: Resource = $rawfile('waku.mp4')
  //预览图,这里我用的是网络图片
  @State previewUri: string = 'https://i1.hdslb.com/bfs/archive/b31a7e4bd8a1ffb142d0a6ace259a2efe5ac1088.jpg'
  //视频速度
  @State curRate: PlaybackSpeed = PlaybackSpeed.Speed_Forward_1_00_X
  @State showControls: boolean = true

  build() {
    Row() {
      Column() {
        Video({
          src: this.videoSrc,
          previewUri: this.previewUri,
          currentProgressRate: this.curRate,
          controller: this.controller
        })
          .objectFit(ImageFit.Contain)//设置视频适配模式
          .height(400)
          .controls(this.showControls) //是否显示进度控制条
      }
      .width('100%')
    }
    .height('100%')
  }
}

自定义控制器

使用自定义控制器需要先把默认控制器关了,然后用slider组件控制视频的样式和滑动播放效果,还增加了倍速控制。

kotlin 复制代码
@Entry
@Component
struct VideoGuide {
  controller: VideoController = new VideoController()
  //视频资源
  @State videoSrc: Resource = $rawfile('waku.mp4')
  //预览图,这里我用的是网络图片
  @State previewUri: string = 'https://i1.hdslb.com/bfs/archive/b31a7e4bd8a1ffb142d0a6ace259a2efe5ac1088.jpg'
  //视频速度
  @State curRate: PlaybackSpeed = PlaybackSpeed.Speed_Forward_1_00_X
  //当前播放时长
  @State currentTime: number = 0;
  //视频时长
  @State durationTime: number = 0;
  //播放状态
  @State isPlay: boolean = false

  //时间处理函数
  myDate(num: number) {
    let hour = Math.floor(num / 60 / 60)
    let minute = Math.floor(num / 60 % 60)
    let second = Math.floor(num % 60)
    if (num < 3600) {
      return `${minute.toString().padStart(2, '0')} : ${second.toString().padStart(2, '0')}`
    } else {
      return `${hour.toString().padStart(2, '0')} : ${minute.toString().padStart(2, '0')} : ${second.toString()
        .padStart(2, '0')}`
    }
  }

  //进度条
  @Builder
  sliderBar() {
    Row({ space: 8 }) {
      Image(this.isPlay ? $r('app.media.pause') : $r('app.media.start'))
        .width(20)

      Text(this.myDate(this.currentTime))
        .fontSize(12)

      Slider({
        value: this.currentTime,
        min: 0,
        max: this.durationTime,
      })
        .onChange((value) => {
          this.currentTime = value
          this.controller.setCurrentTime(this.currentTime)
        })//设置滑动块的大小
        .blockSize({ width: 10, height: 10 })
        .trackColor(Color.Gray)
        .selectedColor(Color.Pink)
        .layoutWeight(1)
        .height(50)

      Text(this.myDate(this.durationTime))
        .fontSize(12)

      Text('倍速')
        .fontSize(14)//倍数弹窗
        .bindMenu([
          {
            value: 'x0.75',
            action: () => {
              this.curRate = PlaybackSpeed.Speed_Forward_0_75_X
            }
          },
          {
            value: 'x1.00',
            action: () => {
              this.curRate = PlaybackSpeed.Speed_Forward_1_00_X
            }
          },
          {
            value: 'x1.75',
            action: () => {
              this.curRate = PlaybackSpeed.Speed_Forward_1_75_X
            }
          },
          {
            value: 'x2.00',
            action: () => {
              this.curRate = PlaybackSpeed.Speed_Forward_2_00_X
            }
          }
        ])
    }
    .padding(10)
  }

  build() {
    Column() {
      Stack() {
        Video({
          src: this.videoSrc,
          previewUri: this.previewUri,
          currentProgressRate: this.curRate,
          controller: this.controller
        })
          .objectFit(ImageFit.Contain)//设置视频适配模式
          .height(400)
          .controls(false)//不显示默认进度控制条
          .onPrepared((event?: DurationObject) => {
            if (event) {
              this.durationTime = event.duration
            }
          })
          .onUpdate((event?: TimeObject) => {
            if (event) {
              this.currentTime = event.time
            }
          })
        if (!this.isPlay) {
          Image($r('app.media.startVideo'))
            .fillColor(Color.White)
            .opacity(0.8)
            .width(100)
        }
      }

      //滑动控制条
      this.sliderBar()
    }
    .width('100%')
    .height('100%')

    .onClick(() => {
      // 点击视频任意位置实现开始暂停
      if (this.isPlay) {
        this.controller.pause()
      } else {
        this.controller.start()
      }
      this.isPlay = !this.isPlay
    })
  }
}

interface DurationObject {
  duration: number;
}

interface TimeObject {
  time: number;
}
相关推荐
爱桥代码的程序媛1 小时前
鸿蒙OpenHarmony【轻量系统芯片移植案例】标准系统方案之瑞芯微RK3568移植案例
嵌入式硬件·harmonyos·鸿蒙·鸿蒙系统·移植·openharmony·鸿蒙开发
AORO_BEIDOU1 小时前
防爆手机+鸿蒙系统,遨游通讯筑牢工业安全基石
5g·安全·智能手机·信息与通信·harmonyos
小强在此16 小时前
【基于开源鸿蒙(OpenHarmony)的智慧农业综合应用系统】
华为·开源·团队开发·智慧农业·harmonyos·开源鸿蒙
PlumCarefree20 小时前
基于鸿蒙API10的RTSP播放器(四:沉浸式播放窗口)
华为·harmonyos
中关村科金1 天前
中关村科金推出得助音视频鸿蒙SDK,助力金融业务系统鸿蒙化提速
华为·音视频·harmonyos
小强在此1 天前
基于OpenHarmony(开源鸿蒙)的智慧医疗综合应用系统
华为·开源·团队开发·健康医疗·harmonyos·开源鸿蒙
奔跑的露西ly1 天前
【鸿蒙 HarmonyOS NEXT】popup弹窗
华为·harmonyos
OH五星上将2 天前
OpenHarmony(鸿蒙南向开发)——轻量和小型系统三方库移植指南(一)
嵌入式硬件·移动开发·harmonyos·openharmony·鸿蒙开发·鸿蒙移植
codes234577892 天前
鸿蒙开发之ArkTS 界面篇 一
harmonyos·arkts·harmonyos next·deveco-studio·鸿蒙界面·鸿蒙界面入门·鸿蒙 index.ets