2

OpenHarmony视频播放器

 1 year ago
source link: https://www.51cto.com/article/716534.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
e40df4790c089f5a74a570d0a5d07a9975befd.png

​想了解更多关于开源的内容,请访问:​

​51CTO 开源基础软件社区​

​https://ost.51cto.com​

由于视频资源在项目中使用较为频繁,于是有了这个教程,本教程在最后也是实现了一个简单的播放器。

​效果预览​

Video

由于使用本地视频文件会影响App的包大小,所以通常我们的视频文件来源于网络地址,需要在config或者module.json对应的"abilities"中添加网络使用权限ohos.permission.INTERNET。

"abilities":[
  {
    "permissions": ["ohos.permission.INTERNET"],
  }
]

在使用的时候一个VideoController对象可以控制一个或多个video。

//一个VideoController对象可以控制一个或多个video。
controller: VideoController = new VideoController();
declare interface VideoOptions {
  src?: string | Resource;
  currentProgressRate?: number | string | PlaybackSpeed;
  previewUri?: string | PixelMap | Resource;
  controller?: VideoController;
}
#物联网征文#OpenHarmony视频播放器-开源基础软件社区

其中仅src( 视频播放源的路径 )这个参数是必填的。

  • 支持本地视频路径和网络路径。
  • 支持在resources下面的video或rawfile文件夹里放置媒体资源。
  • 支持dataability://的路径前缀,用于访问通过Data Ability提供的视频路径

currentProgressRate:number 视频播放倍速,支持0.75,1.0,1.25,1.75,2.0。

previewUri:string 预览图片的路径,可以作为视频未播放时的封面。

controller:VideoController 控制器。一个VideoController对象可以控制一个或多个video。如果需要通过代码控制视频的播放、暂停等,可以给Video组件设置这个参数,然后通过控制器的如下接口控制视频播放状态:

这儿我需要将PlaybackSpeed和VideoController单独拎出来做一个解释。

PlaybackSpeed类型接口说明

Speed_Forward_0_75_X

0.75倍速播放。

Speed_Forward_1_00_X

1倍速播放。

Speed_Forward_1_25_X

1.25倍速播放。

Speed_Forward_1_75_X

1.75倍速播放。

Speed_Forward_2_00_X

2倍速播放。

declare enum PlaybackSpeed {
  Speed_Forward_0_75_X,
  Speed_Forward_1_00_X,
  Speed_Forward_1_25_X,
  Speed_Forward_1_75_X,
  Speed_Forward_2_00_X,
}

VideoController

一个VideoController对象可以控制一个或多个video。

  • start() : void 开始播放。
  • pause() : void 暂停播放。
  • stop() : void 停止播放。
  • setCurrentTime(value: number, seekMode: SeekMode)指定视频播放的进度位置,并指定跳转模式。value是进度,seekMode是跳转模式
  • requestFullscreen() : boolean() 请求全屏播放,true是横屏,false竖屏。
  • exitFullscreen() : void 退出全屏。

在这儿,我同样需要将setCurrentTime单独拎出。

setCurrentTime8+

setCurrentTime(value: number, seekMode: SeekMode)。

指定视频播放的进度位置,并指定跳转模式。

value

number

视频播放进度位置。

seekMode

SeekMode

跳转模式。

  • SeekMode8+类型接口说明

PreviousKeyframe

跳转到前一个最近的关键帧。

NextKeyframe

跳转到后一个最近的关键帧。

ClosestKeyframe

跳转到最近的关键帧。

Accurate

精准跳转,不论是否为关键帧。

declare enum SeekMode {
  PreviousKeyframe,
  NextKeyframe,
  ClosestKeyframe,
  Accurate,
}

Video属性

muted(是否静音)、autoPlay(自动播放)、controls(控制栏)、objectFit(显示模式)、loop(是否循环播放)。其中,objectFit参数设置值为ImageFit.Cover则铺满整个容器。

详细介绍:

  • muted(boolean) 默认值false 是否静音。
  • autoPlay(boolean) 默认值false 是否自动播放。
  • controls(boolean) 默认值true 控制视频播放的控制栏是否显示。
  • loop(boolean) 是否单个视频循环播放。
  • objectFit(ImageFit) 默认值Cover 设置视频显示模式。ImageFit有如下枚举值可选

ImageFit枚举说明

Cover

保持宽高比进行缩小或者放大,使得图片两边都大于或等于显示边界。

Contain

保持宽高比进行缩小或者放大,使得图片完全显示在显示边界内。

不保持宽高比进行放大缩小,使得图片填充满显示边界。

保持原有尺寸显示。通常配合objectRepeat属性一起使用。

ScaleDown

保持宽高比显示,图片缩小或者保持不变。

onStart() => void 播放时触发该事件。

