介绍
HLS.js 是一个 JavaScript 库,用于在网页上实现 HTTP Live Streaming (HLS)。它允许你在网页上播放由流媒体服务器提供的 HLS 格式的视频,这是一种常用于在线视频播放的协议。
HLS.js 的主要特点包括:
- 跨平台兼容性:支持在各种现代浏览器和平台上播放 HLS 视频,包括桌面和移动设备。
- 无需插件:HLS.js 不需要额外的插件或扩展程序,只需在网页中包含相应的 JavaScript 文件即可。
- 模块化:HLS.js 提供了模块化的设计,可以方便地集成到各种项目中。
- 开源:HLS.js 是开源项目,源代码托管在 GitHub 上,可以自由使用和修改。
使用教程
以下是使用 HLS.js 的简单教程:
- 引入 HLS.js 库:首先,你需要在你的网页中引入 HLS.js 库。你可以从 CDN 上获取最新版本的 HLS.js,也可以下载到本地然后引入。
<script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
- 创建视频播放器:在 HTML 文件中创建一个
<video>
元素,用于播放 HLS 视频。
<video id="videoPlayer" controls></video>
- 初始化 HLS.js:在 JavaScript 中初始化 HLS.js,指定 HLS 视频的 URL,并将其绑定到
<video>
元素。
if (Hls.isSupported()) {
var video = document.getElementById('videoPlayer');
var hls = new Hls();
hls.loadSource('your_hls_video_url.m3u8');
hls.attachMedia(video);
} else if (video.canPlayType('application/vnd.apple.mpegurl')) {
video.src = 'your_hls_video_url.m3u8';
video.addEventListener('canplay', function() {
video.play();
});
}
示例
下面是一个简单的示例,演示了如何使用 HLS.js 播放 HLS 视频:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>HLS.js Demo</title>
</head>
<body>
<video id="videoPlayer" controls></video>
<script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
<script>
var video = document.getElementById('videoPlayer');
if (Hls.isSupported()) {
var hls = new Hls();
// HLS.js 事件监听
hls.on(Hls.Events.MEDIA_ATTACHED, function() {
console.log('Video and HLS.js are attached');
});
hls.on(Hls.Events.MANIFEST_PARSED, function() {
console.log('Manifest has been successfully parsed');
});
hls.on(Hls.Events.ERROR, function(event, data) {
var errorType = data.type;
var errorDetails = data.details;
console.error('HLS.js error occurred:', errorType, errorDetails);
});
// Video 元素事件监听
video.addEventListener('play', function() {
console.log('Video started playing');
});
video.addEventListener('pause', function() {
console.log('Video paused');
});
video.addEventListener('ended', function() {
console.log('Video ended');
});
video.addEventListener('error', function() {
console.error('Video playback error occurred');
});
// 加载 HLS 视频源
hls.loadSource('your_hls_video_url.m3u8');
hls.attachMedia(video);
} else if (video.canPlayType('application/vnd.apple.mpegurl')) {
video.src = 'your_hls_video_url.m3u8';
video.addEventListener('canplay', function() {
console.log('Video can start playing');
video.play();
});
video.addEventListener('error', function() {
console.error('Video playback error occurred');
});
}
</script>
</body>
</html>
HLS 常用事件
hls.on(Hls.Events.MEDIA_ATTACHED, handler)
:当媒体元素与hls.js实例进行关联时触发。hls.on(Hls.Events.MEDIA_DETACHED, handler)
:当媒体元素与hls.js实例解除关联时触发。hls.on(Hls.Events.MANIFEST_LOADING, handler)
:在加载manifest文件之前触发。hls.on(Hls.Events.MANIFEST_LOADED, handler)
:在成功加载manifest文件后触发。hls.on(Hls.Events.LEVEL_SWITCHING, handler)
:在切换清晰度级别时触发。hls.on(Hls.Events.LEVEL_SWITCHED, handler)
:在成功切换清晰度级别后触发。hls.on(Hls.Events.FRAG_LOADING, handler)
:在加载片段时触发。hls.on(Hls.Events.FRAG_LOADED, handler)
:在成功加载片段后触发。hls.on(Hls.Events.ERROR, handler)
:在发生错误时触发。hls.on(Hls.Events.BUFFER_CREATED, handler)
:在创建缓冲区时触发。hls.on(Hls.Events.BUFFER_APPENDING, handler)
:在将数据附加到缓冲区时触发。hls.on(Hls.Events.BUFFER_EOS, handler)
:在缓冲区到达末尾时触发。
运行时事件【参考】
hls.js触发了一系列事件,可以按照以下方式注册和取消注册:
function onLevelLoaded(event, data) {
var level_duration = data.details.totalduration;
}
// 订阅事件
hls.on(Hls.Events.LEVEL_LOADED, onLevelLoaded);
// 取消订阅事件
hls.off(Hls.Events.LEVEL_LOADED, onLevelLoaded);
// 仅订阅一次事件调用
hls.once(Hls.Events.LEVEL_LOADED, onLevelLoaded);
完整的事件列表如下:
-
Hls.Events.MEDIA_ATTACHING
- 在MediaSource连接到媒体元素之前触发
- 数据:{ media }
- 在MediaSource连接到媒体元素之前触发
-
Hls.Events.MEDIA_ATTACHED
- 在MediaSource成功连接到媒体元素后触发
- 数据:{ media }
- 在MediaSource成功连接到媒体元素后触发
-
Hls.Events.MEDIA_DETACHING
- 在从媒体元素分离MediaSource之前触发
- 数据:{}
- 在从媒体元素分离MediaSource之前触发
-
Hls.Events.MEDIA_DETACHED
- 在从媒体元素分离MediaSource后触发
- 数据:{}
- 在从媒体元素分离MediaSource后触发
-
Hls.Events.BUFFER_RESET
- 当缓冲区将要被重置时触发
- 数据:{}
- 当缓冲区将要被重置时触发
-
Hls.Events.BUFFER_CODECS
- 当为推入缓冲区所需的编解码器有所了解时触发
- 数据:{ audio? :
[Track]
, video? :[Track]
}
- 数据:{ audio? :
- 当为推入缓冲区所需的编解码器有所了解时触发
-
Hls.Events.BUFFER_CREATED
- 当sourcebuffers已经被创建时触发
- 数据:{ tracks : { audio? :
[Track]
, video? :[Track]
, audiovideo?:[Track]
} } 接口 Track { id: 'audio' | 'main', buffer?: SourceBuffer, container: string, codec?: string, initSegment?: Uint8Array, levelCodec?: string, metadata?: any }
- 数据:{ tracks : { audio? :
- 当sourcebuffers已经被创建时触发
-
Hls.Events.BUFFER_APPENDING
- 当将一个段附加到缓冲区时触发
- 数据:{ parent, type, frag, part, chunkMeta, data }
-
Hls.Events.BUFFER_APPENDED
- 当将媒体段附加到缓冲区完成时触发
- 数据:{ parent : 触发
BUFFER_APPENDING
的播放列表类型, type, frag, part, chunkMeta, timeRanges : { video?: TimeRange, audio?: TimeRange, audiovideo?: TimeRange } }
- 数据:{ parent : 触发
- 当将媒体段附加到缓冲区完成时触发
-
Hls.Events.BUFFER_EOS
- 当流结束并且我们想通知媒体缓冲区将不再有数据时触发
- 数据:{ type: SourceBufferName }
- 当流结束并且我们想通知媒体缓冲区将不再有数据时触发
-
Hls.Events.BUFFER_FLUSHING
- 当应该刷新媒体缓冲区时触发
- 数据:{ startOffset, endOffset, type: SourceBufferName }
- 当应该刷新媒体缓冲区时触发
-
Hls.Events.BUFFER_FLUSHED
- 当媒体缓冲区已刷新时触发
- 数据:{ type: SourceBufferName }
- 当媒体缓冲区已刷新时触发
-
Hls.Events.BACK_BUFFER_REACHED
- 当回退缓冲区根据backBufferLength配置选项被触及时触发
- 数据:{ bufferEnd: number }
- 当回退缓冲区根据backBufferLength配置选项被触及时触发
-
Hls.Events.MANIFEST_LOADING
- 表示manifest加载开始时触发
- 数据:{ url : manifestURL }
- 表示manifest加载开始时触发
-
Hls.Events.MANIFEST_LOADED
- 在manifest加载完成后触发
- 数据:{ levels : [可用质量级别], audioTracks : [可用音轨], captions? [可用封闭字幕媒体], subtitles?: [可用字幕轨道], url : manifestURL, stats : [LoaderStats], sessionData: [解析的#EXT-X-SESSION-DATA], networkDetails: [用于调试的加载器特定对象(XMLHttpRequest或fetch Response)]}
- 在manifest加载完成后触发
-
Hls.Events.MANIFEST_PARSED
- 在manifest解析完成后触发
- 数据:{ levels : [可用质量级别], firstLevel : Manifest中首个质量级别的索引, audioTracks, subtitleTracks, stats, audio: boolean, video: boolean, altAudio: boolean }
- 在manifest解析完成后触发
-
Hls.Events.STEERING_MANIFEST_LOADED
- 当内容转向清单加载时触发
- 数据:{
url
: 转向清单URL,steeringManifest
: SteeringManifest object }
- 数据:{
- 当内容转向清单加载时触发
-
Hls.Events.LEVEL_SWITCHING
- 请求级别切换时触发
- 数据:{
level
和级别对象属性 (请参见下文的level获取更多信息) }
- 数据:{
- 请求级别切换时触发
-
Hls.Events.LEVEL_SWITCHED
- 当级别切换生效时触发
- 数据:{ level : 新级别的id }
- 当级别切换生效时触发
-
Hls.Events.LEVEL_LOADING
- 请求级别播放列表时触发(除非通过
hls.loadSource()
仅加载一个媒体播放列表)- 数据:{ url : 级别URL, level : 被加载的级别id, deliveryDirectives: LL-HLS交付指令或当不支持阻塞重新加载时为
null
}
- 数据:{ url : 级别URL, level : 被加载的级别id, deliveryDirectives: LL-HLS交付指令或当不支持阻塞重新加载时为
- 请求级别播放列表时触发(除非通过
-
Hls.Events.LEVEL_LOADED
- 当级别播放列表加载完成时触发
- 数据:{ details : LevelDetails, level : 加载的级别id, stats : [LoadStats] }
- 当级别播放列表加载完成时触发
-
Hls.Events.LEVEL_UPDATED
- 基于先前的细节更新级别细节后,在加载完成后触发
- 数据:{ details : LevelDetails, level : 更新的级别id }
- 基于先前的细节更新级别细节后,在加载完成后触发
-
Hls.Events.LEVEL_PTS_UPDATED
- 在解析片段后更新级别的PTS信息时触发
- 数据:{ details : LevelDetails, level : 更新的级别id, drift: 解析最后片段时观察到的PTS漂移, type, start, end }
- 在解析片段后更新级别的PTS信息时触发
-
Hls.Events.LEVELS_UPDATED
- 在调用
removeLevel()
移除级别后触发- 数据:{ levels : [可用质量级别] }
- 在调用
-
Hls.Events.AUDIO_TRACKS_UPDATED
- 通知音轨列表已更新时触发
- 数据:{ audioTracks : 音轨列表 }
- 通知音轨列表已更新时触发
-
Hls.Events.AUDIO_TRACK_SWITCHING
- 请求音轨切换时触发
- 数据:{ id : 音轨id, type : 播放列表类型 ('AUDIO' | 'main'), url : 音轨URL }
- 请求音轨切换时触发
-
Hls.Events.AUDIO_TRACK_SWITCHED
- 实际发生音轨切换时触发
- 数据:{ id : 音轨id }
- 实际发生音轨切换时触发
-
Hls.Events.AUDIO_TRACK_LOADING
- 音轨加载开始时触发
- 数据:{ url : 音轨URL, id : 音轨id }
- 音轨加载开始时触发
-
Hls.Events.AUDIO_TRACK_LOADED
- 音轨加载完成时触发
- 数据:{ details : LevelDetails, id : 音轨id, stats : [LoadStats] }
- 音轨加载完成时触发
-
Hls.Events.SUBTITLE_TRACKS_UPDATED
- 通知字幕轨道列表已更新时触发
- 数据:{ subtitleTracks : 字幕轨道列表 }
- 通知字幕轨道列表已更新时触发
-
Hls.Events.SUBTITLE_TRACK_SWITCH
- 字幕轨道切换发生时触发
- 数据:{ id : 字幕轨道id, type? : 播放列表类型 ('SUBTITLES' | 'CLOSED-CAPTIONS'), url? : 字幕轨道URL }
- 字幕轨道切换发生时触发
-
Hls.Events.SUBTITLE_TRACK_LOADING
- 字幕轨道加载开始时触发
- 数据:{ url : 字幕轨道URL, id : 字幕轨道id }
- 字幕轨道加载开始时触发
-
Hls.Events.SUBTITLE_TRACK_LOADED
- 字幕轨道加载完成时触发
- 数据:{ details : LevelDetails, id : 字幕轨道id, stats : [LoadStats] }
- 字幕轨道加载完成时触发
-
Hls.Events.SUBTITLE_FRAG_PROCESSED
- 字幕片段处理完成时触发
- 数据:{ success : boolean, frag : [已处理的片段对象], error?: [解析字幕时的错误] }
- 字幕片段处理完成时触发
-
Hls.Events.INIT_PTS_FOUND
- 首个时间戳被找到时触发
- 数据:{ d : demuxer id, initPTS: initPTS, timescale: timescale, frag : 片段对象 }
- 首个时间戳被找到时触发
-
Hls.Events.FRAG_LOADING
- 片段加载开始时触发
- 数据:{ frag : 片段对象, targetBufferTime: number | null [此片段预期缓冲的未缓冲时间] }
- 片段加载开始时触发
-
Hls.Events.FRAG_LOAD_PROGRESS
- [已弃用]
-
Hls.Events.FRAG_LOAD_EMERGENCY_ABORTED
- 用于紧急切换向下中断片段加载时的标识符
- 数据:{ frag : 片段对象 }
- 用于紧急切换向下中断片段加载时的标识符
-
Hls.Events.FRAG_LOADED
- 片段加载完成时触发
- 数据:{ frag : 片段对象, payload : 片段载荷, stats : [LoadStats]}
- 片段加载完成时触发
-
Hls.Events.FRAG_DECRYPTED
- 片段解密完成时触发
- 数据:{ id : demuxer id, frag : 片段对象, payload : 片段载荷, stats : { tstart, tdecrypt}}
- 片段解密完成时触发
-
Hls.Events.FRAG_PARSING_INIT_SEGMENT
- 从片段中提取初始段时触发
- 数据:{ id: demuxer id, frag : 片段对象, moov : moov MP4 box, codecs : 在解析片段时找到的编解码器 }
- 从片段中提取初始段时触发
-
Hls.Events.FRAG_PARSING_USERDATA
- 解析sei文本完成时触发
- 数据:{ id : demuxer id, frag: 片段对象, samples : [ sei样本 pes ], details: LevelDetails }
- 解析sei文本完成时触发
-
Hls.Events.FRAG_PARSING_METADATA
- 解析ID3完成时触发
- 数据:{ id: demuxer id, frag : 片段对象, samples : [ ID3 pes - pts和dts时间戳是相对的,值以秒为单位], details: LevelDetails }
- 解析ID3完成时触发
-
Hls.Events.FRAG_PARSING_DATA
- [已弃用]
-
Hls.Events.FRAG_PARSED
- 片段解析完成时触发
- 数据:{ frag : 片段对象, partIndex }
- 片段解析完成时触发
-
Hls.Events.FRAG_BUFFERED
- 当重新复用的MP4盒子全部附加到SourceBuffer时触发
- 数据:{ id: demuxer id, frag : 片段对象, stats : [LoadStats] }
- 当重新复用的MP4盒子全部附加到SourceBuffer时触发
-
Hls.Events.FRAG_CHANGED
- 当与当前视频位置匹配的片段发生更改时触发
- 数据:{ id : demuxer id, frag : 片段对象 }
- 当与当前视频位置匹配的片段发生更改时触发
-
Hls.Events.FPS_DROP
- 当最后监控周期中的FPS下降高于指定阈值时触发
- 数据:{ curentDropped : 最后监控周期中丢帧数, currentDecoded : 最后监控周期中解码帧数, totalDroppedFrames : 视频元素中总丢帧数 }
- 当最后监控周期中的FPS下降高于指定阈值时触发
-
Hls.Events.FPS_DROP_LEVEL_CAPPING
- 当FPS下降触发自动级别限制时触发
- 数据:{ level: 建议的新自动级别限制由fps控制器, droppedLevel : 有太多丢帧的级别将被限制 }
- 当FPS下降触发自动级别限制时触发
-
Hls.Events.ERROR
- 错误事件标识符
- 数据:{ type : 错误类型, details : 错误详情, fatal : 错误是否致命, 其他错误特定数据 }
- 错误事件标识符
-
Hls.Events.DESTROYING
- 当hls.js实例开始销毁时触发。不同于
MEDIA_DETACHED
,因为可能希望将视频从hls.js实例分离并重新连接,例如处理中间广告- 数据:{}
- 当hls.js实例开始销毁时触发。不同于
-
Hls.Events.KEY_LOADING
- 解密密钥加载开始时触发
- 数据:{ frag : 片段对象 }
- 解密密钥加载开始时触发
-
Hls.Events.KEY_LOADED
- 解密密钥加载完成时触发
- 数据:{ frag : 片段对象 }
- 解密密钥加载完成时触发
-
Hls.Events.STREAM_STATE_TRANSITION
- [已弃用]
-
Hls.Events.NON_NATIVE_TEXT_TRACKS_FOUND
- 当
renderTextTracksNatively
为false
时,当发现新的标题或字幕轨道时触发,替代将TextTrack添加到视频元素的行为- 数据:{ tracks: Array<{ label, kind, default, subtitleTrack }> }
- 当
-
Hls.Events.CUES_PARSED
- 当
renderTextTracksNatively
为false
时,当解析新的标题或字幕提示时触发- 数据:{ type, cues, track }
- 当
评论区