All Products
Search
Document Center

ApsaraVideo VOD:Implement adaptive bitrate streaming with ApsaraVideo VOD

Last Updated:Sep 05, 2023

ApsaraVideo VOD transcodes videos into video streams of different bitrates and packages these video streams into a single file. The file also provides a streaming profile that includes information such as available bitrates and resolutions. This allows media players to switch between variable bitrates based on the network conditions.

Note

The most widely used adaptive bitrate streaming protocols are HTTP Live Streaming (HLS) and Dynamic Adaptive Streaming over HTTP (DASH). ApsaraVideo VOD supports only HLS adaptive bitrate streaming. For more information, see Adaptive bitrate streaming.

Overview

In ApsaraVideo VOD, you can use video packaging templates and subtitle packaging templates to package video streams that have different bitrates and subtitles in different languages. This way, media players can switch bitrates and subtitles. You can create templates for adaptive bitrate streaming by using the console and API operations.

Adaptive bitrate streaming enables media players to automatically switch to the most suitable video stream based on the network condition and streaming device. This greatly enhances the quality of video playback. The following table describes the differences between a video packaging template and a regular transcoding template.

Item

Video packaging template

Regular transcoding template

Parameter configurations

Packaging parameters are required, including the packaging type and bandwidth threshold.

None.

Subtitling

Embedded subtitles and sidecar subtitles are supported.

Subtitles can only be embedded by calling API operations.

Streaming performance

The media player automatically switches to the most appropriate bitrate based on the network bandwidth.

The stream at the specified bitrate is played.

Usage notes

  • Video packaging templates do not support HLS encryption. If you require HLS encryption, use a regular transcoding template.

  • The subtitle file and video source file must be stored in the same Object Storage Service (OSS) bucket.

  • A subtitle packaging template cannot be created and used separately. It must be used together with a video packaging template.

  • The subtitle packaging template supports only subtitle files in the Web Video Text Tracks (WebVTT) format. When you call API operations to modify the Language parameter, you can use the original value of the Language parameter to find a subtitle file, and then replace the file with a subtitle file in the language that you specified as the new value of the Language parameter. You cannot directly change the language of subtitles in the file. The operation fails if you cannot find any subtitle files in the language indicated by the original value of the Language parameter.

  • You are charged for transcoding. For more information, visit the ApsaraVideo VOD pricing page.

Use the console

  1. Create a transcoding template group for adaptive bitrate streaming.

    Note

    If you require only packaging templates for adaptive bitrate streaming, you do not need to create regular transcoding templates. You need to delete all existing regular transcoding templates to avoid unnecessary transcoding fees.

    1. Log on to the ApsaraVideo VOD console. In the left-side navigation pane, choose Configuration Management > Media Processing > Transcoding Template Groups.

    2. On the Transcoding Template Groups page, click Create Transcoding Template Group.

    3. On the page that appears, specify a name for the template group.

    4. In the Video Packaging Template section, click Add Template, and set the parameters.

      • In the Basic Parameters section, Encapsulation Format is fixed to hls. The Video Packaging section contains the following parameters:

        • Packaging Type: The value is fixed to HLS packaging.

        • Bandwidth Threshold: the network bandwidth based on which media players select video streams of specific bitrates. Unit: bit/s. We recommend that you use the recommended value.

      • You can configure Basic Parameters, Video Parameters, Audio Parameters, Advanced Parameters, and Conditional Transcoding Parameters in the same way as you create regular transcoding templates. For more information about how to configure these parameters, see Configure normal transcoding template groups.

      • You can use Add Template to create multiple video packaging templates with different bitrates, resolutions, and video qualities based on your business requirements. Video qualities include high definition, standard definition, and low definition.

    5. After the parameters are configured, click Save.

  2. Transcode a video into streams of different bitrates.

    1. In the ApsaraVideo VOD console, choose Media Files > Audio/Video.

    2. On the Video and Audio page, find the video that you want to transcode, and click Media Processing in the Actions column.

    3. In the Media Processing dialog box, set Processing Type to Use Transcoding Template Group, select the transcoding template group that you created in Step 1, and then click OK to start media processing.

  3. View video streams.

    • The following figure shows the video streams that are generated after adaptive bitrate streaming is implemented. In this example, two streams use fixed bitrates while one stream adapts its bitrate based on network bandwidths.

      In the ApsaraVideo VOD console, choose Media Files > Audio/Video, find the video that you processed in the previous step, and click Manage in the Actions column. On the page that appears, click the Video URL tab.

      效果展示_1
    • The URL of the adaptive bitrate stream in the preceding figure is used for playback.

      On the Basic tab of the Online Settings page in ApsaraVideo Player, enter the URL of the adaptive bitrate stream and view the video playback effect on the Preview tab.

