logo
Live Streaming
On this page

H.265

2024-01-02

Feature Introduction

Feature Description

H.265 is an efficient video coding standard designed to transmit higher quality network video with limited bandwidth. Developers can output H.265 format video bitstreams during encoding or stream mixing.

Notes
  • ZEGO Express SDK has supported this feature since version 2.12.0 (released on 2021-09-09).
  • If you need to support H.265 video encoding, you need to upgrade all online ZEGO Express SDKs to version 2.12.0 or above. Otherwise, online versions may experience exceptions when decoding H.265.

The differences between H.265 and H.264 are as follows:

Difference ItemH.264H.265
Bitrate under the same video quality-H.265 can save about 30% bitrate compared to H.264 (measured value).
Software encoding performance-H.265 consumes about 3 times the computing power of H.264.
Software decoding performance-H.265 consumes about 1.5 times the computing power of H.264.
Hardware ecosystemBasically all models support hardware encoding and decoding.Most models support hardware encoding, and the vast majority of models support hardware decoding.
Stream mixing outputSupported.Supported, but the price is more expensive than H.264 stream mixing output. For details, please consult ZEGOCLOUD business personnel.
Applicable scenariosAll scenarios.Recommended for use in live streaming and audio/video interaction scenarios.

Application Scenarios

In the following application scenarios, H.265 can be used for encoding:

Application Scenario TypeDescription
Show live streaming, e-commerce live streaming, interactive live streaming, game live streamingThrough H.265 encoding, reduce the bitrate by 30% (measured value) and distribute to thousands of viewers, greatly reducing CDN distribution costs.
Video calls, video conferences, online educationThrough H.265 encoding, improve video clarity under the same bitrate, making call effects better in these scenarios.
Warning

Currently, Web and mini-program platforms do not support H.265 stream playing.

Concept Explanation

  • Video encoding: A way to convert original video format files into another video format through specific compression technology for easy transmission and storage.
  • Stream mixing: A technology that mixes multiple audio and video streams into one stream from the cloud. It supports three methods: manual stream mixing, automatic stream mixing, and fully automatic stream mixing. For details, please refer to Stream Mixing.
  • Relaying to CDN: The process of pushing audio and video streams from ZEGOCLOUD to CDN. For details, please refer to Publishing/Playing Streams through CDN.
  • Co-hosting: A form of interaction between users in a room. While publishing your own stream through the startPublishingStream interface, you also call the startPlayingStream interface to play the other party's stream. After two users successfully co-host, they can conduct interactive calls.

Service Activation

  1. When using stream mixing to output H.265 bitstreams, you need to contact ZEGOCLOUD Technical Support to activate the service.
  2. When using stream mixing to output H.265 bitstreams, there are changes in billing. Please contact ZEGOCLOUD business personnel to learn about specific costs.

Sample Source Code Download

Please refer to Download Sample Source Code to get the source code.

For related source code, please check files in the "/ZegoExpressExample/Examples/AdvancedStreaming/H265" directory.

Prerequisites

Before using H.265 encoding and decoding functions, please ensure:

Implementation Methods

Check H.265 Encoding and Decoding Capabilities

Check H.265 Encoding Capability

Some older or low-end mobile models do not support H.265 video encoding. At this time, developers need to use the isVideoEncoderSupported interface before publishing stream to determine whether the local device supports H.265 video encoding capability. Only if supported, can the H.265 video encoding type be set through the setVideoConfig interface before publishing stream. Otherwise, it will not take effect.

Check H.265 Decoding Capability

Some older or low-end mobile models do not support H.265 video decoding. In scenarios that support playing different video bitstreams, such as CDN scenarios, developers need to use the isVideoDecoderSupported interface before playing stream to determine whether the local device supports H.265 video decoding capability. Only if supported, can H.265 video bitstreams be played. Otherwise, only other format video bitstreams can be played, such as H.264.

Co-hosting Stream Mixing Live Streaming

