HEVC
HEVC, also known as H.265, is the next-generation encoding after H.264 and belongs to the same generation of codecs as AV1. H.265 can save about half the bandwidth compared to H.264, or provide double the clarity and image quality at the same bandwidth.
However, the problem with H.265 is that it's not yet widely supported by clients. Almost all devices support H.264, including low-performance phones or boxes, which have dedicated chips for H.264 support. Although H.265 has been developed for almost ten years, there are still not enough devices that support it. In specific scenarios, like when the device clearly supports H.265, you can choose H.265; otherwise, stick with H.264.
Additionally, the support for H.265 in transport protocols is gradually improving, but not all protocols support it yet. MPEG-TS was the first to support H.265, and since SRT and HLS are based on TS, they also support it. RTMP and HTTP-FLV only started supporting HEVC and AV1 in March 2023 with the Enhanced RTMP project. As for WebRTC, only Safari supports it currently, and Chrome is said to be in development.
SRS 6.0 officially supports the H.265 feature. If you want to use the H.265 function, please switch to the SRS 6.0 version. Please refer to #465 for the detailed research and development process.
Overview
The architecutre for SRS to support H.265(or HEVC):
FFmpeg --RTMP(h.265)---> SRS ----RTMP/FLV/TS/HLS/WebRTC(h.265)--> Chrome/Safari
For live streaming:
- Chrome 105+ supports HEVC by default, see this post.
- You're able to play mp4 directly by H5 video, or by MSE if HTTP-FLV/HTTP-TS/HLS etc.
- Please use mpegts.js to play HTTP-TS with HEVC.
- There is a plan for mpegts.js to support HTTP-FLV with HEVC, see mpegts.js#64
- OBS 29+ supports HEVC over RTMP.
- FFmpeg or ffplay supports libx265
- FFmpeg 6 supports HEVC over RTMP, see 637c761b for detail.
- FFmpeg 4 or 5, need some patch for HEVC over RTMP/FLV, see FFmpeg Tools bellow.
- SRS also supports HEVC.
- We have merged HEVC support into SRS 6.0
- The original supports for HEVC is srs-gb28181/feature/h265 by runner365
Note: To check if your Chrome support HEVC, please open
chrome://gpu
and searchhevc
.
For WebRTC:
- Chrome does not support HEVC right now(2022.11), but supports AV1, please see #2324
- Safari supports HEVC if user enable it, please see this section
- SRS also only supports AV1, because Chrome does not support HEVC yet.
Usage
Please make sure your SRS is 6.0.4+
, build with h265:
docker run --rm -it -p 1935:1935 -p 8080:8080 ossrs/srs:6 \
./objs/srs -c conf/hevc.flv.conf
Note: Besides environment variables, you can also use
conf/hevc.flv.conf
orconf/hevc.ts.conf
config files. Note: Recommendconf/hevc.ts.conf
because TS is better for HEVC.
Build and patch FFmpeg, see FFmpeg Tools:
# For macOS
docker run --rm -it ossrs/srs:encoder ffmpeg -stream_loop -1 -re -i doc/source.flv \
-acodec copy -vcodec libx265 -f flv rtmp://host.docker.internal/live/livestream
# For linux
docker run --net=host --rm -it 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: Please change the ip
host.docker.internal
to your SRS's IP.
Play the HEVC live streams by:
- HTTP-FLV(by H5): http://localhost:8080/live/livestream.flv
- HLS(by VLC or fflay):
http://localhost:8080/live/livestream.m3u8
Note: Please enable MPEG-DASH by
SRS_VHOST_DASH_ENABLED=on
then use VLC/ffplay to play streamhttp://localhost:8080/live/livestream.mpd
Note: Please enable HTTP-TS by
SRS_VHOST_HTTP_REMUX_MOUNT=[vhost]/[app]/[stream].ts
then use H5/VLC/ffplay to play streamhttp://localhost:8080/live/livestream.ts
Note: Please enable DVR MP4 by
SRS_VHOST_DVR_ENABLED=on SRS_VHOST_DVR_DVR_PATH=./objs/nginx/html/[app]/[stream].[timestamp].mp4
if want to covert live stream to MP4 file.
Note: The detail about available protocols and tools for HEVC, please see Status of HEVC in SRS.
Note: The H5 player uses 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
The FFmpeg in ossrs/srs:encoder
or ossrs/srs:6
is built with libx265 and patched with HEVC over RTMP support. So you're able to directly use:
docker run --rm -it --net host ossrs/srs:encoder \
ffmpeg -re -i doc/source.flv -acodec copy -vcodec libx265 \
-f flv rtmp://localhost/live/livestream
If you want to build from code, please read the bellow instructions. Before build FFmpeg, we must build 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
And then 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
Keep in mind that FFmpeg 6.0 does not support HEVC over RTMP until the following commit 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>
So, if you are using FFmpeg 6, you can build FFmpeg without any patch, directly by the following commands:
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
Push HEVC over RTMP to SRS:
./ffmpeg -stream_loop -1 -re -i ~/srs/doc/source.flv -acodec copy -vcodec libx265 \
-f flv rtmp://localhost/live/livestream
Play HEVC over RTMP by ffplay:
./ffplay rtmp://localhost/live/livestream
It works like magic!
If you want to use HEVC over RTMP in FFmpeg 4.1 or 5.1, please read the following instructions. Please clone FFmepg and checkout to 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/
Finally, follow the previous instructions to build 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.