Use the API

  1. Create a transcoding template group for adaptive bitrate streaming.

    The following sample code is used to configure a regular transcoding template, a packaging template for adaptive bitrate streaming, and a subtitle packaging template. You can use the sample code based on your requirements.

    Note

    If you require only packaging templates for adaptive bitrate streaming, you do not need to create regular transcoding templates. You need to delete all existing regular transcoding templates to avoid unnecessary transcoding fees.

        /**
         * Sample code
         */
        public static void main(String[] args) throws ClientException {
            // The AccessKey pair of an Alibaba Cloud account has permissions on all API operations. We recommend that you use a RAM user to call API operations or perform routine O&M. 
            // We recommend that you do not include your AccessKey pair (AccessKey ID and AccessKey secret) in your project code. Otherwise, the AccessKey pair may be leaked and the security of all resources within your account may be compromised. 
            // In this example, ApsaraVideo VOD reads the AccessKey pair from the environment variables to implement identity verification for API access. Before you run the sample code, configure the environment variables ALIBABA_CLOUD_ACCESS_KEY_ID and ALIBABA_CLOUD_ACCESS_KEY_SECRET. 
            DefaultAcsClient client = initVodClient(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"), System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
            AddTranscodeTemplateGroupResponse response = new AddTranscodeTemplateGroupResponse();
            try {
                response = addTranscodeTemplateGroup(client);
                System.out.println("TranscodeTemplateGroupId = " + response.getTranscodeTemplateGroupId());
            } catch (Exception e) {
                System.out.println("ErrorMessage = " + e.getLocalizedMessage());
            }
            System.out.println("RequestId = " + response.getRequestId());
        }
    
        /**
         * Configure a transcoding template group.
         */
        public static AddTranscodeTemplateGroupResponse addTranscodeTemplateGroup(DefaultAcsClient client) throws Exception {
            AddTranscodeTemplateGroupRequest request = new AddTranscodeTemplateGroupRequest();
            request.setName("grouptest2");
            JSONArray transcodeTemplateList = new JSONArray();
            // Configure a regular transcoding template.
            transcodeTemplateList.add(buildNormalTranscodeConfig());
            // Configure a packaging template for adaptive bitrate streaming.
            transcodeTemplateList.add(buildVideoPackageConfig());
            // Configure a subtitle packaging template.
            transcodeTemplateList.add(buildSubtitlePackageConfig());
            request.setTranscodeTemplateList(transcodeTemplateList.toJSONString());
            System.out.println("request = " + JSONObject.toJSONString(request));
            return client.getAcsResponse(request);
        }
    
        /**
         * Set parameters required for adding a transcoding template.
         *
         * @return
         */
        public static JSONObject buildNormalTranscodeConfig() {
            JSONObject transcodeTemplate = new JSONObject();
            // The type of the template. <Normal: regular transcoding template; VideoPackage: video packaging template; SubtitlePackage: subtitle packaging template>
            transcodeTemplate.put("Type","Normal");
            // The name of the template.
            transcodeTemplate.put("TemplateName", "Regular transcoding template for MP4");
            // The definition.
            transcodeTemplate.put("Definition", "HD");
            // The transcoding settings for video streams.
            JSONObject video = new JSONObject();
            video.put("Width", 1280);
            //video.put("Height", 720);
            video.put("Bitrate", 1500);
            video.put("Fps", 25);
            //video.put("Remove", false);
            video.put("Codec", "H.264");
            video.put("Gop", "250");
            video.put("LongShortMode", false);
            transcodeTemplate.put("Video", video);
            // The transcoding settings for audio streams.
            JSONObject audio = new JSONObject();
            audio.put("Codec", "AAC");
            audio.put("Bitrate", "64");
            audio.put("Channels", "2");
            audio.put("Samplerate", "32000");
            transcodeTemplate.put("Audio", audio);
            // The container.
            JSONObject container = new JSONObject();
            container.put("Format", "mp4");
            transcodeTemplate.put("Container", container);
            // The subtitle replacement settings.
            JSONObject subtitleSetting = new JSONObject();
            JSONArray subtitleList = new JSONArray();
            JSONObject subtitle = new JSONObject();
            // The OSS endpoint of the subtitle file. HTTPS URLs are not supported.
            subtitle.put("SubtitleUrl", "http://outin-8db8d2****3e1c9256.oss-cn-shanghai.aliyuncs.com/subtitle/3215879C9F724A43BC84C63BE2AA19AF****.srt");
            // The encoding format of the subtitle content. Valid values: auto, UTF-8, GBK, and BIG5. If you set the value to auto, the system automatically selects an encoding format.
            subtitle.put("CharEncode", "UTF-8");
            subtitleList.add(subtitle);
            transcodeTemplate.put("SubtitleList", subtitleList);
            return transcodeTemplate;
        }
    
        /**
         * Configure video packaging parameters.
         *
         * @return
         */
        private static JSONObject buildVideoPackageConfig() {
            JSONObject transcodeTemplate = new JSONObject();
            // The type of the template. <Normal: regular transcoding template; VideoPackage: video packaging template; SubtitlePackage: subtitle packaging template>
            transcodeTemplate.put("Type","VideoPackage");
            // The name of the template.
            transcodeTemplate.put("TemplateName", "HLS LD packaging");
            // The definition.
            transcodeTemplate.put("Definition", "LD");
            // The transcoding settings for video streams.
            JSONObject video = new JSONObject();
            video.put("Width", 1280);
            //video.put("Height", 720);
            video.put("Bitrate", 1500);
            video.put("Fps", 25);
            //video.put("Remove", false);
            video.put("Codec", "H.264");
            video.put("Gop", "250");
            video.put("LongShortMode", false);
            transcodeTemplate.put("Video", video);
            // The transcoding settings for audio streams.
            JSONObject audio = new JSONObject();
            audio.put("Codec", "AAC");
            audio.put("Bitrate", "64");
            audio.put("Channels", "2");
            audio.put("Samplerate", "32000");
            transcodeTemplate.put("Audio", audio);
            // The container.
            JSONObject container = new JSONObject();
            container.put("Format", "m3u8");
            transcodeTemplate.put("Container", container);
            // Set the container format to m3u8. The MuxConfig parameter is required.
            JSONObject muxConfig = new JSONObject();
            JSONObject segment = new JSONObject();
            segment.put("Duration", "10");// Unit: seconds.
            muxConfig.put("Segment", segment);
            transcodeTemplate.put("MuxConfig",muxConfig);
    
            // The packaging settings.
            JSONObject packageSetting = new JSONObject();
            // The packaging type. Set the value to HLSPackage.
            packageSetting.put("PackageType","HLSPackage");
            JSONObject packageConfig = new JSONObject();
            packageConfig.put("BandWidth","500000");
            packageSetting.put("PackageConfig",packageConfig);
            transcodeTemplate.put("PackageSetting",packageSetting);
            return transcodeTemplate;
        }
    
        /**
         * Configure subtitle packaging parameters.
         *
         * @return
         */
        private static JSONObject buildSubtitlePackageConfig() {
            JSONObject transcodeTemplate = new JSONObject();
            // The type of the template. <Normal: regular transcoding template; VideoPackage: video packaging template; SubtitlePackage: subtitle packaging template>
            transcodeTemplate.put("Type","SubtitlePackage");
            // The name of the template.
            transcodeTemplate.put("TemplateName", "Multi-subtitle packaging");
            // The definition.
            transcodeTemplate.put("Definition", "HD");
            // The transcoding settings for video streams.
            JSONObject video = new JSONObject();
            video.put("Width", 1280);
            //video.put("Height", 720);
            video.put("Bitrate", 1500);
            video.put("Fps", 25);
            //video.put("Remove", false);
            video.put("Codec", "H.264");
            video.put("Gop", "250");
            video.put("LongShortMode", false);
            transcodeTemplate.put("Video", video);
            // The transcoding settings for audio streams.
            JSONObject audio = new JSONObject();
            audio.put("Codec", "AAC");
            audio.put("Bitrate", "64");
            audio.put("Channels", "2");
            audio.put("Samplerate", "32000");
            transcodeTemplate.put("Audio", audio);
            // The container.
            JSONObject container = new JSONObject();
            container.put("Format", "m3u8");
            transcodeTemplate.put("Container", container);
            // Set the container format to m3u8. The MuxConfig parameter is required.
            JSONObject muxConfig = new JSONObject();
            JSONObject segment = new JSONObject();
            segment.put("Duration", "10");// Unit: seconds.
            muxConfig.put("Segment", segment);
            transcodeTemplate.put("MuxConfig",muxConfig);
    
            /*
            The OSS endpoint of the subtitle file. HTTPS URLs and domain names for Alibaba Cloud CDN are not supported.
            Note: The subtitle file and video source file must be stored in the same OSS bucket of a region, such as cn-shanghai.
             */
            // The subtitle packaging template.
            JSONObject subtitlePackageConfig = new JSONObject();
            subtitlePackageConfig.put("Type","SubtitlePackage");
            // Configure a subtitle packaging template.
            JSONObject subtitlePackageSetting = new JSONObject();
            // The packaging type. Set the value to HLSPackage.
            subtitlePackageSetting.put("PackageType","HLSPackage");
            JSONArray subtitleExtractConfigs = new JSONArray();
            // Subtitle 1
            JSONObject subtitleExtractConfig = new JSONObject();
            JSONArray subtitleUrlList = new JSONArray();
            subtitleUrlList.add("http://outin-bfefbb9****e1c7426.oss-cn-shanghai.aliyuncs.com/subtitle/260447BA31D24F9E9E7752BF73F1319B****.vtt");
            subtitleExtractConfig.put("SubtitleUrlList",subtitleUrlList);
            subtitleExtractConfig.put("Language","cn");
            subtitleExtractConfig.put("Format","vtt");
            subtitleExtractConfig.put("Name","Chinese-test");
            // Subtitle 2
            JSONObject subtitleExtractConfig2 = new JSONObject();
            JSONArray subtitleUrlList2 = new JSONArray();
            subtitleUrlList2.add("http://outin-bfefbb9****3e1c7426.oss-cn-shanghai.aliyuncs.com/subtitle/661C67325E0543F0BB8CA7AAB756E6D8****.vtt");
            subtitleExtractConfig2.put("SubtitleUrlList",subtitleUrlList2);
            subtitleExtractConfig2.put("Language","en-US");
            subtitleExtractConfig2.put("Format","vtt");
            subtitleExtractConfig 2.put( "Name","English-test");
    
            subtitleExtractConfigs.add(subtitleExtractConfig);
            subtitleExtractConfigs.add(subtitleExtractConfig2);
            subtitlePackageSetting.put("SubtitleExtractConfigList",subtitleExtractConfigs);
            transcodeTemplate.put("PackageSetting",subtitlePackageSetting);
            return transcodeTemplate;
        }
    
        public static DefaultAcsClient initVodClient(String accessKeyId, String accessKeySecret) throws ClientException {
            // Specify the region from which you want to access ApsaraVideo VOD.
            String regionId = "cn-shanghai";
            DefaultProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, accessKeySecret);
            DefaultAcsClient client = new DefaultAcsClient(profile);
            return client;
        }
  2. Transcode a video into streams of different bitrates.

         public static void main(String[] args) {
           // Set the regionId parameter based on the region from which you want to access ApsaraVideo VOD, such as cn-shanghai.
           String regionId = "cn-shanghai";
           // The AccessKey pair of an Alibaba Cloud account has permissions on all API operations. We recommend that you use a RAM user to call API operations or perform routine O&M. 
           // We recommend that you do not include your AccessKey pair (AccessKey ID and AccessKey secret) in your project code. Otherwise, the AccessKey pair may be leaked and the security of all resources within your account may be compromised. 
           // In this example, ApsaraVideo VOD reads the AccessKey pair from the environment variables to implement identity verification for API access. Before you run the sample code, configure the environment variables ALIBABA_CLOUD_ACCESS_KEY_ID and ALIBABA_CLOUD_ACCESS_KEY_SECRET. 
            DefaultProfile profile = DefaultProfile.getProfile(regionId, System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"), System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
            IAcsClient client = new DefaultAcsClient(profile);
            String videoId = "76913816d****8e57e8c2952";
            String templateId = "4733b3a5****ae36ac22d34";
            try {
                SubmitTranscodeJobsResponse response = submitTranscodeJobs(client,videoId,templateId);
            } catch (ServerException e) {
                e.printStackTrace();
            } catch (ClientException e) {
                System.out.println("ErrCode:" + e.getErrCode());
                System.out.println("ErrMsg:" + e.getErrMsg());
                System.out.println("RequestId:" + e.getRequestId());
            }
        }
        
        /**
         * Start a transcoding job.
         * Pass the video ID and transcoding template group ID.
         *
         * @param client
         * @param videoId
         * @param templateGroupId
         * @return
         * @throws Exception
         */
        public static SubmitTranscodeJobsResponse submitTranscodeJobs(DefaultAcsClient client, String videoId, String templateGroupId) throws Exception {
            SubmitTranscodeJobsRequest request = new SubmitTranscodeJobsRequest();
            // The ID of the video that you want to transcode.
            request.setVideoId(videoId);
            // The ID of the transcoding template group.
            request.setTemplateGroupId(templateGroupId);
            // The transcoding priority. The default value is 6. A larger value indicates a higher priority. The value ranges from 1 to 10.
            request.setPriority("8");
            JSONObject overrideParams = buildOverrideParams();
            // The overrideParams parameter.
            request.setOverrideParams(overrideParams.toJSONString());
            return client.getAcsResponse(request);
        }
    
        // The sample code for configuring the overrideParams parameter.
        public static JSONObject buildOverrideParams() {
            JSONObject overrideParams = new JSONObject();
            // The settings for replacing the packaged subtitle file.
            JSONObject packageSubtitleSetting = new JSONObject();
            JSONArray packageSubtitleList = new JSONArray();
            JSONObject packageSubtitle = new JSONObject();
          // The ID of the subtitle template that includes the OSS endpoint of the subtitle file you want to replace.
            packageSubtitle.put("SubtitlePackageTemplateId", "69fa6ee58****e8492c76168****");
          // The Language parameter value is only used to search for the subtitle file that you want to replace. The language of subtitles in the file is not changed. The replacement fails if the subtitle file in the specified language does not exist. 
            packageSubtitle.put("Language", "cn");
            // The OSS endpoint of the subtitle file. HTTPS URLs are not supported. The subtitle file and video source file must be stored in the same region. 
            packageSubtitle.put("SubtitleUrl", "http://outin-bfefbb9****3e1c7426.oss-cn-shanghai.aliyuncs.com/subtitle/043956117D0C475EAB0CE8C4F7294221****.vtt");
            packageSubtitleList.add(packageSubtitle);
            packageSubtitleSetting.put("PackageSubtitleList", packageSubtitleList);
            overrideParams.put("PackageSubtitleSetting", packageSubtitleSetting);
            return overrideParams;
        }
  3. View video streams.

    • The following figure shows the video streams that are generated after adaptive bitrate streaming is implemented. In this example, two streams use fixed bitrates while one stream adapts its bitrate based on network bandwidths.

      In the ApsaraVideo VOD console, choose Media Files > Audio/Video, find the video that you processed in the previous step, and click Manage in the Actions column. On the page that appears, click the Video URL tab.

      效果展示_1
    • The URL of the adaptive bitrate stream in the preceding figure is used for playback.

      On the Basic tab of the Online Settings page in ApsaraVideo Player, enter the URL of the adaptive bitrate stream and view the video playback effect on the Preview tab.