阿里雲視頻播放防盜鏈生成及獲取阿里雲視頻是否正在播放

寫這篇文檔主要是由於公司採用阿里雲的視頻播放進行APP集成,在阿里雲官方的文檔中文檔介紹不夠全,不少東西須要在網上查到,下面來介紹下用java實現阿里雲阿里雲防盜鏈生成及判斷阿里雲視頻是否正在播放,來刷新數據庫表中播放狀態
阿里雲官方文檔介紹播放鑑權URL爲:http://DomainName/Filename?au...,後端代碼主要生成auth_key來提供給app實現鑑權java

timestamp:失效時間,整形正數,固定長度 10,1970 年 1 月 1 日以來的秒數。用來控制失效時間,10 位整數,有效時間 1800s,這裏是阿里雲官方文檔提供的失效時間,具體在阿里雲直播上進行配置,(咱們採起timestamp在生成主要是經過當前時間+阿里雲配置的超時時間相加得出timestamp)
rand:阿里雲官方默認爲0
uid: 阿里雲官方默認爲0
md5hash:sstring = "URI-Timestamp-rand-uid-PrivateKey"(URI是用戶的請求對象相對地址,不包含參數,如:/Filename),/video/standard-1444435200-0-0-addfvadeda生成防盜鏈代碼
privateKey須要在阿里雲進行配置

下面直接上代碼算法

public class LiveAuthkeyUtils {
static String rand="0";
static String uid="0";
public static void main(String[] args) {
    System.out.println(getPushUrl("/pwgl/cqStream09"));
    System.out.println(getPlayUrl("/pwgl/cqStream09"));
}
//根據阿里雲規則生成auth_key做爲防盜鏈,直播
public static String getPushUrl(String url){
    Date date=new Date();
    long timestampdata=date.getTime()+ApplicationConfig.alimedia_timestamp;
    String hashValue =url+"-"+timestampdata+"-"+rand+"-"+uid+"-"+ApplicationConfig.privateKey;
    System.out.println(hashValue);
    url="auth_key="+timestampdata+"-"+rand+"-"+uid+"-"+Md5Util.compute(hashValue);
    return url;
}
//根據阿里雲規則生成auth_key做爲防盜鏈,播放
public static String getPlayUrl(String url){
    Date date=new Date();
    long timestampdata=date.getTime()+ApplicationConfig.alimedia_timestamp;
    String hashValue =url+"-"+timestampdata+"-"+rand+"-"+uid+"-"+ApplicationConfig.privateKey;
    String auth_key="auth_key="+timestampdata+"-"+rand+"-"+uid+"-"+Md5Util.compute(hashValue);
    return auth_key;
}
}

阿里雲查看是否正在推流及禁止直播推流代碼,調用steamIsOnline方法傳入參數streamName則能夠查看是否正在推流傳入參數爲(上面"cqStream09")數據庫

