HarmonyOS鸿蒙Next中video组件如何获取视频播放进度,然后展示出来
HarmonyOS鸿蒙Next中video组件如何获取视频播放进度,然后展示出来 video 组件如何获取视频播放进度,然后展示出来
【背景知识】
- Video组件:封装了视频播放的基础能力,需要设置数据源以及基础信息即可播放视频,但相对扩展能力较弱。如果开发者想自定义视频播放,请参考视频播放。
- onPrepared:视频准备完成时触发该事件,支持attributeModifier动态设置属性方法。
- onUpdate:播放进度变化时触发该事件,支持attributeModifier动态设置属性方法。
- [@Prop装饰器](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-prop):@Prop装饰的变量可以和父组件建立单向同步关系。
【解决方案】
通过事件回调机制来实现。核心思路是:
- 子组件(Player)定义回调接口:在Player组件中,定义可以被父组件传递进来的回调函数onPrepared和onUpdate,分别用于获取视频时长和监控播放进度变化。
- 父组件传递回调函数:父组件在调用Player时,通过属性方式传入具体的回调函数实现。
- 子组件在适当时机调用:Player内部的Video组件在onPrepared(获取时长)和onUpdate(获取进度)等事件触发时,调用父组件传过来的回调函数。
具体代码实现如下:
父组件:
@Component
@Entry
struct MovePage {
@State duration: number = 0; // 视频总时长状态
@State time: number = 0; // 当前播放时间状态
build() {
Column({ space: 20 }) {
Column() {
Player({
src: $rawfile('example.mp4'),
isControls: true,
onPrepared: (duration: number) => {
this.duration = duration;
},
onUpdate: (time: number) => {
this.time = time;
}
});
}
.width('100%')
.height('70%');
Column({ space: 5 }) {
Text('视频总时长:' + this.duration + 's');
Text('当前播放进度:' + this.time + 's');
}.width('100%');
}
.width('100%')
.height('100%');
}
}
子组件:
@Component
export default struct Player {
[@Prop](/user/Prop) src: string | Resource;
[@Prop](/user/Prop) isControls: boolean = true;
onPrepared?: (duration: number) => void; // 视频准备完成时触发该事件
onUpdate?: (time: number) => void; // 播放进度变化时触发该事件
private videoController: VideoController = new VideoController();
build() {
Column({ space: 10 }) {
Video({
src: this.src,
controller: this.videoController
})
.loop(true)// 循环播放
.objectFit(ImageFit.Cover)// 画面填充模式
.controls(this.isControls)// 绑定控制条
.onPrepared((event) => {
this.onPrepared?.(event.duration); // 获取到总时长后调用
})
.onUpdate((event) => {
this.onUpdate?.(event.time); // 当前视频播放的进度
})
.onError(() => {
console.error('播放失败');
});
Row({ space: 10 }) {
Button('开始播放')
.onClick(() => {
this.videoController.start();
});
Button('暂停播放')
.onClick(() => {
this.videoController.pause();
});
};
}.width('100%')
.height('90%');
}
}
更多关于HarmonyOS鸿蒙Next中video组件如何获取视频播放进度,然后展示出来的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
背景知识:
-
事件监听机制
Video组件通过 onUpdate 事件实时获取当前播放进度,通过 onPrepared 事件获取视频总时长1。这两个事件是进度展示的关键。
-
数据格式转换
将获取的时间戳(单位:秒)转换为 mm:ss 格式,通过文本组件展示。
问题解决:
Video({
//这里可以使用http网络资源,也可以使用本地的media资源
src: $r('app.media.video_sample'),
controller: this.vController
})
.controls(false) // 隐藏默认控制器
.onPrepared((event: PreparedInfo) => {
//准备中获取总时长
event.duration; // 获取总时长(秒)
this.formatTime(event.duration); // 转格式
})
.onUpdate((event: PlaybackInfo) => {
//每秒更新回调
event.time; // 实时更新当前播放时间(秒)
this.formatTime(event.time); // 转格式
})
// 将秒数转为 mm:ss 格式
private formatTime(seconds: number): string {
const minutes = Math.floor(seconds / 60);
const remainingSeconds = seconds % 60;
return `${this.padZero(minutes)}:${this.padZero(remainingSeconds)}`;
}
// 补零函数
private padZero(num: number): string {
return num < 10 ? `0${num}` : `${num}`;
}
找HarmonyOS工作还需要会Flutter的哦,有需要Flutter教程的可以学学大地老师的教程,很不错,B站免费学的哦:https://www.bilibili.com/video/BV1S4411E7LY/?p=17,
获取播放进度需要使用两个回调方法:
onPrepared(callback: Callback<PreparedInfo>):视频准备完成时触发该事件,可获取视频播放长度
onUpdate(callback: Callback<PlaybackInfo>) :播放进度变化时触发该事件,可获取当前播放时间
当前播放进度为 e.time / e.duration
Video({
src: 'your-video-url',
})
.onPrepared((e: PreparedInfo) => {
console.info('总时长 ' + e.duration);
})
.onUpdate((e?: PlaybackInfo) => {
if (e != undefined) {
// 当前播放时间
console.info('当前播放到 ' + e.time);
}
})
在HarmonyOS Next中,使用VideoController的getCurrentTime()方法获取当前播放时间(单位:毫秒)。通过监听onUpdate事件实时更新进度。使用Text组件展示格式化后的时间,例如“当前播放位置:${currentTime}ms”。
在HarmonyOS Next中,可以通过监听VideoController的onCurrentTimeUpdate事件来获取视频播放进度。
具体实现步骤如下:
- 创建VideoController:在组件中创建VideoController对象,用于控制视频播放和监听事件。
private videoController: VideoController = new VideoController();
- 监听播放进度:通过
onCurrentTimeUpdate回调函数获取当前播放时间。
this.videoController.onCurrentTimeUpdate((currentTime: number) => {
// currentTime单位为秒,可转换为需要的时间格式
this.currentTime = this.formatTime(currentTime);
});
- 绑定到Video组件:将controller绑定到Video组件。
Video({
src: $rawfile('video.mp4'),
controller: this.videoController
})
- 展示进度:在UI中显示格式化后的时间。
Text(this.currentTime)
.fontSize(16)
- 时间格式化示例:
private formatTime(seconds: number): string {
const min = Math.floor(seconds / 60);
const sec = Math.floor(seconds % 60);
return `${min.toString().padStart(2, '0')}:${sec.toString().padStart(2, '0')}`;
}
完整示例:
@Entry
@Component
struct VideoProgressExample {
private videoController: VideoController = new VideoController();
@State currentTime: string = '00:00';
build() {
Column() {
Video({
src: $rawfile('video.mp4'),
controller: this.videoController
})
.width('100%')
.height(300)
Text(`当前进度: ${this.currentTime}`)
.fontSize(16)
.margin(10)
}
}
aboutToAppear() {
this.videoController.onCurrentTimeUpdate((currentTime: number) => {
this.currentTime = this.formatTime(currentTime);
});
}
private formatTime(seconds: number): string {
const min = Math.floor(seconds / 60);
const sec = Math.floor(seconds % 60);
return `${min.toString().padStart(2, '0')}:${sec.toString().padStart(2, '0')}`;
}
}
这样就可以实时获取并显示视频播放进度了。

