背景介紹
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();