基于ArkTS语言的OpenHarmony APP应用开发:多媒体管理2

描述

1、程序介绍

本示例展示了视频组件的基本功能,以及如何控制播放状态的相关能力。包括视频组件化,全屏化,窗口化,上下轮播视频等。

本实例使用Video组件,具体如下:

进入首页点击播放按键。

点击视频播放按钮,视频开始播放。再次点击视频进入视频全屏页。

首页下滑500vp后,视频小窗口化。

4.点击直播按钮进入直播页,上下滑动视频。

本案例已在OpenHarmony凌蒙派-RK3568开发板验证通过

API版本:9

2、知识准备

2.1、Video

用于播放视频文件并控制其播放状态的组件。

使用网络视频时,需要申请权限ohos.permission.INTERNET。

详细请参考:官方文档

2.1.1、接口

  •  

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

 

参数定义如下所示:

参数名参数类型必填参数描述
srcstring | Resource视频播放源的路径,支持本地视频路径和网络路径。支持在resources下面的video或rawfile文件夹里放置媒体资源。视频支持的格式是:mp4、mkv、webm、ts。
currentProgressRatenumber | string | PlaybackSpeed视频播放倍速。number取值仅支持:0.75,1.0,1.25,1.75,2.0
previewUristring | PixelMap | Resource视频未播放时的预览图片路径
controllerVideoController设置视频控制器

其中,PlaybackSpeed定义如下所示:

名称描述
Speed_Forward_0_75_X0.75倍速播放
Speed_Forward_1_00_X1倍速播放
Speed_Forward_1_25_X1.25倍速播放
Speed_Forward_1_75_X1.75倍速播放
Speed_Forward_2_00_X2倍速播放

2.1.2、属性

除支持通用属性外,还支持以下属性:

名称参数类型描述
mutedboolean是否静音。默认值:false
autoPlayboolean是否自动播放。默认值:false
controlsboolean控制视频播放的控制栏是否显示。默认值:true
objectFitImageFit设置视频显示模式。默认值:Cover
loopboolean是否单个视频循环播放。默认值:false

2.1.3、事件

除支持通用事件外,还支持以下事件:

名称功能描述
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)在全屏播放与非全屏播放状态之间切换时触发该事件,返回值为true表示进入全屏播放状态,为false则表示非全屏播放

2.1.4、VideoController

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

(1)导入对象

  •  

controller: VideoController = new VideoController()

(2)start

start(): void

开始播放。

(3)pause

pause(): void

暂停播放,显示当前帧,再次播放时从当前位置继续播放。

(4)stop

stop(): void

停止播放,显示当前帧,再次播放时从头开始播放。

2.1.5、exitFullscreen

exitFullscreen()

退出全屏播放。

2.1.6、setCurrentTime

setCurrentTime(value: number)

指定视频播放的进度位置。

其中,参数定义如下:

参数名参数类型必填参数描述
valuenumber视频播放进度位置,单位为s

3、程序解析

本案例展示了视频组件的基本功能,以及如何控制播放状态的相关能力。包括视频组件化,全屏化,窗口化,上下轮播视频等。

本案例主要分为以下几个部分:

(1)MainPage.ets,负责主页面,通过调用其它自定义控件播放视频;

(2)VideoPage.ets:负责上方轮播图视频播放和控制;

(3)SmallVideo.ets:负责小窗口视频播放和控制;

(4)LivePage.ets:负责显示直播页面;

(5)FullPage.ets:全屏显示视频播放页面;

3.1、申请权限

申请网络视频权限,在entry/src/main/module.json5文件中添加如下内容:

  •  
  •  
  •  
  •  
  •  

"requestPermissions": [ { "name": "ohos.permission.INTERNET" }]

3.2、MainPage.ets

在entry/src/main/ets/pages/Index.ets文件中调用MainPage自定义组件。

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  

import { MainPage } from "@ohos/video-component"
@Entry@Componentstruct Index { @State message: string = 'Hello World'
build() { Column() { MainPage() } .width('100%') .height('100%') }}

在VideoComponent/src/main/ets/components/pages/MainPage.ets文件中,首先设置媒体查询的查询条件。

listenerIsPhone = mediaQuery.matchMediaSync('(orientation:landscape)');

其次,对监听句柄进行事件绑定。

  •  
  •  
  •  
  •  

async aboutToAppear() { this.portraitFunc = this.onPortrait.bind(this) // 绑定 this.listenerIsPhone.on('change', this.portraitFunc)}

再次,通过调用VideoPage显示轮播图视频播放。

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  

Swiper() { // 视频界面,调用自定义的VideoPage.ets VideoPage({ isStart: $openFirst }) // 模拟Swiper数据 LazyForEach(new MyDataSource(this.arrSwiper), (item) => { Text(item.toString()) .width('100%') .aspectRatio(1.12) .backgroundColor(0xAFEEEE) .textAlign(TextAlign.Center) .fontSize(20) }, item => item)}

再次,调用SmallVideo显示小视频播放。

  •  
  •  
  •  
  •  
  •  

Column() { SmallVideo({ isHidden: $isHidden, isCancel: $isCancel })}.width('100%').alignItems(HorizontalAlign.End)

最后,显示直播视频按键。

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  

Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) { Image($r('app.media.broadcast')) .objectFit(ImageFit.Contain) .width('24') .height('24') .margin({ top: 10 }) Text($r("app.string.in_live")) .fontSize(10) .fontColor('#000000') .margin({ top: 5 })}.width(58).height(58).backgroundColor('#FFFFFF').border({ color: 'rgba(0,0,0,0.2)' }).borderRadius(16).borderWidth(1.3).key('directVideo').onClick(() => { router.push({ url: 'pages/LivePage' })}).position({ x: '86%', y: '20%' })}.width('100%').height('100%').backgroundColor(0xDCDCDC)

