HLS打包是指將多字幕、多音軌、多碼率視頻流生成一個Master Playlist文件的過程。通過HLS打包可以將視頻內容分割成一系列小的媒體文件(通常為.ts格式),每個文件包含一小段時長的視頻,并根據不同的碼率和分辨率生成多個版本,這一過程確保了流媒體服務可以根據用戶的網絡狀況自適應地提供流暢播放體驗。媒體處理中HLS打包分為兩個步驟:新建HLS打包工作流、調用AddMedia接口指定視頻及HLS打包工作流ID進行視頻的處理。
操作步驟
在創建工作流時,請關注以下對象。創建工作流API接口,請參見新增媒體工作流。
對象
描述
Topology
拓撲結構是指可自定義的業務處理流程,DAG。
Activity
活動是指組成拓撲結構的處理節點,在新建HLS打包工作流時要注意下文活動說明表中的活動。
Dependencies
依賴關系是拓撲結構中的邊,指明活動之間的依賴。
表 1. 活動說明表 活動
描述
前后依賴
指定HLS打包配置,設置Master Playlist文件輸出位置。
前置節點允許:Start。
后置節點允許:SubtitleGroup、AudioGroup、Transcode(僅視頻)。
指定字幕分組ID。
前置節點允許:PackageConfig。
后置節點允許:Transcode(僅字幕)。
指定音頻分組ID。
前置節點允許:PackageConfig。
后置節點允許:Transcode (僅音頻)。
用于提取視頻流、音頻流、字幕流。
前置節點允許:PackageConfig、SubtitleGroup、AudioGroup。
后置節點允許:GenerateMasterPlayList。
HLS打包生成活動,指定視頻多碼率配置,指定音頻,字幕分組。
前置節點允許:Transcode。
后置節點允許:Report。
調用 新增媒體接口,需要注意以下幾點:
指定媒體工作流ID。
若存在字幕提取,可以設置字幕文件地址覆蓋Transcode活動中的參數WebVTTSubtitleURL,只支持WebVTT的字幕文件。
工作流觸發模式設置為:NotInAuto。
場景
源文件mxf格式(也可其它格式如mp4、flv、m3u8(ts)),從源文件中提取3路音軌,提取2路視頻流。提取2路WebVTT字幕,最終組合打包成一個Master Playlist:
設置HLS打包輸出Master Playlist的位置及名稱
設置Bucket。
設置Location。
設置Master Playlist的名稱。
示例代碼如下:
{ "Parameters" : { "Output" : "{\"Bucket\": \"processedmediafile\",\"Location\": \"oss-cn-hangzhou\",\"MasterPlayListName\": \"{MediaId}/{RunId}/hls/master.m3u8\"}" }, "Type" : "PackageConfig" }
Output設置Master Playlist的存儲位置及名稱,請參見PackageConfig活動。
Type指定活動類型為PackageConfig。
音頻分組
設置音頻分組ID,兩個音頻流同屬于一個音頻分組。示例代碼如下:
{
"Parameters" : {
"GroupId" : "audios"
},
"Type" : "AudioGroup"
}
GroupId:指定音頻分組ID為audios。
Type:類型為AudioGroup活動。
提取音軌
從mxf源文件中提取音頻流,需要去掉視頻流。
輸出的音頻流參數:
Codec:AAC
SampleRate:48000 Hz
Format:Stereo
示例代碼如下:
{ "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:S00000001-100020表示音頻輸出為m3u8(ts),預置模板內設置的音頻碼率為80kbps。更多信息,請參見預置模板詳情。
AudioStreamMap:音頻流選擇字。更多信息,請參見Output詳情。
Remove:在輸出中移除掉視頻流。更多信息,請參見參數詳情。
ExtXMedia:定義Media Playlist,URI指定Media Playlist的名稱。更多信息,請參見ExtXMedia詳情。
Type設置為Transcode,即轉碼活動。
提取視頻
從mxf源文件中提取視頻流,需要去掉音頻流。示例代碼如下:
{
"Name" : "video-extract",
"Parameters" : {
"Outputs" : "[{\"TemplateId\":\"1fe5393bdb7b2b883f0a0fc91e81****\",\"Audio\":{\"Remove\":\"true\"}}]",
"MultiBitrateVideoStream" : "{\"URI\": \"sd/video1.m3u8\"}"
},
"Type" : "Transcode"
}
自定義轉碼模板ID:1fe5393bdb7b2b883f0a0fc91e81****,登錄媒體處理控制臺,在左側導航欄選擇 中創建自定義模板,設置視頻轉碼參數:
Codec:H.264
Resolution:384x216
Profile:Main
Bitrate:240 Kbps
Fps:25
PixelFormat:YUV420P Max GOP size:1 segment length (4 seconds)
輸出格式:m3u8
在輸出中移除掉音頻流,請參見參數詳情。
參數詳情定義Master Playlist中的多碼率視頻流,URI指定Media Playlist的名稱。
Type設置為Transcode,即轉碼活動。
字幕分組
設置字幕分組ID,兩個字幕流同屬于一個字幕分組。示例代碼如下:
{
"Parameters" : {
"GroupId" : "subtitles"
},
"Type" : "SubtitleGroup"
}
GroupId:指定音頻分組ID為subtitles。
Type:類型為SubtitleGroup活動。
提取字幕
上傳WebVtt格式的字幕到OSS中。示例代碼如下:
{
"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"
}
Transcode活動中的
WebVTTSubtitleURL
參數是指定字幕地址,字幕地址在調用 AddMedia時可以被動態覆蓋,見參數OverrideParams。ExtXMedia定義Media Playlist,URI指定Media Playlist的名稱。
Type設置為Transcode,即轉碼活動。
輸出Master Playlist
通過提取音頻、視頻、字幕,將所有提取轉換后的資源打包成一個Master Playlist。示例代碼如下:
{
"Parameters" : {
"MasterPlayList" : "{\"MultiBitrateVideoStreams\": [{\"RefActivityName\": \"video-extract\",\"ExtXStreamInfo\": {\"BandWidth\": \"1110000\",\"Audio\": \"audios\",\"Subtitles\": \"subtitles\"}}]}"
},
"Type" : "GenerateMasterPlayList"
}
MasterPlayList:定義Master Playlist。更多信息,請參見MasterPlayList詳情。
MultiBitrateVideoStreams:多碼率視頻流數組。更多信息,請參見MasterPlayList詳情。
RefActivityName指定提取視頻流的活動名稱。
ExtXStreamInfo:定義多碼率視頻流的屬性,Audio指定音頻分組,Subtitles指定字幕分組。更多信息,請參見ExtXStreamInfo詳情。
Type設置為GenerateMasterPlayList,即生成Master Playlist活動。
拓撲示意圖:
完整的場景示例使用拓撲結構,示例代碼如下:
{
"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" ]
}
}