All Products
Search
Document Center

ApsaraVideo Media Processing:Perform HLS packaging

Last Updated:Jun 03, 2026

HLS packaging generates a master playlist that combines multi-bitrate video, audio, and caption streams into adaptive bitrate content. Create an HLS packaging workflow, then call the AddMedia operation with the workflow ID to process videos.

Procedure

  1. Create an HLS packaging workflow. The following table describes the key objects. API details: Add a media workflow.

    Object

    Description

    Topology

    A business process defined as a directed acyclic graph (DAG).

    Activity

    Nodes that constitute the topology. The following table describes the HLS packaging activities.

    Dependencies

    Edges in the topology that define dependencies among activities.

    Table 1: HLS packaging activities

    Activity

    Description

    Dependency

    PackageConfig

    Specifies the output location of the master playlist.

    • Supported parent node: Start

    • Supported child nodes: SubtitleGroup, AudioGroup, and Transcode for video streams only

    SubtitleGroup

    Specifies the ID and language of each caption group.

    • Supported parent node: PackageConfig

    • Supported child node: Transcode for caption streams only

    AudioGroup

    Specifies the ID and language of each audio group.

    • Supported parent node: PackageConfig

    • Supported child node: Transcode for audio streams only

    Transcode

    Extracts video, audio, or caption streams.

    • Supported parent node: PackageConfig, SubtitleGroup, and AudioGroup.

    • Supported child node: GenerateMasterPlayList

    GenerateMasterPlayList

    Combines multi-bitrate video, audio, and caption streams into a master playlist.

    • Supported parent node: Transcode

    • Supported child node: Report

  2. Call the Add a media file operation to trigger the workflow:

    • Specify the HLS packaging workflow ID.

    • To override the caption file URL in the Transcode activity, use the OverrideParams parameter. Only WebVTT caption files are supported.

    • Set TriggerMode to NotInAuto.

Scenario

This example extracts two video streams, three audio streams, and two WebVTT caption streams from an MXF source file (MP4, FLV, M3U8, and TS formats are also supported), then generates a master playlist.

Specify the output location and name of the master playlist

  • Specify the OSS bucket for the master playlist.

  • Specify the location.

  • Specify the name.

    Sample code:

    {
    "Parameters" : {
    "Output" : "{\"Bucket\": \"processedmediafile\",\"Location\": \"oss-cn-hangzhou\",\"MasterPlayListName\": \"{MediaId}/{RunId}/hls/master.m3u8\"}"
    },
    "Type" : "PackageConfig"
    }

Specify an audio group

Specify the audio group ID. The two audio streams belong to the same group. Sample code:

{
"Parameters" : {
"GroupId" : "audios"
},
"Type" : "AudioGroup"
}
  • GroupId: the audio group ID. Set to audios in this example.

  • Type: AudioGroup.

