HarmonyOS 鸿蒙Next中VIDEO组件循环播放
HarmonyOS 鸿蒙Next中VIDEO组件循环播放
Video({
src: VideoSources[this.Params.id][0], //视频地址
previewUri: VideoSources[this.Params.id][1],
currentProgressRate: this.VideoSpeed,
controller: this.Running_Video_controller
}).controls(false)//控制栏不显示
.loop(true)//循环播放
.onStop(() => {
router.replaceUrl({
url: pageManager.Running_EndingPage,
params: {
running_data: this.runningData
}
}, router.RouterMode.Single, (err) => {
if (err) {
console.log('路由失败')
}
});
})
.onFinish(() => {
this.Running_Video_controller.start()
})
在使用loop循环播放时,视频的结尾与下一次的开头会有很微弱的停顿闪烁,有什么好的方法解决?
更多关于HarmonyOS 鸿蒙Next中VIDEO组件循环播放的实战教程也可以访问 https://www.itying.com/category-93-b0.html
【背景知识】
- Video组件用于播放视频文件并控制其播放状态,常用于短视频和应用内部视频的列表页面。具体用法请参考Video。
- 播放停止时触发onStop事件(当stop()方法被调用后触发),支持attributeModifier动态设置属性方法。
- setCurrentTime用于指定视频播放的进度位置,取值范围为[0,duration],单位为秒。从API version 8开始,支持设置视频的跳转模式,视频跳转模式选项详见SeekMode枚举说明。
【修改建议】
尝试在onFinish回调事件里边通过setCurrentTime和SeekMode指定视频播放的进度位置,并指定跳转模式,在视频播放结束时直接精准定位到视频0s位置,避免播放状态重置时引起加载状态的显示。示例代码如下:
// 直接定位到起始位置(避免重置)
this.controller.setCurrentTime(0, SeekMode.Accurate) // 精准跳转到视频的0s位置
更多关于HarmonyOS 鸿蒙Next中VIDEO组件循环播放的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
官网弄了个demo改了一下,不卡啊,是你视频有问题吗,测试的日志也很明显,视频到末尾21秒后,下一个就是0,不存在重新加载资源什么的
// xxx.ets
@Entry
@Component
struct VideoCreateComponent {
// $rawfile('video1.mp4')、$r('app.media.poster1')需要分别替换为开发者所需的视频、图片资源文件
@State previewUri: Resource = $r('app.media.startIcon');
@State curRate: PlaybackSpeed = PlaybackSpeed.Speed_Forward_1_00_X;
@State isAutoPlay: boolean = false;
@State showControls: boolean = true;
@State isShortcutKeyEnabled: boolean = false;
@State showFirstFrame: boolean = false;
controller: VideoController = new VideoController();
build() {
Column() {
Video({
src: "https://vd2.bdstatic.com/mda-riadktnbps72zsd6/720p/h264/1757583400236609958/mda-riadktnbps72zsd6.mp4",
previewUri: this.previewUri, // 设置预览图
currentProgressRate: this.curRate, // 设置播放速度
controller: this.controller,
})
.width('100%')
.loop(true)
.height(600)
.autoPlay(this.isAutoPlay)
.controls(this.showControls)
.enableShortcutKey(this.isShortcutKeyEnabled)
.onStart(() => {
console.info('onStart');
})
.onPause(() => {
console.info('onPause');
})
.onFinish(() => {
console.info('onFinish');
})
.onError(() => {
console.info('onError');
})
.onStop(() => {
console.info('onStop');
})
.onPrepared((e?: DurationObject) => {
if (e != undefined) {
console.info('onPrepared is ' + e.duration);
}
})
.onSeeking((e?: TimeObject) => {
if (e != undefined) {
console.info('onSeeking is ' + e.time);
}
})
.onSeeked((e?: TimeObject) => {
if (e != undefined) {
console.info('onSeeked is ' + e.time);
}
})
.onUpdate((e?: TimeObject) => {
if (e != undefined) {
console.info('onUpdate is ' + e.time);
}
})
.onFullscreenChange((e?: FullscreenObject) => {
if (e != undefined) {
console.info('onFullscreenChange is ' + e.fullscreen);
}
})
Row() {
Button('start').onClick(() => {
this.controller.start(); // 开始播放
}).margin(2)
Button('pause').onClick(() => {
this.controller.pause(); // 暂停播放
}).margin(2)
Button('stop').onClick(() => {
this.controller.stop(); // 结束播放
}).margin(2)
Button('reset').onClick(() => {
this.controller.reset(); // 重置AVPlayer
}).margin(2)
Button('setTime').onClick(() => {
this.controller.setCurrentTime(10, SeekMode.Accurate); // 精准跳转到视频的10s位置
}).margin(2)
}
Row() {
Button('rate 0.75').onClick(() => {
this.curRate = PlaybackSpeed.Speed_Forward_0_75_X; // 0.75倍速播放
}).margin(5)
Button('rate 1').onClick(() => {
this.curRate = PlaybackSpeed.Speed_Forward_1_00_X; // 原倍速播放
}).margin(5)
Button('rate 2').onClick(() => {
this.curRate = PlaybackSpeed.Speed_Forward_2_00_X; // 2倍速播放
}).margin(5)
}
}
}
}
interface DurationObject {
duration: number;
}
interface TimeObject {
time: number;
}
interface FullscreenObject {
fullscreen: boolean;
}
启用无缝循环参数
在设置.loop(true)的基础上,补充视频填充模式参数,避免因分辨率适配问题导致画面闪烁:
Video({
src: this.videoSrc,
controller: this.controller
})
.loop(true)
.objectFit(ImageFit.Cover) // 优先使用Cover模式填充画面
预加载视频资源
通过.autoPlay(true)和.controls(false)确保视频资源在准备完成后立即播放,减少加载间隙:
Video({
src: this.innerResource,
previewUri: $r('app.media.preview'),
controller: this.controller
})
.autoPlay(true) // 自动播放减少初始加载延迟
.controls(false) // 隐藏默认控制条避免UI干扰
可以尝试以下方法
1.提前加载资源:在视频播放前预加载视频文件,减少循环时的加载延迟。可通过VideoController的预加载方法实现:
this.Running_Video_controller.prepare(); // 提前初始化播放资源
2.移除冗余回调:当前的.onFinish(() => { this.Running_Video_controller.start() })可能与loop(true)的自动循环逻辑冲突,导致重复触发。建议删除此回调,仅依赖loop(true)属性。
3.隐藏切换过程:在视频即将结束时,短暂隐藏组件或添加过渡动画覆盖闪烁:
@State isVideoVisible: boolean = true;
Video({ ... })
.visibility(this.isVideoVisible ? Visibility.Visible : Visibility.Hidden)
.onFinish(() => {
this.isVideoVisible = false;
setTimeout(() => { this.isVideoVisible = true; }, 50); // 短暂隐藏再显示
});
建议看一下视频源,特别是片头和片尾的那几帧数据,可以切掉之后再看看。
在HarmonyOS鸿蒙Next中,使用VIDEO组件实现循环播放可通过设置loop属性为true实现。示例代码:
<video src="video.mp4" loop="true"></video>
该属性控制视频播放完成后自动重新开始,无需额外逻辑处理。
在HarmonyOS Next中,可以通过调整视频播放器的缓冲策略来减少循环播放时的停顿闪烁。建议在Video组件中设置autoPlay
为true,并确保视频资源已预加载。此外,可以尝试使用onFinish
事件中直接调用start()
方法,但需注意避免重复触发。检查视频编码格式,确保为流媒体优化格式(如H.264),以减少解码延迟。若问题持续,可考虑使用双Video组件交替播放来实现无缝衔接。