Create an HLS encryption workflow

Updated at:

Create an HLS standard encryption workflow using the Java SDK for ApsaraVideo Media Processing (MPS).

Overview

This sample calls the API described in Add a media workflow to create an HLS encryption workflow.

Dependencies

  • MPS SDK. Installation.

  • Other dependencies.

    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.68.noneautotype</version>
    </dependency>

Sample code

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.tea.TeaException;
/**
 * *****   Notes     ******
 * This demo shows how to create an HLS encryption workflow. If this is your first time using HLS encryption, run this demo and execute the workflow once to complete the system configuration.
 * The workflow data structure is complex. Ensure the accuracy of parameters when you make changes. For more information about the workflow data structure, see https://help.aliyun.com/document_detail/602860.html
 * KeyUri is your decryption service endpoint. Ensure its availability. Otherwise, decryption and playback will fail.
 * For information about how to use HLS encryption, see: xxxxxxxxxxxx
 */
public class MediaHlsWorkflow {

    // The MPS queue ID. You can view the ID in the console by choosing Global Settings > MPS Queues.
    final static String PIPELINE_ID = "bee7a5b9e*******e40a0cbf";
    // The template ID. For more information about preset templates, see https://help.aliyun.com/document_detail/29256.html
    final static String TEMPLATE_ID = "S00000001-100020";
    final static String OSS_LOCATION = "oss-cn-shanghai";
    // The name of the input bucket that is attached in the console.
    final static String INPUT_BUCKET = "<your bucket name>";
    // The trigger path. It must end with a forward slash (/).
    final static String INPUT_PATH = "mps-test/demo/";
    // The name of the output bucket that is attached in the console.
    final static String OUTPUT_BUCKET = "<your bucket name>";
    // The encryption type. The value is fixed to hls-aes-128.
    final static String ENCRYPTION_TYPE = "hls-aes-128";
    // The decryption service endpoint. Example: http://example.aliyundoc.com.
    final static String HLS_KEY_URI = "http://127.0.0.1:8888";
    final static String ACT_START = "Act-Start";
    final static String ACT_ENCRYPTION = "Act-HLS-Encryption";
    final static String ACT_REPORT = "Act-Report";

    /**
     * description :
     * <p>Use an AccessKey pair to initialize the client.</p>
     * @return Client
     *
     * @throws Exception
     */
    public static com.aliyun.mts20140618.Client createClient() throws Exception {

        com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config()
                // Required. Make sure that the ALIBABA_CLOUD_ACCESS_KEY_ID environment variable is set.
                .setAccessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"))
                // Required. Make sure that the ALIBABA_CLOUD_ACCESS_KEY_SECRET environment variable is set.
                .setAccessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
        config.endpoint = "mts.cn-shanghai.aliyuncs.com";
        return new com.aliyun.mts20140618.Client(config);
    }

    /**
     * Create an HLS encryption workflow.
     * @return
     * @throws Exception
     */
    public static void addMediaHlsWorkflow() throws Exception {
        com.aliyun.mts20140618.Client client = MediaHlsWorkflow.createClient();
        com.aliyun.mts20140618.models.AddMediaWorkflowRequest addMediaWorkflowRequest = new com.aliyun.mts20140618.models.AddMediaWorkflowRequest()
                // The workflow name.
                .setName("HLS Encryption Workflow")
                // The job output configurations.
                .setTopology(createWorkflow().toJSONString());

        com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
        try {
            // If you copy the code to run, print the API return value.
            client.addMediaWorkflowWithOptions(addMediaWorkflowRequest, runtime);
        } catch (TeaException error) {
            // This is for demonstration purposes only. Handle exceptions with care. Do not ignore exceptions in your projects.
            // The error message.
            System.out.println(error.getMessage());
            // The diagnosis address.
            System.out.println(error.getData().get("Recommend"));
            com.aliyun.teautil.Common.assertAsString(error.message);
        } catch (Exception _error) {
            TeaException error = new TeaException(_error.getMessage(), _error);
            // This is for demonstration purposes only. Handle exceptions with care. Do not ignore exceptions in your projects.
            // The error message.
            System.out.println(error.getMessage());
            // The diagnosis address.
            System.out.println(error.getData().get("Recommend"));
            com.aliyun.teautil.Common.assertAsString(error.message);
        }
    }

