背景介紹
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。
推流地址的簽名規則中包含的參數及描述如下表所示。
可以通過playlistName來指定生成的m3u8文件名稱,其值涵蓋LiveChannel中的配置。
Signature的計算規則如下
base64(hmac-sha1(AccessKeySecret,
+ Expires + "\n"
+ CanonicalizedParams
+ CanonicalizedResource))
Signature計算規則中涉及的參數及描述如下表所示
創建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();