Co-hosting stream mixing live streaming includes the following two implementation methods. Developers can choose to integrate according to actual needs:

  • Mix out different format bitstreams (recommended): The stream mixing service directly outputs one H.265 mixed stream and one H.264 mixed stream. This scenario only requires one transcoding in the stream mixing service, without the need for CDN transcoding. Compared with stream mixing CDN transcoding, it has higher clarity and is cheaper. It is recommended to use.

  • Stream mixing to CDN transcoding: The stream mixing service directly outputs one H.265 mixed stream, which needs to use CDN's transcoding capability to transcode one H.265 stream and one H.264 stream.

    Warning

    You need to contact ZEGOCLOUD Technical Support to activate the CDN transcoding function.

In this scenario, after the stream mixing service receives the published streams from the host and co-hosting guests through ZEGOCLOUD, it directly outputs one H.265 mixed stream and one H.264 mixed stream, and pushes both streams to CDN. The audience can choose to play H.265 bitstreams or H.264 bitstreams from CDN according to whether their terminal devices support H.265 video decoding.

  • Host side

    1. Create a new stream mixing task object through the constructor ZegoMixerTask, then call instance methods to set inputs, outputs, and other parameters respectively.
    2. Set the stream mixing task input stream list through the setInputList property in the stream mixing task object ZegoMixerTask (the encoding format of streams in stream mixing input supports both H.264 and H.265), supporting up to 9 input streams by default. Please handle the stream layout yourself.
    3. Set the stream mixing task output stream list through the setOutputList property in the stream mixing task object ZegoMixerTask. Assuming in the current scenario, the stream mixing service directly transcodes one H.264 mixed stream and one H.265 mixed stream, that is, the stream mixing output video encoding format is H.264 and H.265.
    4. Call the startMixerTask interface to initiate a stream mixing task.
    5. The developer notifies the App's business server that a new stream has been added.
    // Call startMixerTask to initiate stream mixing
    // Please enter taskID
    NSString *taskID = @"";
    ZegoMixerTask *task = [[ZegoMixerTask alloc] initWithTaskID:taskID];
    
    // Please set videoConfig yourself
    CGSize resolution = CGSizeMake(720, 1280);
    int fps = 15;
    int bitrate = 1500;
    
    ZegoMixerVideoConfig *videoConfig = [[ZegoMixerVideoConfig alloc] initWithResolution:resolution fps:fps bitrate:bitrate];
    [task setVideoConfig:videoConfig];
    
    [task setAudioConfig:[ZegoMixerAudioConfig defaultConfig]];
    
    // Note, the encoding format of streams in stream mixing input supports H.264 and H.265. Please handle stream layout and input yourself
    NSArray<ZegoMixerInput *> *inputArray = [NSArray new];
    [task setInputList:inputArray];
    
    // Stream mixing two outputs
    // Note: output target can be streamID or CDN address. The two are handled differently on the audience side. This scenario recommends directly passing in stremaID
    // Note: The bitrate in ZegoMixerOutput has higher priority than the bitrate in ZegoMixerVideoConfig
    NSString *h264StreamID = @""; // Please enter h264StreamID
    NSString *h265StreamID = @""; // Please enter h265StreamID
    // Please enter h264 bitrate. This bitrate is the recommended bitrate for the current resolution and frame rate (720p, 15fps)
    int h264Bitrate = 2244;
    // Please enter h265 bitrate. This bitrate is the recommended bitrate for the current resolution and frame rate (720p, 15fps)
    int h265Bitrate = 1795;
    ZegoMixerOutput *outputH264 = [[ZegoMixerOutput alloc] initWithTarget:h264StreamID];
    ZegoMixerOutputVideoConfig *outputH264VideoConfig = [[ZegoMixerOutputVideoConfig alloc] init];
    [outputH264VideoConfig configWithCodecID:ZegoVideoCodecIDDefault bitrate:h264Bitrate];
    [outputH264 setVideoConfig:outputH264VideoConfig];
    
    ZegoMixerOutput *outputH265 = [[ZegoMixerOutput alloc] initWithTarget:h265StreamID];
    ZegoMixerOutputVideoConfig *outputH265VideoConfig = [ZegoMixerOutputVideoConfig new];
    [outputH265VideoConfig configWithCodecID:ZegoVideoCodecIDH265 bitrate:h265Bitrate];
    [outputH265 setVideoConfig:outputH265VideoConfig];
    
    NSArray<ZegoMixerOutput *> *outputArray = @[outputH264, outputH265];
    [task setOutputList:outputArray];
    
    [[ZegoExpressEngine sharedEngine] startMixerTask:task callback:^(int errorCode, NSDictionary * _Nullable extendedData) {
        // Stream mixing task callback
    }];
    
    // The developer notifies the App's business server that a new stream has been added
  • Audience side

    1. The audience side receives a notification of new stream from the App's business server.
    2. Call the isVideoDecoderSupported interface to check whether the audience side's device supports H.265 decoding format.
    // Receive notification of new stream from App's business server
    
    BOOL h265DecodeSupport = [[ZegoExpressEngine sharedEngine] isVideoDecoderSupported:ZegoVideoCodecIDH265];
    // h264StreamID
    NSString *h264StreamID = @"";
    // h265StreamID
    NSString *h265StreamID = @"";
    // view for rendering playing stream
    UIView *playView;
    ZegoCanvas *playCanvas = [ZegoCanvas canvasWithView:playView];
    
    if (h265DecodeSupport) {
        // Supports H.265 decoding
        [[ZegoExpressEngine sharedEngine] startPlayingStream:h265StreamID canvas:playCanvas];
    
    }
    else {
        // Does not support H.265 decoding
        [[ZegoExpressEngine sharedEngine] startPlayingStream:h264StreamID canvas:playCanvas];
    }