注意:当Flex触发鼠标按下事件,则通过router.push()跳转到LivePage.ets页面。

3.3、VideoPage.ets

首先,定义播放视频的资源以及视频播放控制器。

  •  
  •  

@State videoSrc: Resource = $rawfile('video_4.mp4') // 视频播放文件detailVideoController: VideoController = new VideoController()  // 设置视频播放的控制器,比如控制视频开始,暂停等

 

其次,调用Video组件,并将视频资源和视频控制器代入。

  •  
  •  
  •  
  •  

Video({ src: this.videoSrc, // 设置视频文件地址 controller: this.detailVideoController, // 设置视频播放的控制器,比如控制视频开始,暂停等})

最后,通过video组件的.onClick()响应事件,控制视频播放。

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  

.onClick(() => { // 单击按钮事件 if (this.isPlayClick) { // 判断play按钮是否用过,没有用过,进入这层 if (this.firstClick) { // 第一次点击视频开始播放,再次点击进入全屏 this.detailVideoController.start() // Video开始播放 this.isHidden = !this.isHidden this.isStart = true this.firstClick = !this.firstClick } else { // 页面跳转 router.push({ url: 'pages/FullPage', params: { videoSrc: this.videoSrc, videoTime: this.updateTime } }) } } else { // 页面跳转 router.push({ url: 'pages/FullPage', params: { videoSrc: this.videoSrc, videoTime: this.updateTime } }) }})

其中,关于播放时间显示(即变量updateTime)需要特别注意。在此不赘述。

3.4、SmallVideo.ets

SmallVideo自定义组件则负责小窗口视频播放,通过调用Video播放视频文件。

首先,定义视频资源和视频控制器。

  •  
  •  

@State smallVideoSrc: Resource = $rawfile('video_4.mp4') // 视频数据源文件smallVideoController: VideoController = new VideoController()   // 设置视频控制器

 

其次,将视频资源和视频控制器放入Video控件。

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  

Video({ src: this.smallVideoSrc, // 视频播放源的路径,支持本地视频路径和网络路径 controller: this.smallVideoController // 设置视频控制器}) .controls(false) .autoPlay(true) // 设置自动播放 .muted(true) // 设置静音 .onFinish(() => { // 播放结束时触发该事件 this.isHidden = false })

注意:.onFinish()事件是在视频播放完毕后触发。

3.5、LivePage.ets

LivePage.ets负责显示直播页面。

首先,定义一个媒体查询的监听句柄。

listenerIsPhone = mediaQuery.matchMediaSync('(orientation:landscape)');

其次,在aboutToAppear()中将视频播放绑定,并通过http连接请求,获取网络视频信息。

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  

async aboutToAppear() { this.portraitFunc = this.onPortrait.bind(this) // bind current js instance this.listenerIsPhone.on('change', this.portraitFunc)
try { let a = await Live() // http连接请求 this.mData = JSON.parse(a.result.toString()) this.liveInfoList = this.mData.data } catch (error) { console.log('http resquest is fail:' + error) }}

最后,在build()中显示网络视频直播。

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  

ForEach(this.liveInfoList, (item, index) => { Stack() { if (this.active == index) { Video({ src: item.uri }) .autoPlay(true) .loop(false) .controls(false) .objectFit(ImageFit.Contain) .width('100%') .height('100%') } ...... } ......}

3.6、FullPage.ets

FullPage.ets负责全屏显示视频播放页面。

首先,定义一个媒体查询的监听句柄和视频控制器。

  •  
  •  

listenerIsPhone = mediaQuery.matchMediaSync('(orientation:landscape)')fullVideoController: VideoController = new VideoController()

 

其次,在aboutToAppear()中绑定当前用例。

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  

aboutToAppear() { this.fullParams = router.getParams() this.fullSrc = this.fullParams['videoSrc'] this.playTime = this.fullParams['videoTime']
this.portraitFunc = this.onPortrait.bind(this) // bind current js instance this.listenerIsPhone.on('change', this.portraitFunc)}

最后,调用Video组件控制视频播放。

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  

Video({ src: this.fullSrc, controller: this.fullVideoController}) .width('100%') .height('100%') .autoPlay(true) .loop(true) .controls(false) .objectFit(ImageFit.Contain) .onPause(() => { this.isHidden = true }) .onFullscreenChange((e) => { this.isHidden = false }) .onStart(() => { this.isHidden = false }) .onPrepared((e) => { this.fullVideoController.setCurrentTime(this.playTime) this.maxValue = e.duration }) .onUpdate((e) => { this.nowValue = e.time }) .onClick(() => { this.fullVideoController.pause(); })

4、项目编译

4.1、打开项目

打开DevEco Studio,再打开自定义通知项目。

4.2、编译程序

点击菜单栏上的“Build” -> "Rebuild Project"。如果出现无法编译,则注意查看Event Log界面。如下所示:

APP

点击Run 'npm install',让DevEco Studio安装相关依赖包。

重新点击菜单栏上的“Build” -> "Rebuild Project"。出现如下错误:

APP

点击上图红色框部分,安装相关服务。

重新点击菜单栏上的“Build” -> "Rebuild Project",编译成功。

APP

4.3、安装程序

点击“entry”按钮,将项目程序安装到设备端。如下图所示:

APP

如果出现下述报错,表示无法安装。如图所示:

APP

点击上图红色框的蓝色字体,弹出"Project Structure"对话框,点击"Apply",再点击"OK"。如图所示:

APP

重新点击“entry”按钮,将项目程序安装到设备端。

APP

 

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分