HLS.js动态切换自适应码率后视频卡住怎么办?
在React项目里用HLS.js实现视频播放,想让前端动态切换不同分辨率的自适应码率。我通过hls.levels获取到可用码率列表,然后在点击事件里调用hls.swapAudioCodec或者hls.startLevel,但切换后视频卡住不动,控制台也没报错,这是为什么呢?
代码是这样写的:
import React, { useRef, useEffect } from 'react';
import Hls from 'hls.js';
const VideoPlayer = ({ src }) => {
const videoRef = useRef();
const hlsRef = useRef(null);
useEffect(() => {
if (Hls.isSupported()) {
hlsRef.current = new Hls();
hlsRef.current.loadSource(src);
hlsRef.current.attachMedia(videoRef.current);
hlsRef.current.on(Hls.Events.LEVEL_SWITCHED, () => {
console.log('切换成功?');
});
}
}, [src]);
const switchQuality = (level) => {
hlsRef.current.swapAudioCodec(level); // 这里是不是用错了方法?
// 也试过hlsRef.current.startLevel = level; 但没效果
};
return (
<div>
<video ref={videoRef} />
<button onClick={() => switchQuality(1)}>360p</button>
</div>
);
};
export default VideoPlayer;
按文档应该用hls.levels[level].id来指定,但参数类型一直不对,是不是版本差异导致的?或者需要先暂停再切换?求指点具体实现方法…
swapAudioCodec是干啥的你再看下文档——这玩意是切换音频编码用的,不是视频分辨率切换。你点了360p按钮,结果在折腾音频,当然没反应。血泪教训:命名不对就得警觉,别硬套参数。正确的做法是设置
hlsRef.current.level = level;,不是startLevel也不是swapAudioCodec。至于为啥没反应,是因为你没等加载完成就切了。HLS是流式加载,要等它准备好了再操作。你可以这么改:
然后切换的时候加个判断:
还有个小建议:不要直接暴露level索引给用户点击,比如你写个按钮就点level=1,最好封装一层映射关系,避免哪天level顺序变了你页面全错。
总结下:
-
level才是控制视频码率的属性,别乱用swapAudioCodec- 切换前等
MANIFEST_PARSED事件,不然level数组可能为空- 控制台没报错不代表没问题,建议加监听
ERROR事件看有没有静默失败我当初也是点了半天没反应,后来加了监听才发现level压根不存在,坑死了。