鸿蒙 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;
}
相关推荐
yg_小小程序员2 小时前
鸿蒙开发(16)使用DevEco Studio上的Git工具进行多远程仓管理
git·华为·harmonyos
JasonYin~2 小时前
HarmonyOS NEXT 实战之元服务:静态案例效果---每日玩机技巧
harmonyos
轻口味2 小时前
【每日学点鸿蒙知识】多线程限制、axios组件下载进度问题、lpx问题、Web组件全局代理、ArrayList问题
华为·harmonyos
yuanlaile2 小时前
纯Dart Flutter库适配HarmonyOS
flutter·华为·harmonyos·flutter开发鸿蒙·harmonyos教程
yuanlaile2 小时前
Flutter开发HarmonyOS 鸿蒙App的好处、能力以及把Flutter项目打包成鸿蒙应用
flutter·华为·harmonyos·flutter开发鸿蒙
JasonYin~2 小时前
HarmonyOS NEXT 实战之元服务:静态案例效果---手机查看电量
android·华为·harmonyos
李游Leo3 小时前
探索HarmonyOS Next API 13 :Camera API 照相机功能实战
harmonyos
编程百晓君11 小时前
一文彻底拿捏DevEco Studio的使用小技巧
华为·harmonyos
轻口味12 小时前
【每日学点鸿蒙知识】私仓搭建、resources创建文件夹、hvigor如何动态设置版本、SM3摘要算法、SP存储报错等
华为·json·harmonyos
JasonYin~13 小时前
HarmonyOS NEXT 实战之元服务:静态案例效果---查看国际航班服务
华为·harmonyos