Stream mixing to CDN then transcoding

In this scenario, after the stream mixing service receives the published streams from the host and co-hosting guests through ZEGOCLOUD, it directly outputs one H.265 mixed stream and pushes this mixed stream to CDN. Through CDN's transcoding capability, the audience can choose to play H.265 bitstreams or H.264 bitstreams from CDN according to whether their terminal devices support H.265 video decoding.

  • Host side

    1. Create a new stream mixing task object through the constructor ZegoMixerTask, then call instance methods to set inputs, outputs, and other parameters respectively.
    2. Set the stream mixing task input stream list through the setInputList property in the stream mixing task object ZegoMixerTask (the encoding format of streams in stream mixing input supports both H.264 and H.265), supporting up to 9 input streams by default. Please handle the stream layout yourself.
    3. Set the stream mixing task output stream list through the setOutputList property in the stream mixing task object ZegoMixerTask. Assuming in the current scenario, the stream mixing service directly outputs one H.265 mixed stream, that is, the stream mixing output video encoding format is H.265.
    4. Call the startMixerTask interface to initiate a stream mixing task.
    5. The developer notifies the App's business server that a new stream has been added.
    // Call startMixerTask to initiate stream mixing
    // Please enter taskID
    NSString *taskID = @"";
    ZegoMixerTask *task = [[ZegoMixerTask alloc] initWithTaskID:taskID];
    
    // Please set videoConfig
    CGSize resolution = CGSizeMake(720, 1280);
    int fps = 15;
    int bitrate = 1500;
    
    ZegoMixerVideoConfig *videoConfig = [[ZegoMixerVideoConfig alloc] initWithResolution:resolution fps:fps bitrate:bitrate];
    [task setVideoConfig:videoConfig];
    
    [task setAudioConfig:[ZegoMixerAudioConfig defaultConfig]];
    
    // Note, the encoding format of streams in stream mixing input supports H.264 and H.265
    NSArray<ZegoMixerInput *> *inputArray = [NSArray new];
    [task setInputList:inputArray];
    // Please enter CDN URL
    NSString *publishCdnUrl = @"";
    // Please enter h265 bitrate. This bitrate is the recommended bitrate for the current resolution and frame rate (720p, 15fps)
    int h265Bitrate = 1795;
    // Note, since CDN transcoding is needed here, target needs to pass in CDN URL
    ZegoMixerOutput *outputH265 = [[ZegoMixerOutput alloc] initWithTarget:publishCdnUrl];
    ZegoMixerOutputVideoConfig *outputH265VideoConfig = [ZegoMixerOutputVideoConfig new];
    [outputH265VideoConfig configWithCodecID:ZegoVideoCodecIDH265 bitrate:h265Bitrate];
    [outputH265 setVideoConfig:outputH265VideoConfig];
    
    NSArray<ZegoMixerOutput *> *outputArray = @[outputH265];
    [task setOutputList:outputArray];
    
    [[ZegoExpressEngine sharedEngine] startMixerTask:task callback:^(int errorCode, NSDictionary * _Nullable extendedData) {
        // Stream mixing task callback
    }];
    
    // The developer notifies the App's business server that a new stream has been added
  • Audience side

    1. The audience side receives a notification of new stream from the App's business server.
    2. Call the isVideoDecoderSupported interface to check whether the audience side's device supports H.265 decoding format.
    // Receive notification of new stream from App's business server
    BOOL h265DecodeSupport = [[ZegoExpressEngine sharedEngine] isVideoDecoderSupported:ZegoVideoCodecIDH265];
    NSString *playStreamID = @"";
    // view for rendering playing stream
    UIView *playView;
    ZegoCanvas *playCanvas = [ZegoCanvas canvasWithView:playView];
    if (h265DecodeSupport) {
        // Supports H.265 decoding
        // Please enter H.265 Url address
        NSString *h265Url = @"";
    
        // Note: ZegoCDNConfig and ZegoPlayerConfig have other configurable items
        ZegoCDNConfig *cdnConfig = [ZegoCDNConfig new];
        // H.265 CDN playing URL
        cdnConfig.url = h265Url;
        ZegoPlayerConfig *playerConfig = [ZegoPlayerConfig new];
        playerConfig.cdnConfig = cdnConfig;
        [[ZegoExpressEngine sharedEngine] startPlayingStream:playStreamID canvas:playCanvas config:playerConfig];
    }
    else {
        // Does not support H.265 decoding
        NSString *h264Url = @""; // Please enter H264 Url address
        // Note: ZegoCDNConfig and ZegoPlayerConfig have other configurable items
        ZegoCDNConfig *cdnConfig = [ZegoCDNConfig new];
        // H.264 CDN playing URL
        cdnConfig.url = h264Url;
        ZegoPlayerConfig *playerConfig = [ZegoPlayerConfig new];
        playerConfig.cdnConfig = cdnConfig;
        [[ZegoExpressEngine sharedEngine] startPlayingStream:playStreamID canvas:playCanvas config:playerConfig];
    }

