3.4 Video组件 原创 精华
本节演示视频播放组件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.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)
}
}
本地预览器无法观看效果,可以到远程模拟器体验,效果如下:
【本节源码:https://gitee.com/cloudev/harmonyos3/tree/master/3.0/BaseComponent 】
感谢老师详细的示例