HEVC
HEVC,也就是H.265,是H.264的下一代编码,和AV1属于统一代的编解码器,H.265大概比H.264能节约一半的带宽,或者同等带宽下能提升 一倍的清晰度和画质。
当然,H.265的问题在于支持的客户端还不够广泛,几乎所有的设备都支持H.264,包括很差性能的手机或者盒子,对于H.264的支持都是有专门 的芯片,然而H.265虽然经过了差不多十年的发展,支持的设备还不够多。 在特定场景下,比如设备端明确支持H.265时,可以选择H.265, 否则还是选择H.264。
此外,传输协议对于H.265的支持也在逐步完善,但是还并非所有的协议都支持。MEPG-TS是最早支持H.265的,当然SRT和HLS是基于TS的协议, 所以也支持了;RTMP和HTTP-FLV,直到2023.03,终于Enhanced RTMP项目建立, 开始支持了HEVC和AV1;而WebRTC目前只有Safari支持了,据说Chrome还在开发中。
SRS 6.0正式支持了H.265的能力,若需要使用H.265功能,请切换到SRS 6.0版本。研发的详细过程请参考#465。
Overview
SRS 支持 H.265(或 HEVC)的架构:
FFmpeg --RTMP(h.265)---> SRS ----RTMP/FLV/TS/HLS/WebRTC(h.265)--> Chrome/Safari
对于直播流:
- Chrome 105+ 默认支持 HEVC,参见这篇文章。
- 你可以通过 H5 视频直接播放 mp4,或者通过 MSE 播放 HTTP-FLV/HTTP-TS/HLS 等。
- 请使用 mpegts.js 播放带有 HEVC 的 HTTP-TS。
- mpegts.js 计划支持带有 HEVC 的 HTTP-FLV,参见 mpegts.js#64
- OBS 29+ 支持 HEVC RTMP。
- FFmpeg 或 ffplay 支持 libx265
- SRS 也支持 HEVC。
- SRS 6.0已经支持了HEVC。
- 原始的 HEVC 支持是由 runner365 在 srs-gb28181/feature/h265 中提供的。
Note:要检查您的 Chrome 是否支持 HEVC,请打开
chrome://gpu
并搜索hevc
。
对于 WebRTC:
- Chrome 目前(2022.11)不支持 HEVC,但支持 AV1,请参见 #2324
- Safari 支持 HEVC,如果用户启用它,请参见本节
- SRS 也只支持 AV1,因为 Chrome 尚未支持 HEVC。
Usage
请确保您的SRS版本为6.0.4+
,并使用h265构建:
docker run --rm -it -p 1935:1935 -p 8080:8080 registry.cn-hangzhou.aliyuncs.com/ossrs/srs:6 \
./objs/srs -c conf/hevc.flv.conf
Note:除了环境变量,您还可以使用
conf/hevc.flv.conf
或conf/hevc.ts.conf
配置文件。 Note:建议使用conf/hevc.ts.conf
,因为TS对于HEVC更好。
构建并修补FFmpeg,请参见FFmpeg工具:
# 对于macOS
docker run --rm -it registry.cn-hangzhou.aliyuncs.com/ossrs/srs:encoder \
ffmpeg -stream_loop -1 -re -i doc/source.flv \
-acodec copy -vcodec libx265 -f flv rtmp://host.docker.internal/live/livestream
# 对于linux
docker run --net=host --rm -it registry.cn-hangzhou.aliyuncs.com/ossrs/srs:encoder \
ffmpeg -stream_loop -1 -re -i doc/source.flv \
-acodec copy -vcodec libx265 -f flv rtmp://127.0.0.1/live/livestream
Note:请将IP
host.docker.internal
更改为您的SRS的IP。
通过以下方式播放HEVC直播流:
- HTTP-FLV(通过H5):http://localhost:8080/live/livestream.flv
- HLS(通过VLC或fflay):
http://localhost:8080/live/livestream.m3u8
Note:请通过
SRS_VHOST_DASH_ENABLED=on
启用MPEG-DASH,然后使用VLC/ffplay播放流http://localhost:8080/live/livestream.mpd
Note:请通过
SRS_VHOST_HTTP_REMUX_MOUNT=[vhost]/[app]/[stream].ts
启用HTTP-TS,然后使用H5/VLC/ffplay播放流http://localhost:8080/live/livestream.ts
Note:如果要将直播流转换为MP4文件,请通过
SRS_VHOST_DVR_ENABLED=on SRS_VHOST_DVR_DVR_PATH=./objs/nginx/html/[app]/[stream].[timestamp].mp4
启用DVR MP4。
Note:关于HEVC可用协议和工具的详细信息,请参见SRS中的HEVC状态。
Note:H5播放器使用mpegts.js。
Status of HEVC in SRS
The status of protocols and HEVC:
- PUSH HEVC over RTMP by FFmpeg. v6.0.2
- PUSH HEVC over SRT by FFmpeg. v6.0.20
- PUSH HEVC over RTMP by OBS. #3464 https://github.com/obsproject/obs-studio/pull/8522
- PUSH HEVC over SRT by OBS. v6.0.20
- PUSH HEVC over GB28181. v6.0.25
- PULL HEVC over RTMP by FFmpeg, with patch for FFmpeg. v6.0.2
- PULL HEVC over HTTP-FLV by FFmpeg, with patch for FFmpeg. v6.0.2
- PULL HEVC over HTTP-TS by FFmpeg v6.0.4
- PULL HEVC over HLS by FFmpeg v6.0.11
- PULL HEVC over MPEG-DASH by FFmpeg v6.0.14
- PULL HEVC over SRT by FFmpeg. v6.0.20
- PUSH HEVC over WebRTC by Safari. v6.0.34
- PULL HEVC over WebRTC by Safari. v6.0.34
- PUSH HEVC over WebRTC by Chrome/Firefox
- PULL HEVC over WebRTC by Chrome/Firefox
- Play HEVC over HTTP-TS by mpegts.js, by Chrome 105+ MSE, NO WASM. v6.0.1
- Play pure video(no audio) HEVC over HTTP-TS by mpegts.js. v6.0.9
- Play HEVC over HTTP-FLV by mpegts.js, by Chrome 105+ MSE, NO WASM. v6.0.1
- Play HEVC over HLS by hls.js
- Play HEVC over MPEG-DASH by dash.js
- Play HEVC over HTTP-TS by ffplay, by offical release. v6.0.4
- PULL HEVC over RTMP by ffplay, with patch for FFmpeg. v6.0.2
- Play HEVC over HTTP-FLV by ffplay, with patch for FFmpeg. v6.0.2
- Play pure video(no audio) HEVC by ffplay.
- Play HEVC over HLS by ffplay. v6.0.11
- Play HEVC over MPEG-DASH by ffplay. v6.0.14
- Play HEVC over SRT by ffplay. v6.0.20
- Play HEVC over HTTP-TS by VLC, by official release. v6.0.4
- Play HEVC over SRT by VLC, by official. v6.0.20
- Play pure video(no audio) HEVC by VLC.
- Play HEVC over RTMP by VLC.
- Play HEVC over HTTP-FLV by VLC.
- Play HEVC over HLS by VLC. v6.0.11
- Play HEVC over MPEG-DASH by VLC. v6.0.14
- DVR HEVC to MP4/FLV file. v6.0.14
- HTTP API contains HEVC metadata.
- HTTP Callback takes HEVC metadata.
- Prometheus Exporter supports HEVC metadata.
- Improve coverage for HEVC.
- Add regression/blackbox tests for HEVC.
- Supports benchmark for HEVC by srs-bench.
- Support patched FFmpeg for SRS dockers: CentOS7, Ubuntu20 and Encoder.
- Update WordPress plugin SrsPlayer for HEVC.
- Update srs-cloud for HEVC.
- Edge server supports publish HEVC stream to origin.
- Edge server supprots play HEVC stream from origin.
- HEVC: Error empty SPS/PPS when coverting RTMP to HEVC.
Note: We're merging HEVC support to SRS 6.0, the original supports for HEVC is srs-gb28181/feature/h265 by runner365
FFmpeg Tools
镜像 ossrs/srs:encoder
或 ossrs/srs:6
中的 FFmpeg 是使用 libx265 构建的,并且支持 RTMP 上的 HEVC。因此,您可以直接使用:
docker run --rm -it --net host \
registry.cn-hangzhou.aliyuncs.com/ossrs/srs:encoder \
ffmpeg -re -i doc/source.flv -acodec copy -vcodec libx265 \
-f flv rtmp://localhost/live/livestream
如果您想从代码构建,请阅读以下说明。在构建 FFmpeg 之前,我们必须先构建 libx264:
git clone https://code.videolan.org/videolan/x264.git ~/git/x264
cd ~/git/x264
./configure --prefix=$(pwd)/build --disable-asm --disable-cli --disable-shared --enable-static
make -j10
make install
然后是编译 libx265:
git clone https://bitbucket.org/multicoreware/x265_git.git ~/git/x265_git
cd ~/git/x265_git/build/linux
cmake -DCMAKE_INSTALL_PREFIX=$(pwd)/build -DENABLE_SHARED=OFF ../../source
make -j10
make install
请注意,FFmpeg 6.0 在以下提交之前不支持 RTMP 上的 HEVC 637c761b:
commit 637c761be1bf9c3e1f0f347c5c3a390d7c32b282
Author: Steven Liu <liuqi05@kuaishou.com>
Date: Mon Aug 28 09:59:24 2023 +0800
avformat/rtmpproto: support enhanced rtmp
add option named rtmp_enhanced_codec,
it would support hvc1,av01,vp09 now,
the fourcc is using Array of strings.
Signed-off-by: Steven Liu <lq@chinaffmpeg.org>
因此,如果您使用的是 FFmpeg 6,您可以通过以下命令直接构建 FFmpeg,无需任何补丁:
git clone -b master https://github.com/FFmpeg/FFmpeg.git ~/git/FFmpeg
cd ~/git/FFmpeg
env PKG_CONFIG_PATH=~/git/x264/build/lib/pkgconfig:~/git/x265_git/build/linux/build/lib/pkgconfig \
./configure \
--prefix=$(pwd)/build \
--enable-gpl --enable-nonfree --enable-pthreads --extra-libs=-lpthread \
--disable-asm --disable-x86asm --disable-inline-asm \
--enable-decoder=aac --enable-decoder=aac_fixed --enable-decoder=aac_latm --enable-encoder=aac \
--enable-libx264 --enable-libx265 \
--pkg-config-flags='--static'
make -j10
推送HEVC over RTMP 到 SRS:
./ffmpeg -stream_loop -1 -re -i ~/srs/doc/source.flv -acodec copy -vcodec libx265 \
-f flv rtmp://localhost/live/livestream
通过 ffplay 播放 HEVC over RTMP:
./ffplay rtmp://localhost/live/livestream
它就像魔术一样奏效!
如果您想在 FFmpeg 4.1 或 5.1 中使用 HEVC over RTM,请阅读以下说明。请下载 FFmepg 并切换到 5.1:
Note: The specfication and usage to support HEVC over RTMP or FLV. There is a patch for FFmpeg 4.1/5.1/6.0 from runner365 for FFmpeg to support HEVC over RTMP or FLV. There is also a patch from Intel for this feature.
git clone -b n5.1.2 https://github.com/FFmpeg/FFmpeg.git ~/git/FFmpeg
Then, patch for HEVC over RTMP/FLV:
git clone -b 5.1 https://github.com/runner365/ffmpeg_rtmp_h265.git ~/git/ffmpeg_rtmp_h265
cp ~/git/ffmpeg_rtmp_h265/flv.h ~/git/FFmpeg/libavformat/
cp ~/git/ffmpeg_rtmp_h265/flv*.c ~/git/FFmpeg/libavformat/
最后,请参考之前的操作方法编译FFmpeg即可。
MSE for HEVC
MSE is a base technology for mpegts.js, hls.js and dash.js.
Now Chrome 105+ supports HEVC by default, see this post, which means, MSE(Chrome 105+) is available for HEVC.
You can verify this feature, by generating a HEVC mp4 file:
ffmpeg -i ~/git/srs/trunk/doc/source.flv -acodec copy \
-vcodec libx265 -y source.hevc.mp4
Note: Please make sure your FFmpeg is 5.0 and libx265 is enabled.
Open source.hevc.mp4
in Chrome 105+ directly, it should works.
You can also move the file to SRS webserver:
mkdir -p ~/git/srs/trunk/objs/nginx/html/vod/
mv source.hevc.mp4 ~/git/srs/trunk/objs/nginx/html/vod
Then open by srs-player
Safari WebRTC
Safari supports WebRTC, if you enable it by:
- English version:
Develop > Experimental Features > WebRTC H265 codec
- Chinese version:
Development > Experimental Features > WebRTC H265 codec
Then open the url in safari, to publish or play WebRTC stream:
- Play http://localhost:1985/rtc/v1/whep/?app=live&stream=livestream&codec=hevc
- Publish http://localhost:1985/rtc/v1/whip/?app=live&stream=livestream&codec=hevc
Please follow other section to publish HEVC stream.
Thanks for Contributors
There is a list of commits and contributors about HEVC in SRS:
- H265: For #1747, Support HEVC/H.265 in SRT/RTMP/HLS.
- H265: For #1747, Fix build fail bug for H.265
- H265: For #1747, GB28181 support h.265 (#2037)
- H265: fix some important bugs (#2156)
- H265: Deliver the right hevc nalu and dump the wrong nalu. (#2447)
- H265: Fix multi nal hevc frame demux fail. #2494
- H265: Fix build error #2657 #2664
- H265: Update mpegts demux in srt. #2678
- H265: Fix the stat issue for h265. (#1949)
- H265: Add h265 codec written support for MP4 format. (#2697)
- H265: Add h265 for SRT.
We will merge some of these commits to SRS 6.0, but not all commits.
- PULL HEVC over WebRTC by Safari. v6.0.34
- GB: Support H.265 for GB28181. v6.0.25 (#3408)
- H265: Support HEVC over SRT. v6.0.20 (#465) (#3366)
- H265: Support DVR HEVC stream to MP4. v6.0.14
- HLS: Support HEVC over HLS. v6.0.11
- HEVC: The codec information is incorrect. v6.0.5
- FFmpeg support libx265 and HEVC over RTMP/FLV: CentOS7, Ubuntu20 and Encoder.
- H265: Support HEVC over HTTP-TS. v6.0.4
- H265: Support parse multiple NALUs in a frame. v6.0.3
- H265: Support HEVC over RTMP or HTTP-FLV. v6.0.2
- H265: Update mpegts.js to play HEVC over HTTP-TS/FLV. v6.0.1
Known Issues
- HEVC over Safari WebRTC, only support WebRTC to WebRTC, doesn't support converting to RTMP.
- Chrome/Firefox does not support HEVC, no any plan as I know.
- Almost all browsers supports MSE, except iOS. HEVC over MSE requires hardware decoder.
- Apart from mpegts.js, other H5 players such as hls.js/dash.js doesn't support HEVC.