名词解释
M3U8
M3U(MP3 URL的缩写)是一种播放多媒体列表的文件格式,M3U文件是一种纯文本文件。
而M3U8则是以utf-8编码的M3U文件,用于指示视频片段(ts)的位置和顺序。
HLS
HLS全称是Http Live Streaming,用于实时的音视频流的传输。
HLS协议由HTTP(传输协议),m3u8(索引文件)和ts(音视频片段数据)三部分组成。
HLS会把整个流分割成一个个ts文件,根据m3u8索引文件的位置和顺序,实时发送http请求下载ts片段。
MIME
MIME是描述消息内容类型的标准,所以MIME类型可以表示该消息的内容,如文本、图像、音频、视频或其他应用程序专用的数据。
浏览器通常使用MIME类型来确定如何处理URL,因此Web服务器在响应头中添加正确的MIME类型非常重要,否则浏览器可能会无法解析文件内容。
MIME的组成结构非常简单,由类型与子类型两个字符串中间用 / 分隔而组成,不允许有空格
如:text/plain
相关MIME类型
.m3u8文件:application/x-mpeg 或 application/x-mpegURL
.ts文件:video/MP2T
hls.js安装
npm
安装 npm install --save hls.js
使用 import Hls from 'hls.js';
举例
<!-- 如果页面只有1个video标签可以使用id获取元素,如果有多个建议使用ref -->
<video ref="videoRef" autoplay="true" controls></video>
const videoRef = ref();
const hls = ref<Hls>();
const setLiveHls = (url: string) => {
if (hls.value) {
hls.value.destroy();
}
// 如果给定的MIME类型和(可选的)编解码器可被当前的用户代理支持,则返回 true
if (Hls.isSupported()) {
hls.value = new Hls({
// Hlsjs 将持续缓冲,直到以下两个条件都满足为止:
// 缓冲区大小超出 maxBufferSize
// 缓冲区长度超出 maxBufferLength
maxBufferLength: 30, // 最大缓冲区长度
});
// 将 hls.js 附加到媒体元素
hls.value.attachMedia(videoRef.value);
// 绑定成功后 启动并载入 HLS 流
hls.value.on(Hls.Events.MEDIA_ATTACHED, () => {
if (hls.value) {
hls.value.loadSource(videoData.url);
}
});
// 索引文件解析完成后开始播放视频
hls.value.on(Hls.Events.MANIFEST_PARSED, () => {
videoRef.value.play();
});
// hls错误处理
hls.value.on(Hls.Events.ERROR, (event, data) => {
if (data.fatal && hls.value) {
switch (data.type) {
case Hls.ErrorTypes.NETWORK_ERROR:
// 恢复网络错误
hls.value.startLoad();
break;
case Hls.ErrorTypes.MEDIA_ERROR:
// 恢复媒体错误
hls.value.recoverMediaError();
break;
default:
// 销毁实例
hls.value.destroy();
break;
}
}
});
} else if (videoRef.value.canPlayType('application/vnd.apple.mpegurl')) {
videoRef.value.src = url;
}
};
// 可以在需要的地方调用方法,但是要保证videoRef有值
onMounted(() => {
setLiveHls('url');
});
HLS的error事件中的data数据类型
export declare interface ErrorData {
type: ErrorTypes;
details: ErrorDetails;
error: Error;
fatal: boolean;
errorAction?: IErrorAction;
buffer?: number;
bytes?: number;
chunkMeta?: ChunkMetadata;
context?: PlaylistLoaderContext;
event?: keyof HlsListeners | 'demuxerWorker';
frag?: Fragment;
part?: Part | null;
level?: number | undefined;
levelRetry?: boolean;
loader?: Loader<LoaderContext>;
networkDetails?: any;
stats?: LoaderStats;
mimeType?: string;
reason?: string;
response?: LoaderResponse;
url?: string;
parent?: PlaylistLevelType;
sourceBufferName?: SourceBufferName;
/**
* @deprecated Use ErrorData.error
*/
err?: {
message: string;
};
}