すべてのプロダクト
Search
ドキュメントセンター

ApsaraVideo Media Processing:HLS暗号化の実行と暗号化ビデオの再生

最終更新日:Jan 12, 2025

このトピックでは、HTTP-Live-Streaming(HLS)暗号化を使用してビデオを暗号化し、暗号化されたビデオを再生する手順について説明します。

手順

  1. HLS暗号化のワークフローを作成します。

    HLS暗号化のワークフローを作成するためのサンプルコードについては、HLS暗号化のワークフローの作成をご参照ください。

    説明

    HLS暗号化のワークフローを作成する際に、テスト用に http://127.0.0.1:8888HLS_KEY_URI パラメーターの値として http://127.0.0.1:8888 を入力します。暗号化されたビデオを再生すると、プレーヤーはこの URL にリクエストを送信して復号キーを取得します。ApsaraVideo Media Processing(MPS)は、キーを配布するためのローカルサービスを開始します。

  2. ビデオをアップロードして暗号化します。

    MPSコンソールにログインします。左側のナビゲーションペインで、[ビデオのアップロード] をクリックします。[ビデオのアップロード] ページで、[ビデオの追加] をクリックします。[ビデオの追加とワークフローの開始] ダイアログボックスで、[ワークフロー] ドロップダウンリストから作成したHLS暗号化のワークフローを選択します。ビデオがアップロードされると、MPSは自動的にワークフローをトリガーします。左側のナビゲーションペインで、[メディアリスト] をクリックします。アップロードしたビデオが[公開済み] 状態になったら、次の手順に進みます。

  3. ローカル認証サービスを構築します。

    HLS暗号化ビデオを再生するには、MtsHlsUriTokenパラメーターを生成および検証するための認証サービスとしてローカル HTTP サービスを構築します。

    Java 用 SDK で必要な依存関係:

    Java SDK Core

    Java SDK KMS

    Base64 アルゴリズムを使用した復号のサンプルコード:

  4. import com.sun.net.httpserver.*;
    import com.sun.net.httpserver.spi.HttpServerProvider;
    
    import java.io.IOException;
    import java.io.OutputStream;
    import java.net.HttpURLConnection;
    import java.net.InetSocketAddress;
    
    /**
     * *****   使用方法に関する注意事項     ******
     * このサンプルコードは、Base64 アルゴリズムを使用してデータキー(DK)をデコードします。
     * サンプルコードのポート番号は 8888 です。この番号がキーの Uniform Resource Identifier(URI)の番号と同じであることを確認してください。
     * 追加のトークン検証が必要な場合は、Key Management Service(KMS)を使用した復号化のサンプルコードを参照してください。
     *
     * ***** コードロジック ******
     * 1. 復号化リクエストを受信し、Enveloped Data Key(EDK)を取得します。
     * 2. Base64 アルゴリズムを使用して DK をデコードし、デコードされた DK を返します。
     */
    public class Base64DecryptServer {
    
        public static void main(String[] args) throws IOException {
            Base64DecryptServer server = new Base64DecryptServer();
            server.startService();
        }
    
        public class Base64DecryptHandler implements HttpHandler {
            /**
             * 復号化リクエストを処理します。
             * @param httpExchange
             * @throws IOException
             */
            public void handle(HttpExchange httpExchange) throws IOException {
                String requestMethod = httpExchange.getRequestMethod();
                if ("GET".equalsIgnoreCase(requestMethod)) {
                    // The decryption key must be the same as the encryption key.
                    byte[] key = "encryptionkey128".getBytes();
                    // Configure the headers.
                    setHeader(httpExchange, key);
                    // Return the DK that is decoded by using the Base64 algorithm.
                    OutputStream responseBody = httpExchange.getResponseBody();
                    System.out.println(new String(key));
                    responseBody.write(key);
                    responseBody.close();
                }
            }
            private void setHeader(HttpExchange httpExchange, byte[] key) throws IOException {
                Headers responseHeaders = httpExchange.getResponseHeaders();
                responseHeaders.set("Access-Control-Allow-Origin", "*");
                httpExchange.sendResponseHeaders(HttpURLConnection.HTTP_OK, key.length);
            }
        }
        /**
         * サービスを開始します。
         * @throws IOException
         */
        private void startService() throws IOException {
            HttpServerProvider provider = HttpServerProvider.provider();
            // Configure a listener on port 8888, which can accept 30 requests at a time.
            HttpServer httpserver = provider.createHttpServer(new InetSocketAddress(8888), 30);
            httpserver.createContext("/", new Base64DecryptHandler());
            httpserver.start();
            System.out.println("base64 hls decrypt server started");
        }
    
    }

KMS を使用した復号化のサンプルコード:

import com.aliyun.mps.sdk.utils.InitClient;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.ProtocolType;
import com.aliyuncs.kms.model.v20160120.DecryptRequest;
import com.aliyuncs.kms.model.v20160120.DecryptResponse;
import com.sun.net.httpserver.*;
import com.sun.net.httpserver.spi.HttpServerProvider;
import org.apache.commons.codec.binary.Base64;

import java.io.IOException;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.URI;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * *****   使用方法に関する注意事項     ******
 * このサンプルコードは、M3U8 の暗号化およびリライト機能が無効になっている KMS を使用して復号化サービスを構築します。MtsHlsUriToken パラメーターは検証されません。
 * M3U8 の暗号化およびリライト機能と MtsHlsUriToken パラメーターの生成方法の詳細については、「xxxxxxxxxxxx」をご参照ください。
 * サンプルコードのポート番号は 8888 です。この番号がキー URI の番号と同じであることを確認してください。
 *
 * ***** コードロジック ******
 * 1. 復号化リクエストを受信し、EDK を取得します。
 * 2. KMS の Decrypt オペレーションを呼び出して、DK を取得します。
 * 3. Base64 アルゴリズムを使用して DK をデコードし、デコードされた DK を返します。
 */