public class LiveUtils {
/**
 * 日誌對象
 */
protected Logger logger = LoggerFactory.getLogger(getClass());
// 簽名算法版本,目前版本是1.0  
private static final String SIGNATURE_VERSION = "1.0";  
// 簽名方式,目前支持 HMAC-SHA1  
private static final String SIGNATURE_METHOD = "HMACSHA1";  
// API 版本號爲日期形式:YYYY-MM-DD。本版本對應爲:2016-11-01  
private static final String VERSION = "2016-11-01";  
// 請求類型(GET/POST)  
private static final String REQUEST_METHOD_TYPE = "GET";  
// 返回值類型(JSON/XML)  
private static final String RET_FORMAT_TYPE = "JSON";  
// 參數之間分隔符  
private static final Character SEPARATOR = '&';  
private static final String HOST = "https://live.aliyuncs.com";  

/** 
 * 查詢推流地址是否在推流 
 * @return 
 */  
  
public Boolean steamIsOnline(String streamName) {  
    logger.info("oooo 查詢推流地址是否在推流");  

    //構建請求參數  
    Map<String, Object> params = Maps.newHashMap();  
    try {  
        //接口參數  
        params.put("Action", "DescribeLiveStreamsOnlineList");  
        params.put("DomainName", ApplicationConfig.ali_live_domain_name);  
        params.put("AppName", ApplicationConfig.ali_live_app_name);  
        //公共參數  
        buildPublicParams(params);  
    }catch (Exception e) {  
        logger.error("oooo 查詢推流地址是否在推流, 參數構建出錯", e);  
    }  

    //構建請求  
    String request = null;  
    try {  
        request = buildRequest(HOST, params, ApplicationConfig.alimedia_accessKeySecret);  
    } catch (UnsupportedEncodingException e) {  
        logger.error("oooo 查詢推流地址是否在推流, 【UTF-8】編碼方式不支持", e);  
    } catch (NoSuchAlgorithmException e) {  
        logger.error("oooo 查詢推流地址是否在推流, 簽名加密【{}】失敗", SIGNATURE_METHOD, e);  
    } catch (InvalidKeyException e) {  
        logger.error("oooo 查詢推流地址是否在推流, secretKey: 【{}】無效", ApplicationConfig.alimedia_accessKeySecret, e);  
    }  

    //發送請求  
    String result = "";  
    try {  
        result = send(request);  
    } catch (IOException e) {  
        logger.error("oooo 查詢推流地址是否在推流, 請求接口失敗", e);  
    }  

    //處理結果列表  
    boolean isContainSteamName = false; //是否包含推流名稱  
    try {  
        JSONObject resultJson = JSONObject.parseObject(result);  
        JSONObject onlineInfo = resultJson.getJSONObject("OnlineInfo"); //正在推送的流信息  
        JSONArray liveStreamOnlineInfo = onlineInfo.getJSONArray("LiveStreamOnlineInfo");  
        for(Object obj : liveStreamOnlineInfo) {  
            JSONObject jsonObject = (JSONObject)obj;  
            String onlineStreamName = jsonObject.getString("StreamName"); //流名稱  
            if(StringUtils.equalsIgnoreCase(streamName, onlineStreamName)) {  
                isContainSteamName = true;  
                break;  
            }  
        }  
    }catch (Exception e) {  
        logger.error("oooo 查詢推流地址是否在推流, 結果集解析出錯, result: {}", result, e);  
    }  

    return isContainSteamName;  
}  

/** 
 * 禁止直播流推送 
 * @param streamName 
 * @return 
 */  
  
public Boolean forbidLiveStream(String streamName) {  
    logger.info("oooo 禁止直播流推送, streamName: {}", streamName);  

    //構建請求參數  
    Map<String, Object> params = Maps.newConcurrentMap();  
    try {  
        //接口參數  
        params.put("Action", "ResumeLiveStream");  
        params.put("DomainName", ApplicationConfig.ali_live_domain_name);  
        params.put("AppName", ApplicationConfig.ali_live_app_name);  
        params.put("StreamName", streamName);  
        params.put("LiveStreamType", "publisher");//用於指定主播推流仍是客戶端拉流,目前支持 「publisher」(主播推送)  
        //公共參數  
        buildPublicParams(params);  
    }catch (Exception e) {  
        logger.error("oooo 禁止直播流推送, 參數構建出錯", e);  
        return false;  
    }  

    //構建請求  
    String request;  
    try {  
        request = buildRequest(HOST, params, ApplicationConfig.alimedia_accessKeySecret);  
    } catch (UnsupportedEncodingException e) {  
        logger.error("oooo 禁止直播流推送, 【UTF-8】編碼方式不支持", e);  
        return false;  
    } catch (NoSuchAlgorithmException e) {  
        logger.error("oooo 禁止直播流推送, 簽名加密【{}】失敗", SIGNATURE_METHOD, e);  
        return false;  
    } catch (InvalidKeyException e) {  
        logger.error("oooo 禁止直播流推送, secretKey: 【{}】無效", ApplicationConfig.alimedia_accessKeySecret, e);  
        return false;  
    }  

    //發送請求  
    try {  
        send(request);  
    } catch (IOException e) {  
        logger.error("oooo 禁止直播流推送, 請求接口失敗", e);  
        return false;  
    }  

    return true;  
}  

/** 
 * 發送請求 
 * @param request  
 * @return 
 * @throws IOException 
 */  
private String send(String request) throws IOException {  
    HttpClient client = new HttpClient();  
    GetMethod method = new GetMethod(request);  
    method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler(3, false));  

    int statusCode = client.executeMethod(method);  
    if (statusCode != HttpStatus.SC_OK) {  
        logger.error("oooo 阿里雲接口請求失敗: request: {}, {}", request, method.getStatusLine());  
    }  

    byte[] responseBody = method.getResponseBody();  

    return new String(responseBody);  
}  

/** 
 * 構建公共參數 
 * @param params 
 * @return 
 */  
