ApsaraVideo VOD transcodes videos into video streams of different bitrates and packages these 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 network conditions.
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.
Introduction
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 enables media players to switch bitrates and subtitles. You can create templates for adaptive bitrate streaming using the console and API operations.
Adaptive bitrate streaming enables media players to automatically switch to the most suitable video stream based on network conditions and streaming devices. This greatly enhances the quality of video playback. The following table describes the differences between a video packaging template and a regular transcoding template.
Difference | Video packaging template | Regular transcoding template |
Parameter configuration | Packaging parameters are required, including the packaging type and bandwidth threshold. | This parameter is not configured. |
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. | You can only play back the specified stream. |
Notes
Video packaging templates do not support standard encryption. If you require standard encryption, use a normal transcoding template.
The subtitle file and video mezzanine file must be stored in the same Object Storage Service (OSS) bucket of a region.
The subtitle packaging template cannot be created separately. To use a subtitle packaging template, you must associate it 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.
Transcoding services are charged. For more information, see Billing.
Using the console
Create a transcoding template group for adaptive bitrate streaming.
NoteIf 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.
Log on to the ApsaraVideo VOD console. In the left navigation pane, choose Configuration Management > Media Processing > Transcoding Template Groups.
On the Transcoding Template Group tab, click Create Transcoding Template Group to navigate to the Add Transcoding Template page.
Set a name for the template group.
In the Audio and Video Packaging Template section, click Add Template to configure the template parameters.
When the Encapsulation Format in the Basic Information section is set to HLS, the following parameters are available in the Audio and Video Packaging Parameters section:
Set Packaging Type to HLS packaging.
Bandwidth Threshold: The threshold, measured in bit/s, that the media player uses to select a stream based on current network conditions. We recommend using the recommended value.
For more information about how to configure the parameters in the Basic Information, Video Parameters, Audio Parameters, and Advanced Parameters sections, see Transcoding template.
Click Add Template to create multiple video packaging templates with different bitrates, resolutions, and definitions.
After configuring the audio and video packaging template, click Save.
Transcode a video into streams of different bitrates.
In the ApsaraVideo VOD console, select Media Files > Audio/Video.
On the Audio/Video page, click Processing for the target video.
For Processing Type, select Use Transcoding Template Group. For Transcoding Template Group, select the transcoding template group that you created in Step 1 and click OK to start media processing.

View the result.
View the streams generated by adaptive bitrate packaging. The output includes two transcoded streams and one adaptive stream.
In the ApsaraVideo VOD console, select Media Files > Audio/Video. In the row that contains the video that you processed in the previous step, click Manage. Then, select the Video URL tab.

Preview the playback. In this example, the adaptive stream is used for playback.
On the Basic Configuration page of ApsaraVideo Player, enter the playback URL (the adaptive URL from the Video URL tab). On the Playback Preview page, you can preview the playback.
Procedure
Create a transcoding template group for adaptive bitrate streaming.
In the following sample code, a general transcoding template, a packing template for adaptive bitrate streaming, and a subtitle packaging template are configured. You can use the sample code based on your requirements.
NoteIf you require only packaging templates for adaptive bitrate streaming, you do not need to create general transcoding templates. You must delete all existing general transcoding templates. Otherwise, you may be charged for these general transcoding templates.
/** * Sample code */ public static void main(String[] args) throws ClientException { // An AccessKey pair of an Alibaba Cloud account has access permissions on all API operations. We recommend that you use an AccessKey pair of a RAM user to call API operations or perform routine O&M. // We recommend that you do not hardcode 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, the AccessKey pair is obtained from the environment variables. Before you run the sample code, configure the following 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 general transcoding template. transcodeTemplateList.add(buildNormalTranscodeConfig()); //Configure a packaging template for adaptive bitrate streaming. transcodeTemplateList.add(buildVideoPackageConfig()); //Configure subtitle packaging parameters. 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 template name. transcodeTemplate.put("TemplateName", "General 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 template name. 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: general transcoding template; VideoPackage: video packaging template; SubtitlePackage: subtitle packaging template> transcodeTemplate.put("Type","SubtitlePackage"); //The template name. 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 Content Delivery Network (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"); //The subtitle packaging settings. 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"); subtitleExtractConfig2.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 in which ApsaraVideo VOD is activated. String regionId = "cn-shanghai"; DefaultProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, accessKeySecret); DefaultAcsClient client = new DefaultAcsClient(profile); return client; }Transcode a video into streams of different bitrates.
public static void main(String[] args) { // Set regionId based on the service endpoint. For example, if the service is deployed in the China (Shanghai) region, set this parameter to cn-shanghai. String regionId = "cn-shanghai"; // An AccessKey pair of an Alibaba Cloud account has permissions to call all API operations. We recommend that you use a RAM user to call API operations or perform routine O&M. // We strongly recommend that you do not hard-code the AccessKey ID and AccessKey secret in your project code. Otherwise, the AccessKey pair may be leaked and threaten the security of all the resources in your account. // This example shows how to read the AccessKey pair from environment variables to implement API authentication. Before you run the sample code, configure the ALIBABA_CLOUD_ACCESS_KEY_ID and ALIBABA_CLOUD_ACCESS_KEY_SECRET environment variables. 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()); } } /** * Submit a transcoding job * Pass the video ID and 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); // Set the transcoding priority. The default priority is 6. A larger value indicates a higher priority. The value can be an integer from 1 to 10. request.setPriority("8"); JSONObject overrideParams = buildOverrideParams(); // The override parameter. request.setOverrideParams(overrideParams.toJSONString()); return client.getAcsResponse(request); } // The following code provides an example of how to build the override parameter for subtitle replacement during packaging. public static JSONObject buildOverrideParams() { JSONObject overrideParams = new JSONObject(); // The settings for subtitle replacement during packaging. JSONObject packageSubtitleSetting = new JSONObject(); JSONArray packageSubtitleList = new JSONArray(); JSONObject packageSubtitle = new JSONObject(); // The ID of the subtitle template in the packaging template group that you want to replace. packageSubtitle.put("SubtitlePackageTemplateId", "69fa6ee58****e8492c76168****"); // The Language parameter is used only to retrieve the subtitle file that you want to replace. The language itself is not replaced. You cannot replace a subtitle file for a language that does not exist. packageSubtitle.put("Language", "cn"); // The OSS URL of the subtitle file. HTTPS URLs are not supported. The subtitle file must be stored in the same region as the video. 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; }View the result.
View the streams generated by adaptive bitrate packaging. The output includes two transcoded streams and one adaptive stream.
In the ApsaraVideo VOD console, select Media Files > Audio/Video. In the row that contains the video that you processed in the previous step, click Manage. Then, select the Video URL tab.

Preview the playback. In this example, the adaptive stream is used for playback.
On the Basic Configuration page of ApsaraVideo Player, enter the playback URL (the adaptive URL from the Video URL tab). On the Playback Preview page, you can preview the playback.