首页  > 时光论坛

了解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-mpegURL"

id="my-video"

>

src="https://www.towait.com/20240619/SBicdVRe/index.m3u8"

type="application/x-mpegURL">

使用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

pauseFFmpeg一些常用的web视频格式转换为什么需要用这么多格式?

在 HTML5 中,使用

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 标签的工作原理当浏览器遇到多个 标签时,它会按顺序尝试加载这些视频源,直到找到一个自己支持的格式。这样可以自动选择最适合该浏览器的视频格式。

Your browser does not support the video tag.

在这个例子中:

浏览器会首先尝试加载 video.mp4 文件,如果浏览器支持 MP4 格式,就会播放 MP4 视频。如果浏览器不支持 MP4 格式,则会继续尝试加载 video.webm。如果 WebM 格式也不支持,浏览器会最后尝试 Ogg 格式。mp4转webmffmpeg -i demo1.mp4 -c:v libvpx-vp9 -crf 30 -b:v 0 -b:a 128k -c:a libopus demo1.webmmp4转ogvffmpeg -i demo1.mp4 -c:v libtheora -q:v 7 -c:a libvorbis -q:a 4 demo1.ogv需要注意的是ogv的引用,type填写video/ogg

OK,结束