public class HlsDecryptServerNoToken {

    private static DefaultAcsClient client;
    static {
        try{
            client = InitClient.initMpsClient();
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws IOException {
        HlsDecryptServerNoToken server = new HlsDecryptServerNoToken();
        server.startService();
    }

    public class HlsDecryptHandler implements HttpHandler {
        public void handle(HttpExchange httpExchange) throws IOException {
            String requestMethod = httpExchange.getRequestMethod();
            if(requestMethod.equalsIgnoreCase("GET")){
                // ビデオ URL から EDK を取得します。
                String ciphertext = getCiphertext(httpExchange);
                System.out.println(ciphertext);
                if (null == ciphertext)
                    return;
                // KMS から取得した DK を復号化し、Base64 アルゴリズムを使用して DK をデコードします。
                byte[] key = decrypt(ciphertext);
                // ヘッダーを設定します。
                setHeader(httpExchange, key);
                // デコードされた DK を返します。
                OutputStream responseBody = httpExchange.getResponseBody();
                responseBody.write(key);
                responseBody.close();
            }
        }

        private void setHeader(HttpExchange httpExchange, byte[] key) throws IOException {
            Headers responseHeaders = httpExchange.getResponseHeaders();
            responseHeaders.set("Access-Control-Allow-Origin", "*");
            httpExchange.sendResponseHeaders(HttpURLConnection.HTTP_OK, key.length);
        }

        private byte[] decrypt(String ciphertext) {
            DecryptRequest request = new DecryptRequest();
            request.setCiphertextBlob(ciphertext);
            request.setProtocol(ProtocolType.HTTPS);
            try {
                DecryptResponse response = client.getAcsResponse(request);
                String plaintext = response.getPlaintext();
                // 注: Base64 アルゴリズムを使用して DK をデコードする必要があります。
                return Base64.decodeBase64(plaintext);
            } catch (ClientException e) {
                e.printStackTrace();
                return null;
            }
        }
        private String getCiphertext(HttpExchange httpExchange) {
            URI uri = httpExchange.getRequestURI();
            String queryString = uri.getQuery();
            String pattern = "Ciphertext=(\\w*)";
            Pattern r = Pattern.compile(pattern);
            Matcher m = r.matcher(queryString);
            if (m.find())
                return m.group(1);
            else {
                System.out.println("Not Found Ciphertext");
                return null;
            }
        }
    }

    /**
     * サービスを開始します。
     *
     * @throws IOException
     */
    private void startService() throws IOException {
        HttpServerProvider provider = HttpServerProvider.provider();
        // ポート 8888 で、一度に 30 件のリクエストを受け入れることができるリスナーを設定します。ビジネス要件に基づいてポートを変更できます。
        HttpServer httpserver = provider.createHttpServer(new InetSocketAddress(8888), 30);
        httpserver.createContext("/", new HlsDecryptHandler());
        httpserver.start();
        System.out.println("no token hls decrypt server started");
    }

}

  1. Python 用 SDK で必要な依存関係:

pip install aliyun-python-sdk-core

pip install aliyun-python-sdk-kms

pip install aliyun-python-sdk-mts

# -*- coding: UTF-8 -*- 
from BaseHTTPServer import BaseHTTPRequestHandler
from aliyunsdkcore.client import AcsClient
from aliyunsdkkms.request.v20160120 import DecryptRequest
import cgi
import json
import base64
import urlparse
client = AcsClient("","","");
class AuthorizationHandler(BaseHTTPRequestHandler):
def do_GET(self):
self.check()
self.set_header()
cipertext = self.get_cihpertext()
plaintext = self.decrypt_cihpertext(cipertext)
print plaintext
key = base64.b64decode(plaintext)
print key
self.wfile.write(key)
def do_POST(self):
pass
def check(self):
# MtsHlsUriTokenなどを確認します。
pass
def set_header(self):
self.send_response(200)
# cors
self.send_header('Access-Control-Allow-Origin', '*')
self.end_headers()
def get_cihpertext(self):
path = urlparse.urlparse(self.path)
query = urlparse.parse_qs(path.query)
return query.get('Ciphertext')[0]
def decrypt_cihpertext(self, cipertext):
request = DecryptRequest.DecryptRequest()
request.set_CiphertextBlob(cipertext)
response = client.do_action_with_exception(request)
jsonResp = json.loads(response)
return jsonResp["Plaintext"]
if __name__ == '__main__':
# シンプルなサーバーを起動し、永久にループします。
from BaseHTTPServer import HTTPServer
print "Starting server, use  to stop"
server = HTTPServer(('127.0.0.1', 8888), AuthorizationHandler)
server.serve_forever()
  1. MPS の QueryMediaList オペレーションを呼び出して、ビデオのストリーミング URL をクエリします。詳細については、「QueryMediaList」をご参照ください。

  2. 暗号化されたビデオを再生します。

    オンラインプレーヤーを使用して、HLS 暗号化によって暗号化されたビデオの再生をテストできます。詳細については、「ApsaraVideo Player 診断ツール」をご参照ください。

    ApsaraVideo Player 診断ツールを使用する場合は、[Source] フィールドにビデオのストリーミング URL を入力し、[再生] をクリックします。

    説明

    ブラウザーのデバッグページで、プレーヤーが認証サーバーにリクエストを送信し、復号化キーを取得して、ビデオを復号化して再生することがわかります。