ApsaraVideo Live supports on-demand stream ingest and playback, eliminating the need to create resources in advance. After adding ingest and streaming domains, you can generate URLs. This topic describes how to construct ingest and streaming URLs.
Usage notes
You can generate multiple ingest and streaming URLs to run multiple live streams simultaneously. However, each ingest domain allows a limited number of concurrent streams. Before live streaming, review the limit to ensure it aligns with your business needs. If not, increase the quota in Quota Center or contact us.
By default, URL signing is enabled for ingest and streaming domains. The generated URLs must include the access token. Otherwise, ingest and playback will fail.
URL formats
Ingest URLs
Concatenation rule: Ingest domain + AppName + StreamName + {Access token}
AppName
andStreamName
can be customized.ApsaraVideo Live determines whether a stream is unique based on
StreamName
instead ofAppName
. To distinguish two streams, their stream names must be different.If you want to use different AppNames under the same domain to ingest an identical stream (StreamName), contact us to enable app isolation.
{Access token} is an encrypted string calculated by MD5 algorithm. For more information, see Structure of the access token.
Examples:
RTMP:
rtmp://demo.aliyundoc.com/app/stream?auth_key={Access token}
ARTC:
artc://demo.aliyundoc.com/app/stream?auth_key= {Access token}
The ARTC URL is used for Real-Time Streaming (RTS).
SRT:
srt://demo.aliyundoc.com:1105?streamid=#!::h=demo.aliyundoc.com,r=/app/stream?auth_key= {Access token} ,m=publish
By default, the SRT protocol is disabled. To enable it, see Configure stream ingest over SRT.
The access token does not include
m=publish
.
Streaming URLs
In addition to standard streams, ApsaraVideo Live supports playing processed ones, including transcoded, delayed, and transcribed streams. The concatenation rules and supported protocols vary by stream type.
Concatenation rules
Standard stream
Format: Streaming domain + AppName + StreamName + {Access token}
Example:
rtmp://example.aliyundoc.com/app/stream?auth_key={Access token}
Transcoded stream using default or custom transcoding
Format: Streaming domain + AppName + StreamName
_Template ID
+ {Access token}Example:
rtmp://example.aliyundoc.com/app/stream_{Template ID}?auth_key={Access token}
Requirement: You must create a default or custom transcoding template.
Transcoded stream using multi-bitrate transcoding
Format: Streaming domain + AppName + StreamName
_Template group ID
+aliyunols=on
+ {Access token}Example:
http://example.aliyundoc.com/app/stream_{Template group ID}.m3u8?aliyunols=on&auth_key={Access token}
Requirement: You must create a multi-bitrate transcoding template group.
Delayed stream
Format: Streaming domain + AppName + StreamName
-alidelay
+ {Access token}Example:
rtmp://example.aliyundoc.com/app/stream-alidelay?auth_key={Access token}
Requirement: You must configure stream delay for the stream. Otherwise, it cannot be played via the generated URL.
Stream with live subtitles
Format: Streaming domain + AppName + StreamName
_Subtitle template name
+ {Access token}Example:
rtmp://example.aliyundoc.com/app/stream_{Subtitle template name}?auth_key={Access token}
Requirement: You must create a live subtitle template and rule.
Supported protocols
Stream type | RTMP | FLV | HLS | ARTC (for RTS) |
Standard stream | ✔️ | ✔️ | ✔️ | ✔️ |
Transcoded stream (default/custom) | ✔️ | ✔️ | ✔️ | ✔️ |
Transcoded stream (Multi-bitrate) | ❌ | ❌ | ✔️ | ❌ |
Delayed stream | ✔️ | ✔️ | ✔️ | ✔️ |
Stream with live subtitles | ✔️ | ✔️ | ✔️ | ❌ |
Examples
RTMP:
rtmp://example.aliyundoc.com/app/stream?auth_key={Access token
FLV:
http://example.aliyundoc.com/app/stream.flv?auth_key={Access token}
HLS:
http://example.aliyundoc.com/app/stream.m3u8?auth_key={Access token}
ARTC:
artc://example.aliyundoc.com/app/stream?auth_key={Access token}
For streams ingested over SRT, the following playback protocols are supported: RTMP, FLV, HLS, and ARTC. If you want to play the streams over SRT, consult your account manager or contact us.
Generate URLs
ApsaraVideo Live supports generating ingest and streaming URLs in the console or programmatically.
Generate URLs in the console
You can use Live URL generator to do this.
You must first associate an ingest domain with a streaming domain.
The generated URLs contain the access tokens.
This method does not support generating URLs for streams with live subtitles.
Generate URLs using code
Step 1: Get the encryption key
Before generating a signed URL, you must retrieve the key for encryption.
To generate ingest URLs, get the key of the ingest domain.
To generate streaming URLs, get the key of the streaming domain.
You can retrieve both in the console or by calling DescribeLiveDomainConfigs.
Step 2: Generate signed URLs
The following sample code shows how to generate a signed URL using the RTMP protocol.
Before generation, learn about the composition of a signed URL.
Java
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) {
// The URL to be encrypted. In the following example, the domain name is example.aliyundoc.com, AppName is liveApp, and StreamName is liveStream.
// Ingest and streaming URLs are encrypted using the same method.
// AppName and StreamName support letters, digits, hyphens (-), underscores (_), and equal signs (=). The maximum length is 256 characters.
String uri = "rtmp://example.aliyundoc.com/liveApp/liveStream";
// The key. To generate an ingest URL, use the key of the ingest domain. To generate a streaming URL, use the key of the streaming domain.
String key = "<input private key>";
// The exp value is a UNIX timestamp measured in seconds. The actual expiration time equals the exp value + the validity period set for the domain name.
// For example, if you set exp to current time + 3600 seconds, the actual expiration time equals the current time + 3600 seconds + the validity period. If you set it to the current time, the expiration time is the current time + the validity period.
long exp = System.currentTimeMillis() / 1000 + 1 * 3600;
String authUri = aAuth(uri, key, exp);
System.out.printf("URL : %s\nAuth: %s", uri, authUri);
}
}
Python
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():
# The URL to be encrypted. In the following example, the domain name is example.aliyundoc.com, AppName is liveApp, and StreamName is liveStream.
# Ingest and streaming URLs are encrypted using the same method.
# AppName and StreamName support letters, digits, hyphens (-), underscores (_), and equal signs (=). The maximum length is 256 characters.
uri = "rtmp://example.aliyundoc.com/liveApp/liveStream"
# The key. To generate an ingest URL, use the key of the ingest domain. To generate a streaming URL, use the key of the streaming domain.
key = "<input private key>"
# The exp value is a UNIX timestamp measured in seconds. The actual expiration time equals the exp value + the validity period set for the domain name.
# For example, if you set exp to current time + 3600 seconds, the actual expiration time equals the current time + 3600 seconds + the validity period. If you set it to the current time, the expiration time is the current time + the validity period.
exp = int(time.time()) + 1 * 3600
authuri = a_auth(uri, key, exp)
print("URL : %s\nAUTH: %s" %(uri, authuri))
if __name__ == "__main__":
main()
Go
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() {
// The URL to be encrypted. In the following example, the domain name is example.aliyundoc.com, AppName is liveApp, and StreamName is liveStream.
// Ingest and streaming URLs are encrypted using the same method.
// AppName and StreamName support letters, digits, hyphens (-), underscores (_), and equal signs (=). The maximum length is 256 characters.
uri := "rtmp://example.aliyundoc.com/liveApp/liveStream"
// The key. To generate an ingest URL, use the key of the ingest domain. To generate a streaming URL, use the key of the streaming domain.
key := "<input private key>"
// The exp value is a UNIX timestamp measured in seconds. The actual expiration time equals the exp value + the validity period set for the domain name.
// For example, if you set exp to current time + 3600 seconds, the actual expiration time equals the current time + 3600 seconds + the validity period. If you set it to the current time, the expiration time is the current time + the validity period.
exp := time.Now().Unix() + 3600
authuri := a_auth(uri, key, exp)
fmt.Printf("URL : %s\nAUTH: %s", uri, authuri)
}
PHP
<?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);
}
}
// The URL to be encrypted. In the following example, the domain name is example.aliyundoc.com, AppName is liveApp, and StreamName is liveStream.
// Ingest and streaming URLs are encrypted using the same method.
// AppName and StreamName support letters, digits, hyphens (-), underscores (_), and equal signs (=). The maximum length is 256 characters.
$uri = "rtmp://example.aliyundoc.com/liveApp/liveStream";
// The key. To generate an ingest URL, use the key of the ingest domain. To generate a streaming URL, use the key of the streaming domain.
$key = "<input private key>";
// The exp value is a UNIX timestamp measured in seconds. The actual expiration time equals the exp value + the validity period set for the domain name.
// For example, if you set exp to current time + 3600 seconds, the actual expiration time equals the current time + 3600 seconds + the validity period. If you set it to the current time, the expiration time is the current time + the validity period.
$exp = time() + 3600;
$authuri = a_auth($uri, $key, $exp);
echo "URL :" . $uri;
echo PHP_EOL;
echo "AUTH:" . $authuri;
?>
C#
using System;
using System.Text.RegularExpressions;
using System.Security.Cryptography;
using System.Text;
public class Test
{
public static void Main()
{
// The URL to be encrypted. In the following example, the domain name is example.aliyundoc.com, AppName is liveApp, and StreamName is liveStream.
// Ingest and streaming URLs are encrypted using the same method.
// AppName and StreamName support letters, digits, hyphens (-), underscores (_), and equal signs (=). The maximum length is 256 characters.
string uri= "rtmp://example.aliyundoc.com/liveApp/liveStream";
// The key. To generate an ingest URL, use the key of the ingest domain. To generate a streaming URL, use the key of the streaming domain.
string key= "<input private key>";
DateTime dateStart = new DateTime(1970, 1, 1, 8, 0, 0);
// The exp value is a UNIX timestamp measured in seconds. The actual expiration time equals the exp value + the validity period set for the domain name.
// For example, if you set exp to current time + 3600 seconds, the actual expiration time equals the current time + 3600 seconds + the validity period. If you set it to the current time, the expiration time is the current time + the validity period.
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();
}
}
References
Troubleshooting
To verify the validity of the generated URLs and their access tokens, use the troubleshooting tool provided in the console.
Ingest and playback
To use the generated URLs to ingest and play streams, see Live stream ingest and Live stream playback.
Server SDK for Java
To learn more about the SDK, see Use the server SDK for Java.
URL signing
To learn more about URL signing, see Ingest and streaming URL signing