鸿蒙 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 天前
【天体运行模拟|11】HarmonyOS ArkTS 收藏与笔记实战:同步知识页和个人学习记录
harmonyos·arkts·preferences·多设备适配·arkdata
2501_919749031 天前
华为鸿蒙录音可视化APP—小羊声觉
华为·harmonyos·鸿蒙
大雷神1 天前
HarmonyOS AR Engine深度估计实战——把毫米距离画成实时热力图
华为·ar·harmonyos
GKxx1 天前
在 HarmonyOS 上给 QEMU 搭一个最小 aarch64 Linux guest(内核 + busybox initramfs)
linux·华为·qemu·harmonyos·鸿蒙·鸿蒙pc
贾伟康1 天前
【天体运行模拟|08】HarmonyOS ArkTS 单位换算实战:处理天文尺度、科学计数与精度
harmonyos·arkts·arkui·数值精度·单位换算
lilian2331 天前
HarmonyOS 7 新特性(十三)|3DGS 模型加载、交互与性能回退
3d·交互·harmonyos
2501_919749031 天前
华为鸿蒙免费反诈APP—小羊反诈
华为·harmonyos·鸿蒙
2501_919749031 天前
华为鸿蒙免费视频播放器—小羊免费播放器
华为·harmonyos·鸿蒙
贾伟康1 天前
【天体运行模拟|15】HarmonyOS ArkTS 本地状态持久化实战:让保存、删除和页面返回后的数据即时一致
harmonyos·arkts·数据持久化·状态管理·preferences
贾伟康1 天前
【天体运行模拟|16】HarmonyOS ArkTS 多设备布局实战:适配手机、平板和 PC/2in1 的窗口变化
harmonyos·arkts·arkui·响应式布局·多设备适配