接口
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
使用案例:
- Video最原始样式,调用VideoPlayer组件,传入一个source,这样就能让一个视频播放起来了
- 为了使页面美观,同时能让用户预览内容,可以增加一个previewUris,给视频增加一个未播放时的预览图,也可以使用网络和本地地址
- 在播放过程中发现视频被拉伸,显示不全,可以通过设置 .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来查询公共媒体库中的视频文件
自定义视频播放控制器:
- 当Video组件的原生控制器的样式和功能不能满足业务需求时,此时需要隐藏原生控制器 .controls(false)
- 自定义控制器包括的功能:控制视频播放、暂停、显示视频总时长、播放起始时间以及控制和显示播放速度
- 增加一个参数 VideoController对象controller,用于控制视频的播放、暂停等功能
- 自定义一个视频播放器的控制栏VideoSlider组件,并将controller传递进去
- 在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)
}
}