鸿蒙 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;
}
相关推荐
摘星编程4 分钟前
React Native鸿蒙版:forwardRef组件引用转发
react native·react.js·harmonyos
俺不理解8 分钟前
鸿蒙 Stage Arkts HSP+HAR 的集成
华为·harmonyos·模块化·har·hsp
小雨青年9 分钟前
鸿蒙 HarmonyOS 6 | AI Kit 集成 CANN Kit 异构计算服务
人工智能·华为·harmonyos
前端不太难32 分钟前
HarmonyOS 游戏卡顿,问题不在渲染
华为·状态模式·harmonyos
讯方洋哥34 分钟前
HarmonyOS App开发——一多图片浏览器应用App开发
华为·harmonyos
Miguo94well9 小时前
Flutter框架跨平台鸿蒙开发——海龟汤APP的开发流程
flutter·华为·harmonyos·鸿蒙
讯方洋哥10 小时前
HarmonyOS App开发——购物商城应用App开发
harmonyos
无穷小亮10 小时前
Flutter框架跨平台鸿蒙开发——Excel函数教程APP的开发流程
flutter·华为·excel·harmonyos·鸿蒙
无穷小亮10 小时前
Flutter框架跨平台鸿蒙开发——打字练习APP开发流程
flutter·华为·harmonyos·鸿蒙
九 龙11 小时前
Flutter框架跨平台鸿蒙开发——水电缴费提醒APP的开发流程
flutter·华为·harmonyos·鸿蒙