3.4 Video组件 原创 精华

不做加班狗
发布于 2022-6-7 16:23
浏览
1收藏

本节演示视频播放组件Video的基本使用方法。

3.4.1 权限配置

由于使用本地视频文件会影响App的包大小,所以通常我们的视频文件来源于网络地址,需要在config.json中做如下权限配置:

        "configChanges": ["orientation"]
...此处配置省略...
    "reqPermissions": [
      {
        "name": "ohos.permission.INTERNET"
      },
      {
        "name": "ohos.permission.MODIFY_AUDIO_SETTINGS"
      },
      {
        "name": "ohos.permission.READ_MEDIA"
      }
    ]

如下图所示:

3.4 Video组件-鸿蒙开发者社区

3.4.2 接口

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

其中仅src( 视频播放源的路径 )这个参数是必填的。另外三个可选参数说明如下:

currentProgressRate:number 视频播放倍速。

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

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

1>.start() : void 开始播放。

2>.pause() : void 暂停播放。

3>.stop() : void 停止播放。

4>.setCurrentTime(value: number)() 指定视频播放的进度位置。

5>.requestFullscreen() : boolean() 请求全屏播放,true是横屏,false竖屏。

6>.exitFullscreen() : void 退出全屏。

3.4.3 属性

可将如下视频属性的值通过@State声明为变量,可通过按钮随时切换状态。

.muted(boolean) 默认值false 是否静音。

.autoPlay(boolean) 默认值false 是否自动播放。

.controls(boolean) 默认值true 控制视频播放的控制栏是否显示。

.loop(boolean) 是否单个视频循环播放。

.objectFit(ImageFit) 默认值Cover 设置视频显示模式。ImageFit有如下枚举值可选(和Image组件相同):

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

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

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

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

5>.ImageFit.ScaleDown 保持宽高比显示,图片缩小或者保持不变。

3.4.4 事件

通过上面接口中的VideoController对象的相关接口,或更改了上述属性时,可以触发如下事件。在响应的代码块中可以添加我们需要的业务逻辑。

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。

3.4.5 示例代码

本节的示例代码仅用于帮助大家了解目前Video组件提供的接口、属性和事件的用法。本案例的效果比较原始、粗糙,不建议直接用于App开发。后续HUI组件库会推出基于Video组件封装的自定义组件,更美观、易于调用。

新建一个VideoSample.ets页面,代码如下:

import {H8} from './index'

/**
 * 3.4 Video组件
 *
 * 视频播放组件。
 *
 * 权限列表:
 *  ohos.permission.INTERNET(如果使用云端路径)
 *  ohos.permission.MODIFY_AUDIO_SETTINGS
 *  ohos.permission.READ_MEDIA
 *  说明:需要在config.json配置:"configChanges": ["orientation"]
 *
 * 接口:
 *  Video(value: {src: string, currentProgressRate?: number, previewUri?: string, controller?: VideoController})
 *    src:string 视频播放源的路径。
 *    currentProgressRate:number 视频播放倍速。
 *    previewUri:string 预览图片的路径。
 *    controller:VideoController 控制器。
 *      说明:一个VideoController对象可以控制一个或多个video。
 *      start() : void 开始播放。
 *      pause() : void 暂停播放。
 *      stop() : void 停止播放。
 *      setCurrentTime(value: number)() 指定视频播放的进度位置。
 *      requestFullscreen() : boolean() 请求全屏播放,true是横屏,false竖屏。
 *      exitFullscreen() : void 退出全屏。
 *
 * 属性:
 *  muted:boolean 默认值false 是否静音。
 *  autoPlay:boolean 默认值false 是否自动播放。
 *  controls:boolean 默认值true 控制视频播放的控制栏是否显示。
 *  objectFit:ImageFit 默认值Cover 设置视频显示模式。
 *    ImageFit.Cover 保持宽高比进行缩小或者放大,使得图片两边都大于或等于显示边界。
 *    ImageFit.Contain 保持宽高比进行缩小或者放大,使得图片完全显示在显示边界内。
 *    ImageFit.Fill 不保持宽高比进行放大缩小,使得图片填充满显示边界。
 *    ImageFit.None 保持原有尺寸显示。通常配合objectRepeat属性一起使用。
 *    ImageFit.ScaleDown 保持宽高比显示,图片缩小或者保持不变。
 *  loop:boolean 是否单个视频循环播放。
 *
 * 事件:
 *  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。
 */
@Entry
@Component
struct VideoSample {
  @State currentProgressRate: number = 1
  @State muted: boolean = false
  @State autoPlay: boolean = false
  @State controls: boolean = true
  @State startStatus: boolean = true
  myVideoController: VideoController = new VideoController()
  build() {
    Column({space:8}) {
      // 返回首页
      Row({space:8}){
        Image($r("app.media.ic_back")).width(24).height(24)

        Navigator({ target: 'pages/index', type: NavigationType.Back }) {
          H8({text:'返回'})
        }
      }

      Video({
        src: 'https://ss0.bdstatic.com/-0U0bnSm1A5BphGlnYG/cae-legoup-video-target/93be3d88-9fc2-4fbd-bd14-833bca731ca7.mp4',  // 视频播放源的路径
        previewUri: '/common/images/lake.jpg',  // 视频封面
        currentProgressRate: this.currentProgressRate,  // 视频播放倍速
        controller: this.myVideoController  // 控制器
      })
        .muted(this.muted)  // 是否静音
        .autoPlay(this.autoPlay)  // 是否自动播放
        .controls(this.controls)  // 控制视频播放的控制栏是否显示
        .objectFit(ImageFit.Contain)  // 视频显示模式
        .loop(true)  // 是否单个视频循环播放
        .width('100%')
        .aspectRatio(1.33)
        .onStart(() => {
          // 播放时触发该事件
        })
        .onPause(() => {
          // 暂停时触发该事件
        })
        .onFinish(() => {
          // 播放结束时触发该事件
        })
        .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.Start }) {
          Button("播放")
            .onClick(() => {
              this.myVideoController.start()
            })
          Button("暂停")
            .onClick(() => {
              this.myVideoController.pause()
            })
          Button("停止")
            .onClick(() => {
              this.myVideoController.stop()
            })
            .margin({bottom:10})
          Button("全屏播放")
            .onClick(() => {
              this.myVideoController.requestFullscreen(true)
            })
          Button("退出全屏")
            .onClick(() => {
              this.myVideoController.exitFullscreen()
            })
            .margin({bottom:10})
          Button("控制栏是否显示")
            .onClick(() => {
              this.controls = !this.controls
            })
            .margin({bottom:10})
          Button("指定视频播放的进度位置")
            .onClick(() => {
              this.myVideoController.setCurrentTime(9)
            })
        }.padding(15)
      }
    }
    .width('100%')
    .height('100%')
    .padding({top: $r("app.float.spaceTop"), bottom:$r("app.float.spaceBottom"), left:$r("app.float.spaceLeft"), right: $r("app.float.spaceRight")})
    .backgroundColor($r("app.color.appBg"))
    .alignItems(HorizontalAlign.Start)
  }
}

本地预览器无法观看效果,可以到远程模拟器体验,效果如下:

3.4 Video组件-鸿蒙开发者社区

3.4 Video组件-鸿蒙开发者社区

3.4 Video组件-鸿蒙开发者社区

【本节源码:https://gitee.com/cloudev/harmonyos3/tree/master/3.0/BaseComponent

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
3
收藏 1
回复
举报
1条回复
按时间正序
/
按时间倒序
红叶亦知秋
红叶亦知秋

感谢老师详细的示例

回复
2022-6-8 10:40:14
回复
    相关推荐