HarmonyOS 鸿蒙Next中AVPlayer播放HLS流媒体视频时,设置seek后实际播放位置和seek位置有很大偏差
HarmonyOS 鸿蒙Next中AVPlayer播放HLS流媒体视频时,设置seek后实际播放位置和seek位置有很大偏差
组件功能操作流程如下:组件加载自动播放视频,然后我拖动Slider调用seek方法,此时日志记录seek设置的time,通过avplayer的Events.TIME_UPDATE事件监控输出time,发现seek的time和播放的time差了好多,大部分时候time直接变0了,有的时候差了很多很多
播放的是hls类型,m3u8格式的流媒体,媒体是服务器转码的。我知道可能是媒体的原因,但能否有人帮忙解惑下对流媒体有什么要求?
代码部分如下,进度条:
Slider({
value: this.progressVal,
min: 0,
max: 100,
step: 1,
})
.onChange((value: number, mode: SliderChangeMode) => {
this.mediaController?.setSeekTime(value, mode)
// ...
})
mediaController的setSeekTime代码:
setSeekTime(value: number, mode: SliderChangeMode) {
if (mode === Number(SliderMode.MOVING)) {
// 拖动进度条回显处理
}
this.seekTime = Math.round(value * this.duration / ONE_HUNDRED)
if (mode == Number(SliderChangeMode.Begin)) {
return
}
if (mode === Number(SliderChangeMode.End) || mode === Number(SliderChangeMode.Click)) {
if (this.avPlayer !== null) {
logger.debug(`time set: percent: ${value}, time: ${this.seekTime}`)
this.avPlayer.seek(this.seekTime, media.SeekMode.SEEK_CLOSEST)
this.avPlayer.play()
}
}
}
avPlayer事件监听:
this.avPlayer.on(Events.STATE_CHANGE, async (state: media.AVPlayerState) => {
// ...
switch (avplayerStatus) {
case AvplayerStatus.IDLE:
// 初始化进度URL等
break
case AvplayerStatus.INITIALIZED:
// 初始化surfaceId等
this.avPlayer.prepare()
break
case AvplayerStatus.PREPARED:
this.duration = this.avPlayer.duration
// 其他初始化行为以及父级事件回调
break
case AvplayerStatus.PLAYING:
// 设置声音和播放状态等
break
case AvplayerStatus.PAUSED:
// 暂停播放处理
break
case AvplayerStatus.COMPLETED:
// 播放完成处理
this.avPlayer.reset()
break
case AvplayerStatus.RELEASED:
this.avPlayer.release()
// 其他释放资源行为
break
default:
break
}
})
this.avPlayer.on(Events.TIME_UPDATE, (time: number) => {
this.loadProgress(time)
})
loadProgress代码:
loadProgress(time: number) {
let nowSeconds = Math.floor(time / A_THOUSAND)
let totalSeconds = Math.floor(this.duration / A_THOUSAND)
const dateTimeNow = date.secondToTime(nowSeconds)
if (this.mediaPlayerInfo.currentTime == dateTimeNow) {
return
}
this.mediaPlayerInfo.currentTime = dateTimeNow
this.mediaPlayerInfo.totalTime = date.secondToTime(totalSeconds)
this.mediaPlayerInfo.progressVal = Math.floor(nowSeconds * ONE_HUNDRED / totalSeconds)
logger.debug(`time get: percent: ${this.mediaPlayerInfo.progressVal}, time: ${time}`)
this.triggerTimeUpdate()
}
play方法代码:
play() {
if (this.avPlayer && (this.avPlayer.state === AvplayerStatus.PAUSED || this.avPlayer.state === AvplayerStatus.PREPARED
|| this.avPlayer.state === AvplayerStatus.COMPLETED || this.avPlayer.state === AvplayerStatus.STOPPED)) {
this.avPlayer.play()
}
}
服务器转码,码率设置很低,然后进入页面开始播放,拖动Slider松开,然后等视频正常播放再次拖动松开重复,从日志可以看到,每次拖动设置的是正确的seek,以及第一次get是正确的,但是马上time就变为0了
06-05 01:53:47.260 12217-12217 A0ff09/MINFY_LOGGER com.rdminfo.minfy D onStatusChange: initialized
06-05 01:53:48.820 12217-12217 A0ff09/MINFY_LOGGER com.rdminfo.minfy D onStatusChange: prepared
06-05 01:53:48.820 12217-12217 A0ff09/MINFY_LOGGER com.rdminfo.minfy D onStatusChange: prepared
06-05 01:53:48.838 12217-12217 A0ff09/MINFY_LOGGER com.rdminfo.minfy D onStatusChange: playing
06-05 01:53:49.937 12217-12217 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 0, time: 1034
06-05 01:53:50.646 12217-12217 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 0, time: 1745
06-05 01:53:50.747 12217-12217 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 0, time: 1840
06-05 01:53:50.850 12217-12217 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 0, time: 1942
06-05 01:53:50.950 12217-12217 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 0, time: 2043
06-05 01:53:50.972 12217-12217 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time set: percent: 36, time: 2664745
06-05 01:53:57.905 12217-12217 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 35, time: 2664745
06-05 01:53:57.905 12217-12217 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 0, time: 170
06-05 01:53:58.811 12217-12217 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 0, time: 1066
06-05 01:53:59.824 12217-12217 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 0, time: 2090
06-05 01:54:00.750 12217-12217 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 0, time: 3007
06-05 01:54:00.935 12217-12217 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 0, time: 3199
06-05 01:54:00.953 12217-12217 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 0, time: 3199
06-05 01:54:01.037 12217-12217 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 0, time: 3285
06-05 01:54:01.053 12217-12217 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 0, time: 3306
06-05 01:54:01.137 12217-12217 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 0, time: 3391
06-05 01:54:01.240 12217-12217 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 0, time: 3498
06-05 01:54:01.360 12217-12217 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time set: percent: 51, time: 3775055
06-05 01:54:08.578 12217-12217 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 50, time: 3775055
06-05 01:54:08.579 12217-12217 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 0, time: 170
06-05 01:54:09.433 12217-12217 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 0, time: 1002
06-05 01:54:10.434 12217-12217 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 0, time: 2005
06-05 01:54:10.859 12217-12217 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 0, time: 2453
06-05 01:54:10.902 12217-12217 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 0, time: 2495
06-05 01:54:10.941 12217-12217 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 0, time: 2538
06-05 01:54:10.961 12217-12217 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 0, time: 2559
06-05 01:54:11.042 12217-12217 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 0, time: 2623
06-05 01:54:11.061 12217-12217 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 0, time: 2645
06-05 01:54:11.106 12217-12217 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 0, time: 2687
06-05 01:54:11.143 12217-12217 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 0, time: 2730
06-05 01:54:11.163 12217-12217 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 0, time: 2751
06-05 01:54:11.206 12217-12217 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 0, time: 2794
06-05 01:54:11.245 12217-12217 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 0, time: 2837
06-05 01:54:11.308 12217-12217 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 0, time: 2879
06-05 01:54:11.346 12217-12217 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 0, time: 2922
06-05 01:54:11.447 12217-12217 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 0, time: 3029
06-05 01:54:11.966 12217-12217 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time set: percent: 94, time: 6957945
06-05 01:54:19.127 12217-12217 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 93, time: 6957945
06-05 01:54:19.128 12217-12217 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 0, time: 42
06-05 01:54:20.000 12217-12217 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 0, time: 1023
06-05 01:54:21.010 12217-12217 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 0, time: 2047
06-05 01:54:21.589 12217-12217 A0ff09/MINFY_LOGGER com.rdminfo.minfy D onStatusChange: released
当我把码率设置高一点,然后再播放,同样的代码操作日志如下:可以看出来进度不会回到0了,稍微正常一点,但是仍有偏差,可以确认是源的原因了,是因为不兼容?有没有官方或者大佬解答下,快崩溃了…
06-05 02:03:17.383 16424-16424 A0ff09/MINFY_LOGGER com.rdminfo.minfy D onStatusChange: initialized
06-05 02:03:18.281 16424-16424 A0ff09/MINFY_LOGGER com.rdminfo.minfy D onStatusChange: prepared
06-05 02:03:18.282 16424-16424 A0ff09/MINFY_LOGGER com.rdminfo.minfy D onStatusChange: prepared
06-05 02:03:18.305 16424-16424 A0ff09/MINFY_LOGGER com.rdminfo.minfy D onStatusChange: playing
06-05 02:03:19.398 16424-16424 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 0, time: 1032
06-05 02:03:20.205 16424-16424 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 0, time: 1828
06-05 02:03:20.307 16424-16424 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 0, time: 1930
06-05 02:03:20.407 16424-16424 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 0, time: 2027
06-05 02:03:20.510 16424-16424 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 0, time: 2127
06-05 02:03:20.624 16424-16424 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time set: percent: 27, time: 1998559
06-05 02:03:21.087 16424-16424 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 26, time: 1998559
06-05 02:03:21.087 16424-16424 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 33, time: 2447701
06-05 02:03:21.593 16424-16424 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 33, time: 2448063
06-05 02:03:22.601 16424-16424 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 33, time: 2449069
06-05 02:03:22.827 16424-16424 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 33, time: 2449296
06-05 02:03:22.904 16424-16424 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 33, time: 2449367
06-05 02:03:22.930 16424-16424 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 33, time: 2449391
06-05 02:03:23.006 16424-16424 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 33, time: 2449467
06-05 02:03:23.028 16424-16424 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 33, time: 2449491
06-05 02:03:23.104 16424-16424 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time set: percent: 61, time: 4515262
06-05 02:03:23.566 16424-16424 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 74, time: 5498368
06-05 02:03:24.270 16424-16424 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 74, time: 5499025
06-05 02:03:25.125 16424-16424 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 74, time: 5499870
06-05 02:03:25.139 16424-16424 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 74, time: 5499885
06-05 02:03:25.176 16424-16424 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 74, time: 5499922
06-05 02:03:25.225 16424-16424 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 74, time: 5499971
06-05 02:03:25.280 16424-16424 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 74, time: 5500033
06-05 02:03:25.325 16424-16424 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 74, time: 5500078
06-05 02:03:25.383 16424-16424 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 74, time: 5500134
06-05 02:03:25.426 16424-16424 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 74, time: 5500178
06-05 02:03:25.483 16424-16424 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 74, time: 5500234
06-05 02:03:25.525 16424-16424 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 74, time: 5500278
06-05 02:03:25.619 16424-16424 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time set: percent: 88, time: 6513821
06-05 02:03:31.271 16424-16424 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 87, time: 6513821
06-05 02:03:31.280 16424-16424 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 0, time: 170
06-05 02:03:32.117 16424-16424 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 0, time: 1002
06-05 02:03:33.121 16424-16424 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 0, time: 2005
06-05 02:03:34.132 16424-16424 A0ff09/MINFY_LOGGER com.rdminfo.minfy D time get: percent: 0, time: 3029
06-05 02:03:34.481 16424-16424 A0ff09/MINFY_LOGGER com.rdminfo.minfy D onStatusChange: released
更多关于HarmonyOS 鸿蒙Next中AVPlayer播放HLS流媒体视频时,设置seek后实际播放位置和seek位置有很大偏差的实战教程也可以访问 https://www.itying.com/category-93-b0.html
请问你这个流媒体是哪种形式?直播、点播?官方文档示例中提到直播是不支持seek的,另外还是需要这边提供下完整一些的demo。
更多关于HarmonyOS 鸿蒙Next中AVPlayer播放HLS流媒体视频时,设置seek后实际播放位置和seek位置有很大偏差的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
找HarmonyOS工作还需要会Flutter的哦,有需要Flutter教程的可以学学大地老师的教程,很不错,B站免费学的哦:BV1S4411E7LY/?p=17
我用你上面的url测试是正常的。有问题的这个视频流是服务器转过来的,想问下怎么操作的?
你那边是正常的?进入页面点击播放,播放后拖动进度条,然后播放是正常的,但是进度条会异常,也就是time_update事件输出的time会异常,我能看下你那边输出的time的set,get日志吗?
添加了seekDone监听输出time,日志如下:seek_done和第一次get结束,time是正确的,而后又是0了
在HarmonyOS鸿蒙Next中,AVPlayer播放HLS流媒体时出现seek偏差,主要原因是HLS流媒体的时间戳不连续和关键帧间隔问题。HLS协议以TS片段为单位分割视频,AVPlayer只能定位到最近的关键帧位置。开发者可使用以下API优化:1)通过AVPlayer的currentPosition获取实际播放位置;2)使用seekToMode参数选择PRECISE模式(若支持);3)检查HLS切片时长是否过大,建议2-10秒。偏差程度取决于HLS分片策略和关键帧密度。
这个问题确实与HLS流媒体的特性有关。在HarmonyOS AVPlayer中处理HLS流媒体seek操作时,需要注意以下几点:
- HLS流媒体seek精度问题:
- HLS是基于分片的流媒体协议,seek操作会定位到最近的关键帧(I帧)
- 低码率视频通常关键帧间隔较大,导致seek后实际位置偏差明显
- 高码率视频关键帧间隔较小,seek精度会有所改善
- 建议的解决方案:
- 检查服务器端HLS分片设置,确保关键帧间隔合理(建议2-4秒)
- 在AVPlayer.seek()时使用SEEK_PREVIOUS_SYNC模式而非SEEK_CLOSEST
- 增加缓冲时间,给播放器足够时间定位准确位置
- 代码优化建议:
- 在seek后添加缓冲状态检测,等待PLAYING状态再更新UI
- 增加seek完成回调处理,避免立即查询播放位置
- 流媒体服务器要求:
- 确保m3u8索引文件包含准确的EXT-X-TARGETDURATION
- 视频分片时长建议2-10秒,不宜过长
- 关键帧间隔应与分片时长对齐
这个问题主要是HLS协议特性导致的,通过优化服务器端编码参数和客户端处理逻辑可以改善体验。