Single Host Live Streaming

Real-time Network Relaying to CDN Live Streaming

This scenario has the following two characteristics:

  • The host relays to CDN through ZEGOCLOUD. Through CDN's transcoding capability, the audience can choose to play H.265 bitstreams or H.264 bitstreams from CDN according to whether their terminal devices support H.265 video decoding.
  • When the host publishes H.265 bitstreams, co-hosting guests play streams directly from ZEGOCLOUD for real-time interaction. At this time, it is required that the co-hosting guest's terminal device supports H.265 video decoding capability.
  • Host side

    1

    After creating the engine, call the enableHardwareEncoder interface to enable hardware encoding (if the configuration is changed after publishing stream, it needs to wait for the next publishing stream to take effect). After enabling, GPU will be used for encoding, reducing CPU usage.

    2

    Call the isVideoEncoderSupported interface to check whether the host side's device supports the specified video encoding type.

    3

    Before publishing stream, call the setVideoConfig interface and set the video encoding format through codecID (if the configuration is changed after publishing stream, it needs to wait for the next publishing stream to take effect). If H.265 encoding is set, then:

    1

    You can call the enableH265EncodeFallback interface to enable automatic fallback to H.264 encoding when H.265 encoding fails (enabled by default). After enabling, when H.265 encoding is not supported or H.265 encoding fails, the SDK will internally try to downgrade to use H.264 encoding for publishing stream. After disabling, when H.265 encoding is not supported or H.265 encoding fails, publishing stream will directly fail.

    2

    Call the addPublishCdnUrl interface to add the URL address for relaying audio and video streams from ZEGOCLOUD to CDN.

    3

    Call the startPublishingStream interface to start publishing stream. After publishing stream succeeds, other users in the same room can get the addition of streams by listening to the onRoomStreamUpdate callback.

    4

    The developer notifies the App's business server of the encoding format of this publishing stream, so that the playing side can be notified to handle accordingly based on different publishing encoding formats.

    // Mobile devices need to enable hardware encoding to use H.265 encoding
    [[ZegoExpressEngine sharedEngine] enableHardwareEncoder:YES];
    
    // Check whether H.265 encoding is supported
    BOOL h265EncoderSupport = [[ZegoExpressEngine sharedEngine] isVideoEncoderSupported:ZegoVideoCodecIDH265];
    
    ZegoVideoConfig *videoConfig = [ZegoVideoConfig defaultConfig];
    if (h265EncoderSupport) {
        // Supports H.265 encoding
        videoConfig.codecID = ZegoVideoCodecIDH265;
    } else {
        // Does not support H.265 encoding
        videoConfig.codecID = ZegoVideoCodecIDDefault;
    }
    [[ZegoExpressEngine sharedEngine] setVideoConfig:videoConfig];
    
    if (h265EncoderSupport) {
        // Choose whether to enable H.265 encoding failure automatic fallback capability through enableH265EncodeFallback
        [[ZegoExpressEngine sharedEngine] enableH265EncodeFallback:YES];
    }
    // Please enter streamID
    NSString *publishStreamID = @"";
    // Please enter CdnUrl
    NSString *publishCdnUrl = @"";
    // Add CDN relaying URL
    [[ZegoExpressEngine sharedEngine] addPublishCdnUrl:publishCdnUrl streamID:publishStreamID callback:^(int errorCode) {
        // Determine whether the relaying CDN URL was added successfully
    }];
    [[ZegoExpressEngine sharedEngine] startPublishingStream:publishStreamID];
    
    // The developer notifies the App's business server of the encoding format of this publishing stream, so that the playing side can be notified to handle accordingly based on different publishing encoding formats
  • Audience side

    1. After the host publishes stream, the audience side receives a notification of new stream through the onRoomStreamUpdate interface.
    2. The audience side gets the encoding format of this publishing stream from the App's business server.
    • If it is H.264 format, the audience can call the startPlayingStream interface to play the host's stream directly from CDN.
    • If it is H.265 format, need to first call the isVideoDecoderSupported interface to check whether the audience side's device supports H.265 decoding format.
    //Receive notification of new stream onRoomStreamUpdate
    - (void)onRoomStreamUpdate:(ZegoUpdateType)updateType streamList:(NSArray<ZegoStream *> *)streamList extendedData:(NSDictionary *)extendedData roomID:(NSString *)roomID {
        // Get the encoding format of this stream from App's business server
        int videoCodecID = 0;
        // Please enter streamID
        NSString *playStreamID = @"";
        // view for rendering playing stream
        UIView *playView;
        ZegoCanvas *playCanvas = [ZegoCanvas canvasWithView:playView];
    
        if (videoCodecID == ZegoVideoCodecIDH265) {
            // Encoding format is H.265, specific fallback strategy needs to be combined with advanced playing stream
            BOOL h265DecoderSupport = [[ZegoExpressEngine sharedEngine] isVideoDecoderSupported:ZegoVideoCodecIDH265];
    
            if (h265DecoderSupport) {
                // Supports H.265 decoding
                // Please enter H.265 Url address
                NSString *h265Url = @"";
    
                // Note: ZegoCDNConfig and ZegoPlayerConfig have other configurable items
                ZegoCDNConfig *cdnConfig = [ZegoCDNConfig new];
                // H.265 CDN playing URL
                cdnConfig.url = h265Url;
                ZegoPlayerConfig *playerConfig = [ZegoPlayerConfig new];
                playerConfig.cdnConfig = cdnConfig;
                [[ZegoExpressEngine sharedEngine] startPlayingStream:playStreamID canvas:playCanvas config:playerConfig];
    
            }
            else {
                // Does not support H.265 decoding
                // Please enter H264 Url address
                NSString *h264Url = @"";
    
                // Note: ZegoCDNConfig and ZegoPlayerConfig have other configurable items
                ZegoCDNConfig *cdnConfig = [ZegoCDNConfig new];
                // H.264 CDN playing URL
                cdnConfig.url = h264Url;
                ZegoPlayerConfig *playerConfig = [ZegoPlayerConfig new];
                playerConfig.cdnConfig = cdnConfig;
                [[ZegoExpressEngine sharedEngine] startPlayingStream:playStreamID canvas:playCanvas config:playerConfig];
            }
        }
        else if (videoCodecID == ZegoVideoCodecIDDefault) {
            // Encoding format is H.264
            [[ZegoExpressEngine sharedEngine] startPlayingStream:playStreamID canvas:playCanvas];
        }
    }
  • Co-hosting guest side

    1. After the host publishes stream, co-hosting guests receive notification of new stream through the onRoomStreamUpdate interface.
    2. Co-hosting guests get the encoding format of this publishing stream from the App's business server.
      • If it is H.264 format, co-hosting guests can call the startPlayingStream interface to play the host's stream directly from ZEGOCLOUD.
      • If it is H.265 format, need to first call the isVideoDecoderSupported interface to check whether their own device supports H.265 decoding format.
        • If supported, call the startPlayingStream interface to play H.265 bitstreams from ZEGOCLOUD.
        • If not supported, prompt that the current terminal device does not support playing this stream.
    //Receive notification of new stream onRoomStreamUpdate
    - (void)onRoomStreamUpdate:(ZegoUpdateType)updateType streamList:(NSArray<ZegoStream *> *)streamList extendedData:(NSDictionary *)extendedData roomID:(NSString *)roomID {
        // Get the encoding format of this stream from App's business server
        int videoCodecID = 0;
        // Please enter streamID
        NSString *playStreamID = @"";
        // view for rendering playing stream
        UIView *playView;
        ZegoCanvas *playCanvas = [ZegoCanvas canvasWithView:playView];
        ZegoPlayerConfig *config = [[ZegoPlayerConfig alloc]init];
        // Only play stream from RTC
        config.resourceMode = ZegoStreamResourceModeOnlyRTC;
    
        if (videoCodecID == ZegoVideoCodecIDH265) {
            // Encoding format is H.265
            BOOL h265DecoderSupport = [[ZegoExpressEngine sharedEngine] isVideoDecoderSupported:ZegoVideoCodecIDH265];
    
            // If decoding is not supported, do not play stream
            if (h265DecoderSupport) {
                // Supports H.265 decoding
                [[ZegoExpressEngine sharedEngine] startPlayingStream:playStreamID canvas:playCanvas config:config];
            }
        }
        else if (videoCodecID == ZegoVideoCodecIDDefault) {
            // Encoding format is H.264
            [[ZegoExpressEngine sharedEngine] startPlayingStream:playStreamID canvas:playCanvas config:config];
        }
    }