private Map<String, Object> buildPublicParams(Map<String, Object> params) {  
    final String timestamp = ParameterHelper.getISO8601Time(new Date());  
    final String signatureNonce = new BigInteger(32, new SecureRandom()).toString(8);  

    params.put("Format", RET_FORMAT_TYPE);  
    params.put("SignatureMethod", "HMAC-SHA1");  
    params.put("Timestamp", timestamp);  
    params.put("AccessKeyId", ApplicationConfig.alimedia_accessKeyId);  
    params.put("SignatureNonce", signatureNonce);  
    params.put("Version", VERSION);  
    params.put("SignatureVersion", SIGNATURE_VERSION);  

    return params;  
}  

/** 
 * 構建請求 
 * @param host 
 * @param params 
 * @param secret 
 * @return 
 * @throws UnsupportedEncodingException 
 * @throws NoSuchAlgorithmException 
 * @throws InvalidKeyException 
 */  
private String buildRequest(String host, Map<String, Object> params, String secret) throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException {  
    String paramsStr = "";  
    List<String> sortedKeys = new ArrayList<String>(params.keySet());  
    Collections.sort(sortedKeys);  
    for (String key : sortedKeys) {  
        paramsStr += URLEncoder.encode(key, CharEncoding.UTF_8) + "=" + URLEncoder.encode(String.valueOf(params.get(key)), CharEncoding.UTF_8) + SEPARATOR;  
    }  

    return host + "/?" + paramsStr + "Signature=" + buildSignature(REQUEST_METHOD_TYPE, params, (secret + SEPARATOR));  
}  

/** 
 * 構建簽名 
 * @param method 
 * @param params 
 * @param secretKey 
 * @return 
 * @throws UnsupportedEncodingException 
 * @throws NoSuchAlgorithmException 
 * @throws InvalidKeyException 
 */  
private String buildSignature(String method, Map<String, Object> params, String secretKey) throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException {  
    String paramsStr = "";  
    List<String> sortedKeys = new ArrayList<String>(params.keySet());  
    Collections.sort(sortedKeys);  
    for (String key : sortedKeys) {  
        paramsStr += SEPARATOR + popEncode(key) + '=' + popEncode(String.valueOf(params.get(key)));  
    }  

    String stringToSign = method + SEPARATOR + popEncode("/") + SEPARATOR + popEncode(paramsStr.substring(1, paramsStr.length()));  

    //按照 RFC2104 的定義,計算簽名 HMAC 值  
    Mac mac = Mac.getInstance(SIGNATURE_METHOD);  
    mac.init(new SecretKeySpec(secretKey.getBytes(CharEncoding.UTF_8), SIGNATURE_METHOD));  
    byte[] rawHmac = mac.doFinal(stringToSign.getBytes(CharEncoding.UTF_8));  
    String sign = new Base64Encoder().encode(rawHmac);  

    return URLEncoder.encode(sign, CharEncoding.UTF_8);  
}  

/** 
 * 編碼 
 * @param value 
 * @return 
 * @throws UnsupportedEncodingException 
 */  
private static String popEncode(String value) throws UnsupportedEncodingException {  
    return value != null ? URLEncoder.encode(value, CharEncoding.UTF_8).replace("+", "%20").replace("*", "%2A").replace("%7E", "~") : null;  
}  
}

根據實際狀況進行具體配置數據,配置後便可使用json

public class ApplicationConfig {
static {
    Properties prop = new Properties();
    InputStream in = LiveAuthkeyUtils.class.getClassLoader()
            .getResourceAsStream("appconfig.properties");
    try {
        prop.load(in);
        privateKey = prop.getProperty("play.privateKey").trim();
        ali_live_domain_name = prop.getProperty("play.ali_live_domain_name").trim();
        ali_live_app_name = prop.getProperty("play.ali_live_app_name").trim();
        alimedia_accessKeySecret = prop.getProperty("play.alimedia_accessKeySecret").trim();
        alimedia_accessKeyId = prop.getProperty("play.alimedia_accessKeyId").trim();
        alimedia_timestamp = Integer.parseInt(prop.getProperty("play.alimedia_timestamp").trim());
    } catch (IOException e) {
        e.printStackTrace();
    }
}
  //阿里雲播放域名
 public  static  String ali_live_domain_name="";
 //阿里雲播放app名
 public static  String ali_live_app_name="";
 //阿里雲  
 public static  String alimedia_accessKeyId="";
 //阿里雲 accessKeySecret
 public static  String alimedia_accessKeySecret="";
 //阿里雲播放鑑權私匙
 public static String privateKey="";
 //阿里雲播放鑑權超時時間設置,在阿里雲進行設置
 public static Integer alimedia_timestamp=86400;
}
相關文章
相關標籤/搜索