阿里云视频直播提供触发式推流与播放,您无需提前创建资源,只要添加经过备案的推流域名和播流域名,并完成域名解析、鉴权等操作,即可快速拼接生成推流地址和播放地址。通过阅读本文,您可以了解推流地址和播放地址的拼接规则及生成方法。
使用说明
直播地址
推流地址
拼接规则:推流域名+AppName+StreamName+{鉴权串}。
地址示例:
RTMP:
rtmp://demo.aliyundoc.com/app/stream?auth_key={鉴权串}
ARTC:
artc://demo.aliyundoc.com/app/stream?auth_key={鉴权串}
ARTC推流地址是阿里云超低延时直播RTS推流地址。
SRT:
srt://demo.aliyundoc.com:1105?streamid=#!::h=demo.aliyundoc.com,r=/app/stream?auth_key={鉴权串},m=publish
SRT协议推流默认处于关闭状态,您需要对推流域名开启SRT协议(操作指引可参见SRT推流)才能使用。
m=publish不在鉴权串中,例如:
srt://demo.aliyunlive.com:1105?streamid=#!::h=demo.aliyunlive.com,r=/1/1?auth_key=1661312655-0-0-3fded78b61b14071****aa6e6d2,m=publish
生成推流地址:
播放地址
拼接规则:播流域名+AppName+StreamName+{鉴权串}。
AppName和StreamName需要与推流地址中的值保持一致。
{鉴权串}使用方法同推流地址。
地址示例:
RTMP:
rtmp://example.aliyundoc.com/app/stream?auth_key={鉴权串}
FLV:
http://example.aliyundoc.com/app/stream.flv?auth_key={鉴权串}
HLS:
http://example.aliyundoc.com/app/stream.m3u8?auth_key={鉴权串}
ARTC(阿里云超低延时直播RTS):
artc://example.aliyundoc.com/app/stream?auth_key={鉴权串}
SRT:推流为SRT协议时,播放协议支持RTMP、FLV、HLS、ARTC。SRT协议播放暂未对外开放,若需使用,请联系您的阿里云客户经理或联系我们进行开通。
协议支持:
播放地址
RTMP
FLV
HLS
ARTC
说明
播放地址
RTMP
FLV
HLS
ARTC
说明
直播播放地址
支持
支持
支持
支持
示例:
rtmp://example.aliyundoc.com/app/stream?auth_key={鉴权串}
转码流播放地址(通用转码/自定义转码)
支持
支持
支持
支持
转码流地址需要在StreamName后加
_转码模板ID
,转码模板ID
需通过直播转码功能进行配置。示例:
rtmp://example.aliyundoc.com/app/stream_{转码模板ID}?auth_key={鉴权串}
转码流播放地址(多码率转码)
暂不支持
暂不支持
支持
暂不支持
多码率转码流地址需要在StreamName后加
_转码模板组ID
,地址中需增加aliyunols=on
参数,转码模板组ID
需通过直播转码功能进行配置。示例:
http://example.aliyundoc.com/app/stream_{转码模板组ID}.m3u8?aliyunols=on&auth_key={鉴权串}
延播播放地址
支持
支持
支持
支持
延播播放地址需要在
StreamName
后加-alidelay
。使用延播播放前需进行延播配置。示例:
rtmp://example.aliyundoc.com/app/stream-alidelay?auth_key={鉴权串}
实时字幕播放地址
支持
支持
支持
暂不支持
实时字幕播放地址需要在StreamName后加
_字幕模板名称
。字幕模板名称
需通过实时字幕功能进行配置。示例:
rtmp://example.aliyundoc.com/app/stream_{字幕模板名称}?auth_key={鉴权串}
生成播放地址:
代码生成推/播流地址
第一步,获取鉴权Key
在使用代码生成鉴权URL前,您需要获取鉴权Key。鉴权Key用于对URL进行加密,您可以通过控制台URL鉴权配置或调用DescribeLiveDomainConfigsAPI获取鉴权Key。
第二步,对URL进行加密
在此之前您可以通过鉴权URL组成了解鉴权URL结构。以下示例代码以RTMP协议为例,生成鉴权URL。
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class AuthDemo {
private static String md5Sum(String src) {
MessageDigest md5 = null;
try {
md5 = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
md5.update(StandardCharsets.UTF_8.encode(src));
return String.format("%032x", new BigInteger(1, md5.digest()));
}
private static String aAuth(String uri, String key, long exp) {
String pattern = "^(rtmp://)?([^/?]+)(/[^?]*)?(\\\\?.*)?$";
Pattern r = Pattern.compile(pattern);
Matcher m = r.matcher(uri);
String scheme = "", host = "", path = "", args = "";
if (m.find()) {
scheme = m.group(1) == null ? "rtmp://" : m.group(1);
host = m.group(2) == null ? "" : m.group(2);
path = m.group(3) == null ? "/" : m.group(3);
args = m.group(4) == null ? "" : m.group(4);
} else {
System.out.println("NO MATCH");
}
String rand = "0"; // "0" by default, other value is ok
String uid = "0"; // "0" by default, other value is ok
String sString = String.format("%s-%s-%s-%s-%s", path, exp, rand, uid, key);
String hashValue = md5Sum(sString);
String authKey = String.format("%s-%s-%s-%s", exp, rand, uid, hashValue);
if (args.isEmpty()) {
return String.format("%s%s%s%s?auth_key=%s", scheme, host, path, args, authKey);
} else {
return String.format("%s%s%s%s&auth_key=%s", scheme, host, path, args, authKey);
}
}
public static void main(String[] args) {
// 待加密的推/播流地址,example.aliyundoc.com为推/播流域名,liveApp为AppName,liveStream为StreamName
// 推流和播流URL采用同样的加密方法
// AppName或StreamName不超过256字符,支持数字、大小写字母、短划线(-)、下划线(_)、等号(=)。
String uri = "rtmp://example.aliyundoc.com/liveApp/liveStream";
// 鉴权Key,推流地址使用推流域名URL鉴权Key,播流地址使用播流域名URL鉴权Key
String key = "<input private key>";
// exp值为UNIX时间戳,单位秒,最终失效时间由该值加上域名URL鉴权有效时长决定
// 比如您在此处设置exp为:当前时间+3600秒,那最终失效时间为:当前时间+3600秒+域名URL鉴权有效时长。如果设置exp为:当前时间,那最终失效时间为:当前时间+域名URL鉴权有效时长
long exp = System.currentTimeMillis() / 1000 + 1 * 3600;
String authUri = aAuth(uri, key, exp);
System.out.printf("URL : %s\nAuth: %s", uri, authUri);
}
}
import re
import time
import hashlib
import datetime
def md5sum(src):
m = hashlib.md5()
m.update(src)
return m.hexdigest()
def a_auth(uri, key, exp):
p = re.compile("^(rtmp://)?([^/?]+)(/[^?]*)?(\\?.*)?$")
if not p:
return None
m = p.match(uri)
scheme, host, path, args = m.groups()
if not scheme: scheme = "rtmp://"
if not path: path = "/"
if not args: args = ""
rand = "0" # "0" by default, other value is ok
uid = "0" # "0" by default, other value is ok
sstring = "%s-%s-%s-%s-%s" %(path, exp, rand, uid, key)
hashvalue = md5sum(sstring.encode('utf-8'))
auth_key = "%s-%s-%s-%s" %(exp, rand, uid, hashvalue)
if args:
return "%s%s%s%s&auth_key=%s" %(scheme, host, path, args, auth_key)
else:
return "%s%s%s%s?auth_key=%s" %(scheme, host, path, args, auth_key)
def main():
# 待加密的推/播流地址,example.aliyundoc.com为推/播流域名,liveApp为AppName,liveStream为StreamName
# 推流和播流URL采用同样的加密方法
# AppName或StreamName不超过256字符,支持数字、大小写字母、短划线(-)、下划线(_)、等号(=)。
uri = "rtmp://example.aliyundoc.com/liveApp/liveStream"
# 鉴权Key,推流地址使用推流域名URL鉴权Key,播流地址使用播流域名URL鉴权Key
key = "<input private key>"
# exp值为UNIX时间戳,单位秒,最终失效时间由该值加上域名URL鉴权有效时长决定
# 比如您在此处设置exp为:当前时间+3600秒,那最终失效时间为:当前时间+3600秒+域名URL鉴权有效时长。如果设置exp为:当前时间,那最终失效时间为:当前时间+域名URL鉴权有效时长
exp = int(time.time()) + 1 * 3600
authuri = a_auth(uri, key, exp)
print("URL : %s\nAUTH: %s" %(uri, authuri))
if __name__ == "__main__":
main()
package main
import (
"crypto/md5"
"encoding/hex"
"fmt"
"regexp"
"time"
)
func md5sum(src string) string {
h := md5.New()
h.Write([]byte(src))
return hex.EncodeToString(h.Sum(nil))
}
func a_auth(uri, key string, exp int64) string {
p, err := regexp.Compile("^(rtmp://)?([^/?]+)(/[^?]*)?(\\?.*)?$")
if err != nil {
fmt.Println(err)
return ""
}
m := p.FindStringSubmatch(uri)
var scheme, host, path, args string
if len(m) == 5 {
scheme, host, path, args = m[1], m[2], m[3], m[4]
} else {
scheme, host, path, args = "rtmp://", "", "/", ""
}
rand := "0" // "0" by default, other value is ok
uid := "0" // "0" by default, other value is ok
sstring := fmt.Sprintf("%s-%d-%s-%s-%s", path, exp, rand, uid, key)
hashvalue := md5sum(sstring)
auth_key := fmt.Sprintf("%d-%s-%s-%s", exp, rand, uid, hashvalue)
if len(args) != 0 {
return fmt.Sprintf("%s%s%s%s&auth_key=%s", scheme, host, path, args, auth_key)
} else {
return fmt.Sprintf("%s%s%s%s?auth_key=%s", scheme, host, path, args, auth_key)
}
}
func main() {
// 待加密的推/播流地址,example.aliyundoc.com为推/播流域名,liveApp为AppName,liveStream为StreamName
// 推流和播流URL采用同样的加密方法
// AppName或StreamName不超过256字符,支持数字、大小写字母、短划线(-)、下划线(_)、等号(=)。
uri := "rtmp://example.aliyundoc.com/liveApp/liveStream"
// 鉴权Key,推流地址使用推流域名URL鉴权Key,播流地址使用播流域名URL鉴权Key
key := "<input private key>"
// exp值为UNIX时间戳,单位秒,最终失效时间由该值加上域名URL鉴权有效时长决定
// 比如您在此处设置exp为:当前时间+3600秒,那最终失效时间为:当前时间+3600秒+域名URL鉴权有效时长。如果设置exp为:当前时间,那最终失效时间为:当前时间+域名URL鉴权有效时长
exp := time.Now().Unix() + 3600
authuri := a_auth(uri, key, exp)
fmt.Printf("URL : %s\nAUTH: %s", uri, authuri)
}
<?php
function a_auth($uri, $key, $exp) {
preg_match("/^(rtmp:\/\/)?([^\/?]+)?(\/[^?]*)?(\\?.*)?$/", $uri, $matches);
$scheme = $matches[1];
$host = $matches[2];
$path = $matches[3];
$args = $matches[4];
if (empty($args)) {
$args ="";
}
if (empty($scheme)) {
$scheme ="rtmp://";
}
if (empty($path)) {
$path ="/";
}
$rand = "0";
// "0" by default, other value is ok
$uid = "0";
// "0" by default, other value is ok
$sstring = sprintf("%s-%u-%s-%s-%s", $path, $exp, $rand, $uid, $key);
$hashvalue = md5($sstring);
$auth_key = sprintf("%u-%s-%s-%s", $exp, $rand, $uid, $hashvalue);
if ($args) {
return sprintf("%s%s%s%s&auth_key=%s", $scheme, $host, $path, $args, $auth_key);
} else {
return sprintf("%s%s%s%s?auth_key=%s", $scheme, $host, $path, $args, $auth_key);
}
}
// 待加密的推/播流地址,example.aliyundoc.com为推/播流域名,liveApp为AppName,liveStream为StreamName
// 推流和播流URL采用同样的加密方法
// AppName或StreamName不超过256字符,支持数字、大小写字母、短划线(-)、下划线(_)、等号(=)。
$uri = "rtmp://example.aliyundoc.com/liveApp/liveStream";
// 鉴权Key,推流地址使用推流域名URL鉴权Key,播流地址使用播流域名URL鉴权Key
$key = "<input private key>";
// exp值为UNIX时间戳,单位秒,最终失效时间由该值加上域名URL鉴权有效时长决定
// 比如您在此处设置exp为:当前时间+3600秒,那最终失效时间为:当前时间+3600秒+域名URL鉴权有效时长。如果设置exp为:当前时间,那最终失效时间为:当前时间+域名URL鉴权有效时长
$exp = time() + 3600;
$authuri = a_auth($uri, $key, $exp);
echo "URL :" . $uri;
echo PHP_EOL;
echo "AUTH:" . $authuri;
?>
using System;
using System.Text.RegularExpressions;
using System.Security.Cryptography;
using System.Text;
public class Test
{
public static void Main()
{
// 待加密的推/播流地址,example.aliyundoc.com为推/播流域名,liveApp为AppName,liveStream为StreamName
// 推流和播流URL采用同样的加密方法
// AppName或StreamName不超过256字符,支持数字、大小写字母、短划线(-)、下划线(_)、等号(=)。
string uri= "rtmp://example.aliyundoc.com/liveApp/liveStream";
// 鉴权Key,推流地址使用推流域名URL鉴权Key,播流地址使用播流域名URL鉴权Key
string key= "<input private key>";
DateTime dateStart = new DateTime(1970, 1, 1, 8, 0, 0);
// exp值为UNIX时间戳,单位秒,最终失效时间由该值加上域名URL鉴权有效时长决定
// 比如您在此处设置exp为:当前时间+3600秒,那最终失效时间为:当前时间+3600秒+域名URL鉴权有效时长。如果设置exp为:当前时间,那最终失效时间为:当前时间+域名URL鉴权有效时长
string exp = Convert.ToInt64((DateTime.Now - dateStart).TotalSeconds+3600).ToString();
string authUri = aAuth(uri, key, exp);
Console.WriteLine (String.Format("URL :{0}",uri));
Console.WriteLine (String.Format("AUTH :{0}",authUri));
}
public static string aAuth(string uri, string key, string exp)
{
Regex regex = new Regex("^(rtmp://)?([^/?]+)(/[^?]*)?(\\\\?.*)?$");
Match m = regex.Match(uri);
string scheme = "rtmp://", host = "", path = "/", args = "";
if (m.Success)
{
scheme=m.Groups[1].Value;
host=m.Groups[2].Value;
path=m.Groups[3].Value;
args=m.Groups[4].Value;
}else{
Console.WriteLine ("NO MATCH");
}
string rand = "0"; // "0" by default, other value is ok
string uid = "0"; // "0" by default, other value is ok
string u = String.Format("{0}-{1}-{2}-{3}-{4}", path, exp, rand, uid, key);
string hashValue = Md5(u);
string authKey = String.Format("{0}-{1}-{2}-{3}", exp, rand, uid, hashValue);
if (args=="")
{
return String.Format("{0}{1}{2}{3}?auth_key={4}", scheme, host, path, args, authKey);
} else
{
return String.Format("{0}{1}{2}{3}&auth_key={4}", scheme, host, path, args, authKey);
}
}
public static string Md5(string value)
{
MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
byte[] bytes = Encoding.ASCII.GetBytes(value);
byte[] encoded = md5.ComputeHash(bytes);
StringBuilder sb = new StringBuilder();
for(int i=0; i<encoded.Length; ++i)
{
sb.Append(encoded[i].ToString("x2"));
}
return sb.ToString();
}
}
相关文档
使用Java SDK,请参见Java SDK使用说明。
更多鉴权URL说明,请参见推/播流地址鉴权。