Recording

If H.265 encoding and decoding functions are used during local server-side recording, cloud recording, or data stream recording, it will affect the generation of recording files. Details are as follows:

When recording a publishing stream (H.265 video encoding bitstream), it may trigger encoding fallback due to H.265 encoding failure. At this time, the onPublisherVideoEncoderChanged callback will be received, indicating that the video encoding format has changed.

In this scenario, to avoid damaging the recording file, the SDK will internally end and save the current recording task and automatically restart a new recording task. The recording file path of the new recording task will be regenerated to avoid overwriting the original recording file. The generation rule for the new file is to add a timestamp to the original recording file name:

For example, if the original recording file path passed in by the developer is: /user/data/mediarecord.mp4, then the new recording file is: /user/data/mediarecord_1626880634948.mp4, where 1626880634948 is the current timestamp.

Notes

If developers have received the onPublisherVideoEncoderChanged callback during recording, they need to collect other files in the recording file storage path after the recording ends.

FAQ

  1. What to do when H.265 hardware encoding encounters an error?

You can call the enableH265EncodeFallback interface to enable the fallback function (enabled by default). If H.265 hardware encoding fails, it will fallback to H.264. If using the recording function at the same time, the recording files will become two copies.

  1. Will H.265 automatically fallback from hardware decoding to software decoding?

Yes, if hardware decoding fails during decoding, it will automatically fallback to software decoding.

  1. How is H.265 charged?

Enabling H.265 functionality on the client side does not require fees, but stream mixing output H.265 requires stream mixing fees, which is more expensive than stream mixing output H.264. For details, please consult ZEGOCLOUD business personnel.

  1. Is there a change in billing when stream mixing inputs H.265 streams and outputs H.264 streams?

No change, billing is based on output H.264.

  1. What are the hardware requirements for H.265 decoding?

Currently, all models on the market support H.265 decoding. Based on testing, low-end models before 2013 may experience frame rate fluctuations during decoding.

Previous

Subject Segmentation

Next

Video Large/Small Stream and Layered Encoding