鸿蒙系列--组件介绍之Video

发布时间:2024年01月08日

接口

Video(value: {src?: string | Resource, currentProgressRate?: number | string |PlaybackSpeed, previewUri?: string |PixelMap | Resource, controller?: VideoController})

参数:

  • src:视频播放源的路径。支持本地路径和网络路径
  • currentProgressRate:视频播放倍速,其参数类型为number,取值支持0.75,1.0,1.25,1.75,2.0,默认值为1.0倍速
  • previewUri:视频未播放时的预览图片路径
  • controller:视频控制器

属性:

  • muted:是否静音,默认值:false
  • autoPlay:是否自动播放,默认值:false
  • controls:控制视频播放的控制栏是否显示,默认值:true
  • objectFit:设置视频显示模式,默认值:Cover
    • Contain
    • Cover
    • Auto
    • Fill
    • ScaleDown
    • None?
  • loop:是否单个视频循环播放,默认值:false

事件:

  • onStart(event:() => void):播放时触发
  • onPause(event:() => void):暂停时触发
  • onFinish(event:() => void):播放结束时触发
  • onError(event:() => void):播放失败时触发
  • onPrepared(callback:(event?: { duration: number }) => void):视频准备完成时触发,通过duration可以获取视频时长,单位为s
  • onSeeking(callback:(event?: { time: number }) => void):操作进度条过程时上报时间信息,单位为s
  • onSeeked(callback:(event?: { time: number }) => void):操作进度条完成后,上报播放时间信息,单位为s
  • onUpdate(callback:(event?: { time: number }) => void):播放进度变化时触发该事件,单位为s,更新时间间隔为250ms
  • onFullscreenChange(callback:(event?: { fullscreen: boolean }) => void):在全屏播放与非全屏播放状态之间切换时触发该事件

视频支持格式:

  • mp4、mkv、webm、TS

使用案例:

  1. Video最原始样式,调用VideoPlayer组件,传入一个source,这样就能让一个视频播放起来了
  2. 为了使页面美观,同时能让用户预览内容,可以增加一个previewUris,给视频增加一个未播放时的预览图,也可以使用网络和本地地址
  3. 在播放过程中发现视频被拉伸,显示不全,可以通过设置?.objectFit(ImageFit.Contain) 使视频保持宽高比例进行缩放,从而保证视频原有的显示效果
@Component
export struct VideoPlayer {
  private source: string | Resource;
  private previewUris: Resource = $r('app.media.preview');

  build() {
    Column() {
      Video({
        src: this.source,
        previewUri: this.previewUris
      })
        .width('100%')
        .height('100%')
        .objectFit(ImageFit.Contain)
    }
  }
}

注意:

  • 使用网络播放路径时,需要注意的是需要在module.json5文件中申请网络权限

  • 本地视频地址可以使用媒体库管理模块medialibrary来查询公共媒体库中的视频文件

自定义视频播放控制器:

  1. 当Video组件的原生控制器的样式和功能不能满足业务需求时,此时需要隐藏原生控制器? ? ? ? ?.controls(false)
  2. 自定义控制器包括的功能:控制视频播放、暂停、显示视频总时长、播放起始时间以及控制和显示播放速度
  3. 增加一个参数 VideoController对象controller,用于控制视频的播放、暂停等功能
  4. 自定义一个视频播放器的控制栏VideoSlider组件,并将controller传递进去
  5. 在ViewSlider组件中来控制视频的播放和进度显示

VideoPlayer

import { Event } from '@ohos.worker';
import Prompt from '@system.prompt';
import { ALL_PERCENT, COMMON_NUM_DOUBLE, COMMON_NUM_MINUTE, SPLIT, STRING_PERCENT, ZERO_STR } from './Constants';
import { changeSliderTime } from './VideoControll';
import { VideoSlide } from './VideoSlide';

@Component
export struct VideoPlayer {
  private source: string | Resource;
  private previewUris: Resource = $r('app.media.preview');
  private controller: VideoController
  isPlay: boolean = false
  @Provide durationTime: number = 0
  @Provide durationStringTime: string = '00:00'
  @Provide currentTime: number = 0
  @Provide currentStringTime: string = '00:00'

  build() {
    Column() {
      Video({
        src: this.source,
        previewUri: this.previewUris,
        controller: this.controller
      })
        .width(ALL_PERCENT)
        .height(STRING_PERCENT.NINETY_PERCENT)
        .objectFit(ImageFit.Contain)
        .controls(false)
        .onPrepared((event) => {
          this.prepared.call(this, event?.duration)
        })
        .onUpdate((event) => {
          if (event) {
            this.currentTime = event.time
            this.currentStringTime = changeSliderTime(this.currentTime)
          }
        })
        .onFinish(() => {
          //视频播放完成回调
          this.finish.call(this)
        })
        .onError(() => {
          //视频播放出错回调
          Prompt.showToast({ duration: 5000, message: '错误提示' })
        })
      //自定义视频播放控制器组件
      VideoSlide({ controller: this.controller })
    }
  }

  prepared(duration: number) {
    this.durationTime = duration;
    let second: number = duration % COMMON_NUM_MINUTE;
    let min: number = Number.parseInt((duration / COMMON_NUM_MINUTE).toString());
    let head = min < COMMON_NUM_DOUBLE ? `${ZERO_STR}${min}` : min;
    let end = second < COMMON_NUM_DOUBLE ? `${ZERO_STR}${second}` : second;
    this.durationStringTime = `${head}${SPLIT}${end}`;
  }

  finish() {
    this.isPlay = false
  }
}

ViewSlider

import { ALL_PERCENT } from './Constants'
@Component
export struct VideoSlide {
  private controller: VideoController
  private isPlay: boolean = false
  @Consume durationTime: number
  @Consume durationStringTime: string
  @Consume currentTime: number
  @Consume currentStringTime: string

  build() {
    Row({ space: 12 }) {
      //视频播放/暂停控制
      Image(this.isPlay
        ? $r('app.media.ic_pause')
        : $r('app.media.ic_play'))
        .onClick(() => {
          this.iconOnclick()
        })
        .width(50)
        .height(50)

      //显示当前播放时间
      Text(this.currentStringTime)
        .fontColor(Color.White)

      //控制和播放进度
      Slider({ value: this.currentTime, min: 0, max: this.durationTime, step: 1 })
        .width(180)
        .onChange((value: number, mode: SliderChangeMode) => {
          this.slideOnChange.call(this, value, mode)
        })

      //显示视频时长
      Text(this.durationStringTime)
        .fontColor(Color.White)
    }.backgroundColor(Color.Green)
    .width(ALL_PERCENT)
  }

  iconOnclick() {
    if (this.isPlay) {
      this.controller.pause()
      this.isPlay = false
    } else {
      this.controller.start()
      this.isPlay = true
    }
  }

  slideOnChange(value: number, mode: SliderChangeMode) {
    this.currentTime = parseInt(value.toString())
    this.controller.setCurrentTime(this.currentTime, SeekMode.Accurate)
  }
}

文章来源:https://blog.csdn.net/weixin_42277946/article/details/135407595
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。