了解HLS实时流看这篇就够了
什么是 HTTP 实时流(HLS)?
HTTP 实时流(HLS)是使用最广泛的视频流协议之一。尽管它称为 HTTP“实时”流,但它同时适用于点播流和实时流。HLS 将视频文件分解为较小的可下载 HTTP 文件,并使用 HTTP 协议来交付。客户端设备加载这些 HTTP 文件,然后将它们作为视频进行播放。
HLS 的一个优点是,所有连入互联网的设备都支持 HTTP,因而它比需要使用专用服务器的流协议更易于实施。另一个优点是 HLS 流可以根据网络状况提高或降低视频质量,而不会中断播放。这就是在用户观看视频的过程中视频质量可能会变好或变差的原因。这个功能称为“自适应比特率视频传输”或“自适应比特率流式传输”,如果没有它,慢速网络条件可能导致视频播放完全停止。
HLS 由 Apple 为 Apple 产品开发,但现在已广泛用于许多设备。
HLS常用于各大电影电视剧等视频网站。
为什么播放视频使用HLS(.m3u8)而不是mp4文件?
关于.m3u8文件
m3u8
文件是一种用于表示媒体播放列表的文件格式,通常用来描述 HLS(HTTP Live Streaming)流媒体,用于在线视频流和音乐播放列表。它通常包含一系列媒体文件的路径或 URL,所以我们在一个视频网站播放的时候打开Chrome的开发者工具,会看到它不断地在加载.ts
文件片段:
同样mp4也可以在页面做视频播放,为什么HLS更胜一筹?
其根本原因主要在于 HLS 的特性更适合 流媒体传输,尤其是实时直播、视频点播等应用场景。以下是一些关键原因:
1. 支持分片传输
HLS 将视频分割成许多小片段(通常是 2-10 秒的 .ts 文件),通过 M3U8 文件中的 URL 进行有序传输,而 MP4 是一个完整的视频文件。这带来了几个优势:
- 更好的网络适应性:HLS 的分片机制使得它可以根据网络状况灵活调整传输质量。例如,当网络质量不好时,客户端可以自动请求低分辨率的片段,而无需重新加载整个视频。
- 分段加载:用户只需要加载当前播放片段,而不必像 MP4 那样一次性下载整个文件,适合长视频或直播场景。
2. 实时直播支持
HLS 是专为 实时直播 设计的,允许不断添加新的视频片段,使客户端可以边下载边播放最新的视频内容。这在以下场景中尤为关键:
- 低延迟直播:HLS 支持实时直播,并可以通过减少片段长度和减少缓冲时间来降低延迟。
- 动态更新:M3U8 文件可以动态更新,添加新的流片段,适用于直播和长时间的活动,比如体育赛事、新闻直播等。
MP4 则更适合用于 预录制的视频播放,不太适合用于实时场景。
3. 多码率自适应 (ABR)
HLS 支持多种码率和分辨率的切换,也叫做 自适应比特率流 (Adaptive Bitrate Streaming, ABR)。这意味着,HLS 可以根据用户的网络带宽自动选择合适的码率和分辨率:
- 用户体验更好:用户在网络状况良好的时候可以看到高清内容,而在网络波动或减速时,HLS 会自动切换到较低的分辨率,以保证播放流畅,而不会发生长时间的缓冲。
- 避免卡顿:对于移动设备和不稳定的网络环境(如 4G 切换 Wi-Fi 等),ABR 能够确保用户体验较少的中断。
MP4 不支持动态码率切换,播放时网络波动可能导致缓冲或停止。
4. 渐进式下载与即时播放
HLS 支持边下载边播放,特别是在大型视频文件或者直播场景中,用户无需等待完整的视频下载完成就可以开始播放。而 MP4 视频通常是一个整体文件,虽然也可以边下载边播放,但加载速度和播放体验不如 HLS 流畅,特别是视频较大的情况下。
5. 内容保护与加密支持
HLS 支持 AES-128 加密,可以对流媒体进行端到端的加密,保护视频内容,防止未授权的访问。对于流媒体平台,版权保护至关重要。
- DRM 集成:HLS 可以与各种数字版权管理(DRM)技术结合,进一步保护流媒体内容的安全性。
MP4 虽然也支持 DRM 和加密,但没有 HLS 的端到端加密和分片传输的优势明显。
6. 跨设备支持
HLS 由苹果公司开发,最初用于 iOS 设备。随着时间推移,HLS 已经成为一种广泛支持的标准,兼容大多数设备和浏览器:
- 原生支持:HLS 在 iOS 和 macOS 上有原生支持,不需要额外插件。而且,现代的 Android、Windows、智能电视、机顶盒、浏览器等大部分设备也支持 HLS。
- 浏览器支持:在网页上通过 HTML5 播放 HLS 流也十分便捷,而 MP4 文件更多是直接下载到本地后播放,或者通过播放器加载,灵活性较差。
总而言之
- HLS 更适合流媒体和直播,因为它支持分片传输、多码率自适应、低延迟播放,以及良好的网络适应性。
- MP4 更适合下载和离线播放,它是一个单一文件格式,适合短视频、预录制内容或需要离线保存的场景。
HLS 的动态更新、实时流、ABR 等特性使其成为流媒体平台、直播服务的首选,而 MP4 则适合文件传输或本地存储。
在前端是如何工作的?
当前H5视频播放器并不支持HLS视频格式的播放,要获得该格式的支持需要在前端引入HLS.js或者videojs等第三方播放器插件。
示例:
在video
标签source
参数src
中引入.m3u8
后缀的文件,而type
中需要指定"application/x-mpegUR
L"
<video id="my-video" > <!--<source src="demo.mp4" type="video/mp4" />--> <source src="https://www.towait.com/20240619/SBicdVRe/index.m3u8" type="application/x-mpegURL"> </video>
使用FFmpeg将mp4转换成m3u8文件
准备FFmpeg
下载FFmpeg,并将其加入系统变量,这里不做过多阐述。
格式化命令
$ ffmpeg -i demo1.mp4 -codec: copy -start_number 0 -hls_time 10 -hls_list_size 0 -f hls demo1.m3u8
输出结果
ffmpeg -i demo1.mp4 -codec: copy -start_number 0 -hls_time 10 -hls_list_size 0 -f hls demo1.m3u8 ffmpeg version 2024-09-22-git-a577d313b2-essentials_build-www.gyan.dev Copyright (c) 2000-2024 the FFmpeg developers built with gcc 13.2.0 (Rev5, Built by MSYS2 project) configuration: --enable-gpl --enable-version3 --enable-static --disable-w32threads --disable-autodetect --enable-fontconfig --enable-iconv --enable-gnutls --enable-libxml2 --enable-gmp --enable-bzlib --enable-lzma --enable-zlib --enable-libsrt --enable-libssh --enable-libzmq --enable-avisynth --enable-sdl2 --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxvid --enable-libaom --enable-libopenjpeg --enable-libvpx --enable-mediafoundation --enable-libass --enable-libfreetype --enable-libfribidi --enable-libharfbuzz --enable-libvidstab --enable-libvmaf --enable-libzimg --enable-amf --enable-cuda-llvm --enable-cuvid --enable-dxva2 --enable-d3d11va --enable-d3d12va --enable-ffnvcodec --enable-libvpl --enable-nvdec --enable-nvenc --enable-vaapi --enable-libgme --enable-libopenmpt --enable-libopencore-amrwb --enable-libmp3lame --enable-libtheora --enable-libvo-amrwbenc --enable-libgsm --enable-libopencore-amrnb --enable-libopus --enable-libspeex --enable-libvorbis --enable-librubberband libavutil 59. 37.100 / 59. 37.100 libavcodec 61. 17.100 / 61. 17.100 libavformat 61. 6.100 / 61. 6.100 libavdevice 61. 2.101 / 61. 2.101 libavfilter 10. 3.100 / 10. 3.100 libswscale 8. 2.100 / 8. 2.100 libswresample 5. 2.100 / 5. 2.100 libpostproc 58. 2.100 / 58. 2.100 Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'demo1.mp4': Metadata: major_brand : mp42 minor_version : 0 compatible_brands: mp42mp41isomavc1 creation_time : 2021-02-01T09:58:39.000000Z Duration: 00:00:27.64, start: 0.000000, bitrate: 4593 kb/s Stream #0:0[0x1](und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709, progressive), 1920x1080, 4590 kb/s, 25 fps, 25 tbr, 25 tbn (default) Metadata: creation_time : 2021-02-01T09:58:39.000000Z handler_name : L-SMASH Video Handler vendor_id : [0][0][0][0] encoder : AVC Coding Stream mapping: Stream #0:0 -> #0:0 (copy) Output #0, hls, to 'demo1.m3u8': Metadata: major_brand : mp42 minor_version : 0 compatible_brands: mp42mp41isomavc1 encoder : Lavf61.6.100 Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709, progressive), 1920x1080, q=2-31, 4590 kb/s, 25 fps, 25 tbr, 90k tbn (default) Metadata: creation_time : 2021-02-01T09:58:39.000000Z handler_name : L-SMASH Video Handler vendor_id : [0][0][0][0] encoder : AVC Coding Press [q] to stop, [?] for help [hls @ 0000016c76f2b5c0] Opening 'demo10.ts' for writing [hls @ 0000016c76f2b5c0] Opening 'demo1.m3u8.tmp' for writing [hls @ 0000016c76f2b5c0] Opening 'demo11.ts' for writing [hls @ 0000016c76f2b5c0] Opening 'demo1.m3u8.tmp' for writing [hls @ 0000016c76f2b5c0] Opening 'demo12.ts' for writing [hls @ 0000016c76f2b5c0] Opening 'demo1.m3u8.tmp' for writing [out#0/hls @ 0000016c76f1ff40] video:15490KiB audio:0KiB subtitle:0KiB other streams:0KiB global headers:0KiB muxing overhead: unknown frame= 691 fps=0.0 q=-1.0 Lsize=N/A time=00:00:27.56 bitrate=N/A speed= 631x
这时候我们的文件夹内会有文件,这是一个15Mb的视频文件,它被分割为3个.ts文件
如何批量转换?
我在github上找到一个脚本,但是目前我没有做测试
@echo off echo The filename: %~n1 echo The extention: %~x1 REM Make new directories in the same folder. md media\%~n1\hls REM Get the cover jpg and preview gif from video ffmpeg -i %~n1%~x1 -ss 20.00 -vframes 1 ./media/%~n1/hls/cover_h1.jpg ffmpeg -i %~n1%~x1 -ss 20.00 -vframes 1 -s 760x428 ./media/%~n1/hls/cover_l1.jpg ffmpeg -ss 00:00:10 -t 3 -i %~n1%~x1 -s 640x360 -r 2 ./media/%~n1/hls/preview.gif REM Start to work on videos ffmpeg -i %~n1%~x1 -profile:v baseline -level 3.0 -s 640x360 -start_number 0 -hls_time 10 -hls_list_size 0 -threads 5 -preset ultrafast -f hls ./media/%~n1/hls/360_out.m3u8 ffmpeg -i %~n1%~x1 -profile:v baseline -level 3.0 -s 800x480 -start_number 0 -hls_time 10 -hls_list_size 0 -threads 5 -preset ultrafast -f hls ./media/%~n1/hls/480_out.m3u8 ffmpeg -i %~n1%~x1 -profile:v baseline -level 3.0 -s 1280x720 -start_number 0 -hls_time 10 -hls_list_size 0 -threads 5 -preset ultrafast -f hls ./media/%~n1/hls/720_out.m3u8 ffmpeg -i %~n1%~x1 -profile:v baseline -level 3.0 -s 1920x1080 -start_number 0 -hls_time 10 -hls_list_size 0 -threads 5 -preset ultrafast -f hls ./media/%~n1/hls/1080_out.m3u8 REM Check if any error if %ERRORLEVEL% == 0 goto :next echo "Errors encountered during execution. Exited with status: %errorlevel%" goto :endofscript :next echo "Generating overall m3u8 play list...." REM Generate an overall play list. ( echo #EXTM3U echo #EXT-X-STREAM-INF:BANDWIDTH=375000,RESOLUTION=640x360 echo 360_out.m3u8 echo #EXT-X-STREAM-INF:BANDWIDTH=750000,RESOLUTION=854x480 echo 480_out.m3u8 echo #EXT-X-STREAM-INF:BANDWIDTH=2000000,RESOLUTION=1280x720 echo 720_out.m3u8 echo #EXT-X-STREAM-INF:BANDWIDTH=3500000,RESOLUTION=1920x1080 echo 1080_out.m3u8 ) > ./media/%~n1/hls/%~n1.m3u8 echo "Overall m3u8 play list generated." goto :endofscript :endofscript echo "Work complete." REM Brought to you by Duke Yin www.dukeyin.com pause
FFmpeg一些常用的web视频格式转换
为什么需要用这么多格式?
在 HTML5 中,使用 <video>
标签播放视频时,通常会同时提供多种格式(如 MP4、WebM 和 Ogg),这是为了确保视频可以在不同的浏览器中正常播放。原因如下:
1. 浏览器的兼容性问题
不同浏览器对视频格式的支持并不相同,尤其是早期的 HTML5 实现中,各个浏览器支持的格式差异很大。为了确保视频可以在更多的浏览器中播放,通常会提供多种格式。
常见的视频格式及其支持情况:
- MP4(H.264 编码 + AAC 音频)
- 支持度较广:几乎所有现代浏览器(包括 Chrome、Firefox、Safari、Edge、Internet Explorer)都支持 MP4。
- 优点:高压缩率、质量好、广泛支持。
- 缺点:涉及专利和版权问题,需要支付专利费用。
- WebM(VP8/VP9 编码 + Vorbis 音频)
- 支持:主要在 Chrome、Firefox、Opera 上支持。
- 优点:开源且免专利费用。
- 缺点:不被 Safari 和 Internet Explorer 支持。
- Ogg(Theora 编码 + Vorbis 音频)
- 支持:Firefox、Chrome、Opera。
- 优点:开源,免专利费用。
- 缺点:质量和压缩率不如 MP4 和 WebM,且 Safari 和 Internet Explorer 不支持。
2. 提升用户体验
通过提供多种格式,可以确保视频能在大多数用户的设备和浏览器上正常播放,避免用户因为视频格式不兼容而无法观看视频。
3. HTML5 标签的工作原理
当浏览器遇到多个 <source>
标签时,它会按顺序尝试加载这些视频源,直到找到一个自己支持的格式。这样可以自动选择最适合该浏览器的视频格式。
<video controls> <source src="video.mp4" type="video/mp4"> <source src="video.webm" type="video/webm"> <source src="video.ogv" type="video/ogg"> Your browser does not support the video tag. </video>
在这个例子中:
- 浏览器会首先尝试加载
video.mp4
文件,如果浏览器支持 MP4 格式,就会播放 MP4 视频。 - 如果浏览器不支持 MP4 格式,则会继续尝试加载
video.webm
。 - 如果 WebM 格式也不支持,浏览器会最后尝试 Ogg 格式。
mp4转webm
ffmpeg -i demo1.mp4 -c:v libvpx-vp9 -crf 30 -b:v 0 -b:a 128k -c:a libopus demo1.webm
mp4转ogv
ffmpeg -i demo1.mp4 -c:v libtheora -q:v 7 -c:a libvorbis -q:a 4 demo1.ogv
需要注意的是ogv
的引用,type
填写video/ogg
<video controls> <source src="video.ogv" type="video/ogg"> </video>
OK,结束