Skip to main content
Version: 6.0 (Unstable) 🚧

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.

Note: To check if your Chrome support HEVC, please open chrome://gpu and search hevc.

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 or conf/hevc.ts.conf config files. Note: Recommend conf/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:

Note: Please enable MPEG-DASH by SRS_VHOST_DASH_ENABLED=on then use VLC/ffplay to play stream http://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 stream http://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:

Please follow other section to publish HEVC stream.

Thanks for Contributors

There is a list of commits and contributors about HEVC in SRS:

We will merge some of these commits to SRS 6.0, but not all commits.

Known Issues

  1. HEVC over Safari WebRTC, only support WebRTC to WebRTC, doesn't support converting to RTMP.
  2. Chrome/Firefox does not support HEVC, no any plan as I know.
  3. Almost all browsers supports MSE, except iOS. HEVC over MSE requires hardware decoder.
  4. Apart from mpegts.js, other H5 players such as hls.js/dash.js doesn't support HEVC.