本文介绍如何创建Python版Widevine工作流。

使用限制

  • 使用Widevine前,请联系您的商务经理,开通服务并获取产品报价。
  • 播放视频需集成Web播放器。

安装

  • MPS SDK安装,参见 安装
  • 创建三个容器格式为mpd的三路不同分辨率的转码模版,参见 创建模版

示例代码

# -*- coding: UTF-8 -*-
import json
from aliyunsdkmts.request.v20140618 import AddMediaWorkflowRequest
from aliyunsdkcore import client

REGION_ID = "cn-shanghai";
ACCESS_KEY_ID = '<idid>'
ACCESS_KEY_SECRET = '<secret>'
ENCRYPTION_TYPE = "Widevine";
PIPELINE_ID = "<pipelineid>";
OSS_LOCATION = "oss-" + REGION_ID;
INPUT_BUCKET = "<inputbucket>"; #输入bucket
INPUT_PATH = "<inputpath>"; #如 "DRM/WidevineEncryption",视频将要上将要上传到此目录
OUTPUT_BUCKET = "<ouputbucket>"; #输出bucket
OUTPUT_PATH = "<outputpaht>"; #输出路径
MPD_360P_TEMPLATE = "<MPD模版ID>";
MPD_480P_TEMPLATE = "<MPD模版ID>";
MPD_720P_TEMPLATE = "<MPD模版ID>";

WORKFLOW_TEMPLATE = '''
{
	"Activities": {
		"video-group": {
			"Name": "video-group",
			"Parameters": {
				"AdaptationSet": "{\\"Group\\":\\"VideoGroup\\"}"
			},
			"Type": "VideoGroup"
		},
		"act-start": {
			"Name": "act-start",
			"Parameters": {
				"PipelineId": "PIPELINE_ID",
				"InputFile": "{\\"Bucket\\":\\"INPUT_BUCKET\\",\\"Location\\":\\"OSS_LOCATION\\",\\"ObjectPrefix\\":\\"INPUT_PATH/\\"}"
			},
			"Type": "Start"
		},
		"audio-cn-group": {
			"Name": "audio-cn-group",
			"Parameters": {
				"AdaptationSet": "{\\"Lang\\":\\"chinese\\", \\"Group\\":\\"AudioGroupChinese\\"}"
			},
			"Type": "AudioGroup"
		},
		"audioCNTransNode": {
			"Name": "audioCNTransNode",
			"Parameters": {
				"Outputs": "[{\\"TemplateId\\":\\"MPD_360P_TEMPLATE\\",\\"AudioStreamMap\\":\\"0:a:0\\",\\"Video\\":{\\"Remove\\":\\"true\\"},\\"Encryption\\":{\\"Type\\":\\"ENCRYPTION_TYPE\\"}}]",
				"Representation": "{\\"Id\\":\\"chinese128k\\", \\"URI\\":\\"audiocn/cn-abc.mpd\\"}"
			},
			"Type": "Transcode"
		},
		"act-package": {
			"Name": "act-package",
			"Parameters": {
				"Output": "{\\"Bucket\\": \\"OUTPUT_BUCKET\\",\\"Location\\": \\"OSS_LOCATION\\",\\"MasterPlayListName\\": \\"INPUT_PATH/{MediaId}/{RunId}/master.mpd\\"}",
				"Protocol": "dash"
			},
			"Type": "PackageConfig"
		},
		"videoTransLD": {
			"Name": "videoTransLD",
			"Parameters": {
				"Outputs": "[{\\"TemplateId\\":\\"MPD_360P_TEMPLATE\\",\\"Audio\\":{\\"Remove\\":\\"true\\"},\\"Encryption\\":{\\"Type\\":\\"ENCRYPTION_TYPE\\"}}]",
				"Representation": "{\\"Id\\":\\"360p\\", \\"URI\\":\\"videoLD/xx.mpd\\"}"
			},
			"Type": "Transcode"
		},
		"act-report": {
			"Name": "act-report",
			"Parameters": {
				"PublishType": "Auto"
			},
			"Type": "Report"
		},
		"generateMasterPlayListAct": {
			"Name": "generateMasterPlayListAct",
			"Parameters": {},
			"Type": "GenerateMasterPlayList"
		},
		"videoTransSD": {
			"Name": "videoTransSD",
			"Parameters": {
				"Outputs": "[{\\"TemplateId\\":\\"MPD_480P_TEMPLATE\\",\\"Audio\\":{\\"Remove\\":\\"true\\"}, \\"Encryption\\":{\\"Type\\":\\"ENCRYPTION_TYPE\\"}}]",
				"Representation": "{\\"Id\\":\\"480p\\", \\"URI\\":\\"videoSD/xx.mpd\\"}"
			},
			"Type": "Transcode"
		},
		"videoTransHD": {
			"Name": "videoTransHD",
			"Parameters": {
				"Outputs": "[{\\"TemplateId\\":\\"MPD_720P_TEMPLATE\\",\\"Audio\\":{\\"Remove\\":\\"true\\"},\\"Encryption\\":{\\"Type\\":\\"ENCRYPTION_TYPE\\"}}]",
				"Representation": "{\\"Id\\":\\"720p\\", \\"URI\\":\\"videoHD/xx.mpd\\"}"
			},
			"Type": "Transcode"
		}
	},
	"Dependencies": {
		"video-group": ["videoTransLD", "videoTransSD", "videoTransHD"],
		"act-start": ["act-package"],
		"audio-cn-group": ["audioCNTransNode"],
		"audioCNTransNode": ["generateMasterPlayListAct"],
		"act-package": ["audio-cn-group", "video-group"],
		"videoTransLD": ["generateMasterPlayListAct"],
		"act-report": [],
		"generateMasterPlayListAct": ["act-report"],
		"videoTransSD": ["generateMasterPlayListAct"],
		"videoTransHD": ["generateMasterPlayListAct"]
	}
}
'''


def addMediaWorkflow():
    global client
    client = client.AcsClient(ACCESS_KEY_ID, ACCESS_KEY_SECRET, REGION_ID)
    request = AddMediaWorkflowRequest.AddMediaWorkflowRequest()
    request.set_Topology(buildWorkflowTopology())
    print request.get_Topology();
    request.set_Name("Widevine加密工作流py")
    response = client.do_action_with_exception(request)
    print json.loads(response)

def buildWorkflowTopology():
    return WORKFLOW_TEMPLATE.replace("PIPELINE_ID", PIPELINE_ID).replace("INPUT_BUCKET", INPUT_BUCKET).replace("OSS_LOCATION", OSS_LOCATION).replace("INPUT_PATH", INPUT_PATH).replace("OUTPUT_BUCKET", OUTPUT_BUCKET).replace("OUTPUT_PATH", OUTPUT_PATH).replace("ENCRYPTION_TYPE", ENCRYPTION_TYPE).replace("MPD_360P_TEMPLATE", MPD_360P_TEMPLATE).replace("MPD_480P_TEMPLATE", MPD_480P_TEMPLATE).replace("MPD_720P_TEMPLATE", MPD_720P_TEMPLATE);

if __name__ == "__main__":
    addMediaWorkflow()