天天看點

【OSS最佳實踐】JAVA實作RTMP推流上傳OSS的簽名URL背景介紹簽名URL格式建立LiveChannel生成簽名URL-自簽名方式生成簽名URL-SDK方法

背景介紹

OSS支援使用RTMP協定推送H264編碼的視訊流和AAC編碼的音頻流到OSS。推送到OSS的音視訊資料可以點播播放;在對延遲不敏感的應用場景,也可以做直播用途。RTMP推流上傳的流程是建立LiveChannel以後生成推流位址,關于這塊的介紹在官方幫助文檔裡也有介紹,具體可以參考文檔"

RTMP推流上傳

"。由于目前提供的示例是Python的,本文介紹如何使用JAVA實作生成LiveChannel的簽名URL,包括推流位址和播放位址。主要介紹兩種方式:

  • 自簽名方式:根據簽名算法來生成簽名并拼接URL
  • SDK方法:直接調用SDK的方法生成簽名URL

自簽名方式便于了解OSS的簽名原理,使用者可以脫離SDK,自己封裝方法去生成簽名URL;SDK方法相對比較簡單,直接內建SDK調用即可。

簽名URL格式

目前OSS JAVA SDK的CreateLiveChannelResult類擷取到的推流位址和播放位址,是不帶簽名參數的,如果Bucket的權限是私有的話,那必須使用簽名URL去推流。帶簽名的推流位址形如:

rtmp://${bucket}.${host}/live/${channel}?OSSAccessKeyId=xxx&Expires=yyy&Signature=zzz&${params}

  • live:RTMP協定的app名稱,OSS固定使用live。
  • params:推流參數,格式與HTTP請求的query string相同,即形如varA=valueA&varB=valueB。

推流位址的簽名規則中包含的參數及描述如下表所示。

【OSS最佳實踐】JAVA實作RTMP推流上傳OSS的簽名URL背景介紹簽名URL格式建立LiveChannel生成簽名URL-自簽名方式生成簽名URL-SDK方法

可以通過playlistName來指定生成的m3u8檔案名稱,其值涵蓋LiveChannel中的配置。

【OSS最佳實踐】JAVA實作RTMP推流上傳OSS的簽名URL背景介紹簽名URL格式建立LiveChannel生成簽名URL-自簽名方式生成簽名URL-SDK方法

Signature的計算規則如下

base64(hmac-sha1(AccessKeySecret,
+ Expires + "\n"
+ CanonicalizedParams
+ CanonicalizedResource))
           

Signature計算規則中涉及的參數及描述如下表所示

【OSS最佳實踐】JAVA實作RTMP推流上傳OSS的簽名URL背景介紹簽名URL格式建立LiveChannel生成簽名URL-自簽名方式生成簽名URL-SDK方法

建立LiveChannel

參考OSS的JAVA SDK的

安裝文檔

引入JavaSDK。import以下幾個類

import com.aliyun.oss.OSSClient;

import com.aliyun.oss.model.CreateLiveChannelRequest;

import com.aliyun.oss.model.CreateLiveChannelResult;

通過CreateLiveChannelRequest類建立LiveChennel,通過CreateLiveChannelResult擷取推流位址和播放位址,示例代碼如下

public static void main(String[] args) {
    // TODO Auto-generated method stub
    // endpoint以杭州為例,其它region請按實際情況填寫
    String endpoint = "http://oss-cn-hangzhou.aliyuncs.com";
    // 雲賬号AccessKey有所有API通路權限,建議遵循阿裡雲安全最佳實踐,建立并使用RAM子賬号進行API通路或日常運維,請登入 https://ram.console.aliyun.com 建立
    String accessKeyId = "<您的AccessKeyId>";
    String accessKeySecret = "<您的AccessKeySecret>";
    String bucketName = "<您的Bucket名稱>";
    String liveChannelName = "testChannel";//您的LiveChannel的名稱,例如testChannel
    // 建立OSSClient執行個體
    OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);        
    //建立livechannel,列印推流位址和播放位址(未簽名)
    CreateLiveChannelRequest request = new CreateLiveChannelRequest(bucketName, liveChannelName);
    CreateLiveChannelResult result = new CreateLiveChannelResult();
    result = ossClient.createLiveChannel(request);
    System.out.println("推流位址:"+result.getPublishUrls());
    System.out.println("播放位址:"+result.getPlayUrls());        
    // 關閉client
    ossClient.shutdown();        
}
           

生成簽名URL-自簽名方式

引入如下依賴

import org.apache.commons.codec.binary.Base64;

import javax.crypto.Mac;

import javax.crypto.spec.SecretKeySpec;

private final static String CHARSET_UTF8 = "utf8";
private final static String ALGORITHM = "HmacSHA1";
           

構造簽名字元串函數,傳回簽名字元串signString

public static String buildSignString(String Expires,String CanonicalizedParams,String CanonicalizedResource){
    String signString = Expires + "\n"
            + CanonicalizedParams + "\n"
            + CanonicalizedResource;
    return signString;
}    

           

計算簽名的函數,參數為簽名字元串signString+AccessKeySecret

public static String hmacSha1(String signString, String AccessKeySecret) {
    try {
        Mac mac = Mac.getInstance("HmacSHA1");
        SecretKeySpec keySpec = new SecretKeySpec(AccessKeySecret.getBytes(), ALGORITHM);
        mac.init(keySpec);
        byte[] rawHmac;
        rawHmac = mac.doFinal(signString.getBytes(CHARSET_UTF8));
        return new String(Base64.encodeBase64(rawHmac));
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}
           

主函數,生成推流URL

public static void main(String[] args) throws Exception{        
    String bucketName= "<您的Bucket名稱>";
    String Endpoint= "oss-cn-hangzhou.aliyuncs.com";//Endpoint
    String channelName = "testChannel";//liveCahnnel名稱
    String CanonicalizedParams = "playlistName:playlist.m3u8";//格式為"playlistName:<指定的m3u8名稱>"
    String CanonicalizedResource = "/test-bucket/testChannel";//CanonicalizedResource格式為/BucketName/ChannelName
    String accessKeyId= "<您的AccessKeyId>";
    String secretAccessKey= "<您的AccessKeySecret>";
    String Expires = Long.toString(System.currentTimeMillis()/1000L+3600); //生成一個unix時間戳Expires,定義URL過期時間
    String Signature = (hmacSha1(buildSignString(Expires,CanonicalizedParams,CanonicalizedResource),secretAccessKey));
    
    //推流位址的格式是:rtmp://bucketName.Endpoint/live/channelName?playlistName=playlist.m3u8&Expires=xxx&OSSAccessKeyId=xxx&Signature=xxx
    System.out.println("推流位址是\n"+"rtmp://"+bucketName+"."+Endpoint+"/live/"+channelName+"?playlistName=playlist.m3u8"+"&Expires="+Expires+"&OSSAccessKeyId="+accessKeyId+"&Signature="+Signature);

}
           

生成簽名URL-SDK方法

rtmp的推流位址可以用JavaSDK裡的generateRtmpUri方法生成,示例如下

OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
    Date expiration = new Date(new Date().getTime() + 360000 * 1000);
    String url = ossClient.generateRtmpUri(bucketName, liveChannelName, PlaylistName, expires);
    System.out.println(url);
           

m3u8的簽名播放位址可以用JavaSDK裡的generatePresignedUrl方法來直接生成,示例如下

OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
    Date expiration = new Date(new Date().getTime() + 360000 * 1000);
    java.net.URL url = ossClient.generatePresignedUrl(bucketName, objectName, expiration);
    System.out.println(url);
    ossClient.shutdown();