onPause() => void 暂停时触发该事件。

onFinish() => void 播放结束时触发该事件。

onError() => void 播放失败时触发该事件。

onFullscreenChange(event?: { fullscreen: boolean }) => void) 视频进入和退出全屏时触发该事件。

onPrepared(event?: { duration: number }) => void 视频准备完成时触发该事件,通过duration可以获取视频时长,单位为秒(s)。

onSeeking(event?: { time: number }) => void 操作进度条过程时上报时间信息,单位为s。

onSeeked(event?: { time: number }) => void 操作进度条完成后,上报播放时间信息,单位为s。

onUpdate(event?: { time: number }) => void 播放进度变化时触发该事件,单位为s,更新时间间隔为250ms。

onStart() => void

播放时触发该事件。

onPause() => void

暂停时触发该事件。

onFinish() => void

播放结束时触发该事件。

onError() => void

播放失败时触发该事件。

onPrepared(event?: { duration: number }) => void

视频准备完成时触发该事件,通过duration可以获取视频时长,单位为秒(s)。

onSeeking(event?: { time: number }) => void

操作进度条过程时上报时间信息,单位为s。

onSeeked(event?: { time: number }) => void

操作进度条完成后,上报播放时间信息,单位为s。

onUpdate(event?: { time: number }) => void

播放进度变化时触发该事件,单位为s,更新时间间隔为250ms。

@Entry
@Component
struct Index {
  @State message: string = '视频预览'
  @State previewUris: Resource = $r('app.media.openharmony'); //预览封面
  controller: VideoController = new VideoController();
  @State currentProgressRate: number = 1
  @State muted: boolean = false
  @State autoPlay: boolean = true
  @State controls: boolean = true
  @State startStatus: boolean = true
  @State loop: boolean = true
  aboutToAppear() {
    this.controller.requestFullscreen(true)
    this.controller.start()
  }
  build() {
    Column() {
      Text(this.message)
        .fontSize(50)
        .fontWeight(FontWeight.Bold)
      Video({
        src: $r('app.media.video'),
        previewUri: this.previewUris, // 视频封面
        currentProgressRate: this.currentProgressRate, // 视频播放倍速
        controller: this.controller,
      })
        .muted(this.muted) // 是否静音
        .autoPlay(this.autoPlay) // 是否自动播放
        .controls(this.controls) // 控制视频播放的控制栏是否显示
        .objectFit(ImageFit.Contain) // 视频显示模式
        .loop(this.loop) // 是否单个视频循环播放
        .height("60%")
        .onStart(() => {
          // 播放时触发该事件
          console.info('onStart');
        })
        .onPause(() => {
          // 暂停时触发该事件
          console.info('onPause');
        })
        .onFinish(() => {
          console.info('onFinish');
        })
        .onError(() => {
          // 播放失败时触发该事件
          console.error('onError');
        })
        .onFullscreenChange((e) => {
          console.info('视频进入和退出全屏时触发该事件:' + e.fullscreen)
        })
        .onPrepared((e) => {
          console.info('视频准备完成时触发该事件:' + e.duration)
        })
        .onSeeking((e) => {
          console.info('操作进度条过程时上报时间信息:' + e.time)
        })
        .onSeeked((e) => {
          console.info('操作进度条完成后,上报播放时间信息:' + e.time)
        })
        .onUpdate((e) => {
          console.info('播放进度变化时触发该事件:' + e.time)
        })
      Row({}) {
        Flex({ wrap: FlexWrap.Wrap, justifyContent: FlexAlign.SpaceAround, alignItems: ItemAlign.Center }) {
          Button("播放")
            .onClick(() => {
              this.controller.start()
            }).margin(8)
          Button("暂停")
            .onClick(() => {
              this.controller.pause()
            })
          Button("循环播放")
            .onClick(() => {
              this.loop=!this.loop
            })
          Button("2倍速")
            .onClick(() => {
              this.currentProgressRate=2
            })
          Button("静音")
            .onClick(() => {
              this.muted=!this.muted
            })
          Button("停止")
            .onClick(() => {
              this.controller.stop()
            })
          Button("全屏播放")
            .onClick(() => {
              this.controller.requestFullscreen(true)
            })
          Button("退出全屏")
            .onClick(() => {
              this.controller.exitFullscreen()
            }).margin(8)
          Button("控制栏是否显示")
            .onClick(() => {
              this.controls = !this.controls
            }).margin(8)
          Button("指定视频播放的进度")
            .onClick(() => {
              this.controller.setCurrentTime(9)
            })
        }
      }
    }
    .width('100%').height('100%')
  }
}

​想了解更多关于开源的内容,请访问:​

​51CTO 开源基础软件社区​

​https://ost.51cto.com​​。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK