本文提供了創建HLS標準加密工作流到播放加密視頻的一個完整步驟。
操作步驟
HLS標準加密架構,請參見HLS的加密與播放。
創建HLS加密工作流。
控制臺方式創建HLS加密工作流,請參見阿里云私有加密。
接口方式創建HLS加密工作流,DEMO代碼,請參見創建HLS標準加密工作流。
說明創建HLS標準工作流時,為了測試,參數
HLS_KEY_URI
值填http://127.0.0.1:8888。播放時,播放器會在該地址請求密鑰,媒體處理會在本地啟動服務,進行分發密鑰。上傳及加密視頻。
在控制臺的媒體庫中,上傳視頻,選擇工作流時,選擇剛剛創建的HLS標準加密工作流,上傳完成后,會自動觸發加密轉碼。待狀態為發布時,進行下一步。
開啟本地鑒權服務。
搭建一個本地HTTP服務,作為播放HLS標準加密視頻的鑒權服務,頒發及驗證MtsHlsUriToken令牌。
Java示例代碼依賴:
Base64解密示例:
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;
/**
* ***** 使用須知 ******
* 本demo Base64方式解密服務代碼示例
* demo中端口號為8888, 請注意與KeyUri解密服務端口保持一致
* 如果您需要額外的Token令牌校驗, 請參考kms方式解密服務的實現邏輯
*
* ***** 邏輯概述 ******
* 1、接收解密請求,獲取密文密鑰
* 2、將明文密鑰base64decode返回
*/
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)) {
// 此處的解密密鑰需要和加密時候的密鑰一致
byte[] key = "encryptionkey128".getBytes();
// 設置header
setHeader(httpExchange, key);
// 返回base64decode之后的密鑰
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();
//監聽端口8888,能同時接受30個請求
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;
/**
* ***** 使用須知 ******
* 本demo 為未開啟標準加密改寫時的kms方式解密服務代碼示例, 不包含MtsHlsUriToken的校驗邏輯
* 什么是標準加密改寫 以及 MtsHlsUriToken如何生成 參考 xxxxxxxxxxxx
* demo中端口號為8888, 請注意與KeyUri解密服務端口保持一致
*
* ***** 邏輯概述 ******
* 1、接收解密請求,獲取密文密鑰
* 2、調用KMS decrypt接口通過Ciphertext獲取明文密鑰
* 3、將明文密鑰base64decode返回
*/
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中取得密文密鑰
String ciphertext = getCiphertext(httpExchange);
System.out.println(ciphertext);
if (null == ciphertext)
return;
//從KMS中解密出來,并Base64 decode
byte[] key = decrypt(ciphertext);
//設置header
setHeader(httpExchange, key);
//返回密鑰
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 decode
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");
}
}
Python示例代碼依賴:
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):
#check MtsHlsUriToken, etc.
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__':
# Start a simple server, and loop forever
from BaseHTTPServer import HTTPServer
print "Starting server, use to stop"
server = HTTPServer(('127.0.0.1', 8888), AuthorizationHandler)
server.serve_forever()
可通過查詢媒體接口,獲取播放地址。請參見查詢媒體-使用媒體ID。
播放視頻。
借助一個在線播放器,測試HLS加密視頻的播放。更多詳情,請參見阿里云播放器用戶診斷工具。
將獲取的播放地址,如圖填入對話框中,單擊視頻播放。
說明通過瀏覽器DEBUG,可以看到播放器自動請求了鑒權服務器,獲取解密密鑰,并進行解密播放。
文檔內容是否對您有幫助?