Extract audio streams

  • To extract audio streams from the MXF source file, remove the video streams.

  • Output audio stream configurations:

    • Codec: AAC

    • Sample rate: 48000 Hz

    • Format: Stereo

    Sample code:

    
    {
    "Name" : "audio-extract-1",
    "Parameters" : {
    "Outputs" : "[{\"TemplateId\":\"S00000001-100020\",\"AudioStreamMap\":\"0:a:0\",\"Video\":{\"Remove\":\"true\"}}]",
    "ExtXMedia" : "{\"URI\": \"sd/audio-en.m3u8\",\"Name\": \"audio-en\",\"Language\": \"en-US\"}"
    }
    • TemplateId: the transcoding template ID. Template S00000001-100020 extracts an M3U8 audio file at 80 Kbit/s. Preset template details.

    • AudioStreamMap: the audio stream sequence number. Details: the "Output" section in Parameter details.

    • Remove: whether to remove video streams from the output. Parameter details.

    • ExtXMedia: the media playlist information. URI specifies the playlist name. Details: the "ExtXMedia" section in Parameter details.

    • Type: Transcode.

Extract video streams

To extract video streams from the MXF source file, remove the audio streams. Sample code:

{
"Name" : "video-extract",
"Parameters" : {
"Outputs" : "[{\"TemplateId\":\"1fe5393bdb7b2b883f0a0fc91e81****\",\"Audio\":{\"Remove\":\"true\"}}]",
"MultiBitrateVideoStream" : "{\"URI\": \"sd/video1.m3u8\"}"
},
"Type" : "Transcode"
}
  • This example uses a custom transcoding template (ID: 1fe5393bdb7b2b883f0a0fc91e81****). To create one, log on to the ApsaraVideo Media Processing (MPS) console, choose Template Management > Transcoding Template, and click Create Template on the Custom Template tab. Configure the following video parameters:

    • Codec: H.264

    • Resolution: 384 × 216

    • Profile: Main

    • Bitrate: 240 Kbit/s

    • FPS: 25

    • Pixel format: YUV420P Max GOP size: 1 Segment length: 4 seconds

    • Output format: M3U8

  • Remove: whether to remove audio streams from the output. Parameter details.

  • MultiBitrateVIdeoStream: the media playlist information. URI specifies the playlist name. Parameter details.

  • Type: Transcode.

Specify a caption group

Specify the caption group ID. The two caption streams belong to the same group. Sample code:

{
"Parameters" : {
"GroupId" : "subtitles"
},
"Type" : "SubtitleGroup"
}
  • GroupId: the caption group ID. Set to subtitles in this example.

  • Type: SubtitleGroup.

Extract caption streams

Upload WebVTT caption files to OSS. Sample code:


{
"Name" : "subtitle-extract-1",
"Parameters" : {
"WebVTTSubtitleURL" : "http://example-bucket-****.oss-cn-hangzhou.aliyun-inc.com/ShawshankRedemption****.vtt",
"ExtXMedia" : "{\"URI\": \"zh/subtitle1-cn.m3u8\",\"Name\": \"subtitle-cn\",\"Language\": \"cn\"}"
},
"Type" : "Transcode"
}
  • WebVTTSubtitleURL: the caption file URL. You can use the OverrideParams parameter in the AddMedia call to override this URL. Details: the OverrideParams parameter in the "Request parameters" section of the Add a media file topic.

  • ExtXMedia: the media playlist information. URI specifies the playlist name. Details: the "ExtXMedia" section in Parameter details.

  • Type: Transcode.

Generate a master playlist

Generate a master playlist from the extracted audio, video, and caption streams. Sample code:

{
"Parameters" : {
"MasterPlayList" : "{\"MultiBitrateVideoStreams\": [{\"RefActivityName\": \"video-extract\",\"ExtXStreamInfo\": {\"BandWidth\": \"1110000\",\"Audio\": \"audios\",\"Subtitles\": \"subtitles\"}}]}"
},
"Type" : "GenerateMasterPlayList"
}
  • MasterPlayList: the master playlist configuration. Details: the "MasterPlayList" section in Parameter details.

  • MultiBitrateVideoStreams: the multi-bitrate video streams. Details: the "MasterPlayList" section in Parameter details.

  • RefActivityName: the name of the video stream extraction activity.

  • ExtXStreamInfo: attributes of the multi-bitrate video streams. Audio specifies the audio group, and Subtitles specifies the caption group. Details: the "ExtXStreamInfo" section in Parameter details.

  • Type: GenerateMasterPlayList.

Complete topology sample code:

{
"Activities" : {
"package-node" : {
"Name" : "package-node",
"Parameters" : {
"Output" : "{\"Bucket\": \"processedmediafile\",\"Location\": \"oss-cn-hangzhou\",\"MasterPlayListName\": \"{MediaId}/{RunId}/hls/master.m3u8\"}"
},
"Type" : "PackageConfig"
},
"audioGroupNode" : {
"Name" : "audioGroupNode",
"Parameters" : {
"GroupId" : "audios"
},
"Type" : "AudioGroup"
},
"subtitleGroupNode" : {
"Name" : "subtitleGroupNode",
"Parameters" : {
"GroupId" : "subtitles"
},
"Type" : "SubtitleGroup"
},
"video-extract-1" : {
"Name" : "video-extract-1",
"Parameters" : {
"Outputs" : "[{\"TemplateId\":\"1fe5393bdb7b2b883f0a0fc91e81344a\",\"Audio\":{\"Remove\":\"true\"}}]",
"MultiBitrateVideoStream" : "{\"URI\": \"sd/video1.m3u8\"}"
},
"Type" : "Transcode"
},
"video-extract-2" : {
"Name" : "video-extract-1",
"Parameters" : {
"Outputs" : "[{\"TemplateId\":\"1fe5393bdb7b2b883f0a0fc91e81344b\",\"Audio\":{\"Remove\":\"true\"}}]",
"MultiBitrateVideoStream" : "{\"URI\": \"sd/video2.m3u8\"}"
},
"Type" : "Transcode"
},
"audio-extract-1" : {
"Name" : "audio-extract-1",
"Parameters" : {
"Outputs" : "[{\"TemplateId\":\"S00000001-100020\",\"AudioStreamMap\":\"0:a:0\"}]",
"ExtXMedia" : "{\"URI\": \"sd/audio-en-1.m3u8\",\"Name\": \"audio-en\",\"Language\": \"en-US\"}"
},
"Type" : "Transcode"
},
"audio-extract-2" : {
"Name" : "audio-extract-2",
"Parameters" : {
"Outputs" : "[{\"TemplateId\":\"S00000001-100020\",\"AudioStreamMap\":\"0:a:1\"}]",
"ExtXMedia" : "{\"URI\": \"sd/audio-cn.m3u8\",\"Name\": \"audio-cn\",\"Language\": \"cn\"}"
},
"Type" : "Transcode"
},
"audio-extract-3" : {
"Name" : "audio-extract-3",
"Parameters" : {
"Outputs" : "[{\"TemplateId\":\"S00000001-100020\",\"AudioStreamMap\":\"0:a:2\"}]",
"ExtXMedia" : "{\"URI\": \"sd/audio-de.m3u8\",\"Name\": \"audio-de\",\"Language\": \"de\"}"
},
"Type" : "Transcode"
},
"subtitle-extract-1" : {
"Name" : "subtitle-extract-1",
"Parameters" : {
"WebVTTSubtitleURL" : "http://example-bucket-****.oss-test.aliyun-inc.com/1****.vtt",
"ExtXMedia" : "{\"URI\": \"zh/subtitle1-cn.m3u8\",\"Name\": \"subtitle-cn\",\"Language\": \"cn\"}"
},
"Type" : "Transcode"
},
"subtitle-extract-2" : {
"Name" : "subtitle-extract-2",
"Parameters" : {
"WebVTTSubtitleURL" : "http://example-bucket-****.oss-cn-hangzhou.aliyun-inc.com/ShawshankRedemption****.vtt",
"ExtXMedia" : "{\"URI\": \"zh/subtitle1-en.m3u8\",\"Name\": \"subtitle-en\",\"Language\": \"en-US\"}"
},
"Type" : "Transcode"
},
"masterPlayListGenerate" : {
"Name" : "masterPlayListGenerate",
"Parameters" : {
"MasterPlayList" : "{\"MultiBitrateVideoStreams\": [{\"RefActivityName\": \"video-extract-1\",\"ExtXStreamInfo\": {\"BandWidth\": \"1110000\",\"Audio\": \"audios\",\"Subtitles\": \"subtitles\"}}, {\"RefActivityName\": \"video-extract-2\",\"ExtXStreamInfo\": {\"BandWidth\": \"5000000\",\"Audio\": \"audios\",\"Subtitles\":\"subtitles\"}}]}"
},
"Type" : "GenerateMasterPlayList"
},
"activityEnd" : {
"Name" : "activityEnd",
"Parameters" : {
"PublishType" : "Manual"
},
"Type" : "Report"
},
"activityStart" : {
"Name" : "activityStart",
"Parameters" : {
"PipelineId" : "900ededca77641ecbecd4f44cc3a2965",
"Role" : "AliyunMTSDefaultRole",
"InputFile" : "{\"Bucket\":\"videouploaded\",\"Location\":\"oss-cn-hangzhou\",\"ObjectPrefix\":\"uploaded/\"}"
},
"Type" : "Start"
}
},
"Dependencies" : {
"video-extract-1" : [ "masterPlayListGenerate" ],
"video-extract-2" : [ "masterPlayListGenerate" ],
"audio-extract-1" : [ "masterPlayListGenerate" ],
"audio-extract-2" : [ "masterPlayListGenerate" ],
"audio-extract-3" : [ "masterPlayListGenerate" ],
"subtitle-extract-1" : [ "masterPlayListGenerate" ],
"subtitle-extract-2" : [ "masterPlayListGenerate" ],
"package-node" : [ "video-extract-1", "video-extract-2","subtitleGroupNode", "audioGroupNode" ],
"audioGroupNode" : [ "audio-extract-1", "audio-extract-2","audio-extract-3"],
"subtitleGroupNode" : [ "subtitle-extract-1", "subtitle-extract-2" ],
"masterPlayListGenerate" : [ "activityEnd" ],
"activityEnd" : [ ],
"activityStart" : [ "package-node" ]
}
}

Sample code