    /**
     * Create the workflow data structure.
     * @return
     */
    private static JSONObject createWorkflow() {
        JSONObject workflow = new JSONObject();
        JSONObject activities = new JSONObject();
        activities.put(ACT_START, createStartActivity());
        activities.put(ACT_ENCRYPTION, createTrancodeActivity());
        activities.put(ACT_REPORT, createReportActivity());
        workflow.put("Activities", activities);
        workflow.put("Dependencies", createDependencies());
        return workflow;
    }

    /**
     * Add a start node to the workflow.
     * @return
     */
    private static JSONObject createStartActivity() {
        JSONObject startActivity = new JSONObject();
        startActivity.put("Name", ACT_START);
        startActivity.put("Type", "Start");
        startActivity.put("Parameters", buildStartParameters());
        return startActivity;
    }

    /**
     * Add input configurations to the workflow.
     * @return
     */
    private static JSONObject buildStartParameters() {
        JSONObject parameters = new JSONObject();
        parameters.put("PipelineId", PIPELINE_ID);
        // The input bucket structure.
        JSONObject inputFile = new JSONObject();
        inputFile.put("Bucket", INPUT_BUCKET);
        inputFile.put("Location", OSS_LOCATION);
        inputFile.put("ObjectPrefix", INPUT_PATH);

        parameters.put("InputFile", inputFile);
        return parameters;
    }

    /**
     * Add a transcoding node to the workflow.
     * @return
     */
    private static JSONObject createTrancodeActivity() {
        JSONObject transcodeActivity = new JSONObject();
        transcodeActivity.put("Name", ACT_ENCRYPTION);
        transcodeActivity.put("Type", "Transcode");

        JSONObject transcodeParamters = new JSONObject();
        transcodeParamters.put("OutputBucket", OUTPUT_BUCKET);
        transcodeParamters.put("OutputLocation", OSS_LOCATION);
        transcodeParamters.put("Outputs", buildOutputsConfig());

        transcodeActivity.put("Parameters", transcodeParamters);
        return transcodeActivity;
    }

    /**
     * Add output configurations to the workflow.
     * @return
     */
    private  static JSONArray buildOutputsConfig() {
        JSONArray outputs = new JSONArray();
        JSONObject output = new JSONObject();
        output.put("ObjectRegex", ACT_ENCRYPTION + "/{RunId}/{FileName}");
        output.put("TemplateId", TEMPLATE_ID);
        output.put("Encryption", buildEncryption());
        outputs.add(output);
        return outputs;
    }

    /**
     * The encryption configuration.
     * @return
     */
    private static JSONObject buildEncryption() {
        JSONObject encryption = new JSONObject();
        encryption.put("Type", ENCRYPTION_TYPE);
        encryption.put("KeyUri", HLS_KEY_URI);
        return encryption;
    }

    /**
     * Add the Report node configuration.
     * @return
     */
    private static JSONObject createReportActivity() {
        JSONObject reportActivity = new JSONObject();
        reportActivity.put("Name", ACT_REPORT);
        JSONObject parameters = new JSONObject();
        parameters.put("PublishType","Auto");
        reportActivity.put("Parameters", parameters);
        reportActivity.put("Type", "Report");
        return  reportActivity;
    }

    /**
     * Add workflow dependencies.
     * Dependencies are the edges in the topology that specify the dependencies between activities.
     * @return
     */
    private static JSONObject createDependencies() {
        JSONObject dependencies = new JSONObject();
        JSONArray subActivityOfStart = new JSONArray();
        subActivityOfStart.add(ACT_ENCRYPTION);
        dependencies.put(ACT_START, subActivityOfStart);
        JSONArray subActivityOfTranscode = new JSONArray();
        subActivityOfTranscode.add(ACT_REPORT);
        dependencies.put(ACT_ENCRYPTION, subActivityOfTranscode);
        dependencies.put(ACT_REPORT, new JSONArray());
        return dependencies;
    }
}