This topic describes how to generate signed ingest URLs for sending the live feed and streaming URLs for viewers to watch the streams. This process is essential for ensuring secure and reliable live stream delivery.
Before you begin
Before you generate live streaming URLs, add ingest and streaming domains.
You can generate multiple ingest and streaming URLs for each domain to host multiple live events simultaneously. The number of concurrent streams for an ingest domain is limited: by default, the live centers in the China (Beijing), China (Shanghai), and China (Shenzhen) regions support up to 300 concurrent streams, while other live centers support up to 50. For more information, see Limits.
By default, URL signing is enabled for all ingest and streaming domains. For configuration details, see URL signing. To enable stream ingest and playback, you must append an access token to the URLs.
URL structure
In ApsaraVideo Live, a standard live streaming URL consists of an ingest or streaming domain, an AppName, a StreamName, and an {access_token}.
The following table describes these parameters:
Parameter | Description |
Ingest/Streaming domain | Generate your ingest URL from the ingest domain, and your streaming URL from the streaming domain. |
AppName | A custom name for your application to distinguish between different applications or business scenarios. |
StreamName | A unique, custom name for your stream. |
Access token | An encrypted string generated using the MD5 algorithm to secure your live stream. For details on how to generate this string, see Signed ingest and streaming URLs. |
Ingest URL examples
Supported protocol | Example | Description |
RTMP |
| Standard protocol for stream ingest. |
ARTC |
| Ingest URL for Real-Time Streaming (RTS). |
SRT |
| The SRT protocol is disabled by default. To use this protocol, enable it for the ingest domain. For details, see Configure stream ingest over SRT. |
Streaming URL examples
URL type | Description | Supported protocol | Example |
Standard streaming URL | If you use the SRT protocol for stream ingest, playback is supported over RTMP, FLV, HLS, and ARTC. | RTMP |
|
FLV |
| ||
HLS |
| ||
ARTC |
| ||
Transcoded stream URL (Default transcoding or custom transcoding) | Append | RTMP |
|
FLV |
| ||
HLS |
| ||
ARTC |
| ||
Transcoded stream URL (Multi-bitrate transcoding) | For a multi-bitrate transcoded stream, append | HLS |
|
Delayed stream URL | For a delayed stream, append | RTMP |
|
FLV |
| ||
HLS |
| ||
ARTC |
| ||
Live subtitles stream URL | Append | RTMP |
|
FLV |
| ||
HLS |
|
Generate URLs
Generate from the console
Use the live URL generator to generate ingest and streaming URLs in the console. This tool generates URLs that include an encrypted {access_token}.
The live URL generator does not support generating live subtitles stream URLs.
Generate by using code
1. Construct the URI
Construct the URI using the format: {protocol}://{domain}/{AppName}/{streamName}. For examples of different protocols, see Ingest URL examples and Streaming URL examples.
// Pseudocode
protocol = "rtmp"
domain = "example.aliyundoc.com"
appName = "liveApp"
streamName = "liveStream"
uri = protocol + "://" + domain + "/" + appName + "/" + streamName
// Result: rtmp://example.aliyundoc.com/liveApp/liveStream2. Get the authentication key
Use the authentication key to generate the access token. You can obtain the key from the console on the URL signing page or by calling the DescribeLiveDomainConfigs operation.
To generate ingest URLs, use the key of the ingest domain. To generate streaming URLs, use the key of the streaming domain.
3. Assemble the complete URL
The following code shows how to generate an {access_token} and assemble a complete live streaming URL using the RTMP protocol as an example:
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 ingest or streaming URL to be signed. example.aliyundoc.com is the ingest or streaming domain, liveApp is the AppName, and liveStream is the StreamName.
// Ingest and streaming URLs use the same signing method.
// The AppName or StreamName can be up to 256 characters long and can contain digits, letters, hyphens (-), underscores (_), and equal signs (=).
String uri = "rtmp://example.aliyundoc.com/liveApp/liveStream";
// The authentication key. To generate ingest URLs, use the key of the ingest domain. To generate streaming URLs, use the key of the streaming domain.
String key = "<input private key>";
// exp is a UNIX timestamp in seconds. The URL's final expiration time is this timestamp plus the validity period configured for URL signing on the domain.
// For example, if you set exp to the current time + 3600 seconds, the final expiration time is the current time + 3600 seconds + the validity period. If you set exp to the current time, the final 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 ingest or streaming URL to be signed. example.aliyundoc.com is the ingest or streaming domain, liveApp is the AppName, and liveStream is the StreamName.
# Ingest and streaming URLs use the same signing method.
# The AppName or StreamName can be up to 256 characters long and can contain digits, letters, hyphens (-), underscores (_), and equal signs (=).
uri = "rtmp://example.aliyundoc.com/liveApp/liveStream"
# The authentication key. To generate ingest URLs, use the key of the ingest domain. To generate streaming URLs, use the key of the streaming domain.
key = "<input private key>"
# exp is a UNIX timestamp in seconds. The URL's final expiration time is this timestamp plus the validity period configured for URL signing on the domain.
# For example, if you set exp to the current time + 3600 seconds, the final expiration time is the current time + 3600 seconds + the validity period. If you set exp to the current time, the final 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 ingest or streaming URL to be signed. example.aliyundoc.com is the ingest or streaming domain, liveApp is the AppName, and liveStream is the StreamName.
// Ingest and streaming URLs use the same signing method.
// The AppName or StreamName can be up to 256 characters long and can contain digits, letters, hyphens (-), underscores (_), and equal signs (=).
uri := "rtmp://example.aliyundoc.com/liveApp/liveStream"
// The authentication key. To generate ingest URLs, use the key of the ingest domain. To generate streaming URLs, use the key of the streaming domain.
key := "<input private key>"
// exp is a UNIX timestamp in seconds. The URL's final expiration time is this timestamp plus the validity period configured for URL signing on the domain.
// For example, if you set exp to the current time + 3600 seconds, the final expiration time is the current time + 3600 seconds + the validity period. If you set exp to the current time, the final 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 ingest or streaming URL to be signed. example.aliyundoc.com is the ingest or streaming domain, liveApp is the AppName, and liveStream is the StreamName.
// Ingest and streaming URLs use the same signing method.
// The AppName or StreamName can be up to 256 characters long and can contain digits, letters, hyphens (-), underscores (_), and equal signs (=).
$uri = "rtmp://example.aliyundoc.com/liveApp/liveStream";
// The authentication key. To generate ingest URLs, use the key of the ingest domain. To generate streaming URLs, use the key of the streaming domain.
$key = "<input private key>";
// exp is a UNIX timestamp in seconds. The URL's final expiration time is this timestamp plus the validity period configured for URL signing on the domain.
// For example, if you set exp to the current time + 3600 seconds, the final expiration time is the current time + 3600 seconds + the validity period. If you set exp to the current time, the final 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 ingest or streaming URL to be signed. example.aliyundoc.com is the ingest or streaming domain, liveApp is the AppName, and liveStream is the StreamName.
// Ingest and streaming URLs use the same signing method.
// The AppName or StreamName can be up to 256 characters long and can contain digits, letters, hyphens (-), underscores (_), and equal signs (=).
string uri= "rtmp://example.aliyundoc.com/liveApp/liveStream";
// The authentication key. To generate ingest URLs, use the key of the ingest domain. To generate streaming URLs, use the key of the streaming domain.
string key= "<input private key>";
DateTime dateStart = new DateTime(1970, 1, 1, 8, 0, 0);
// exp is a UNIX timestamp in seconds. The URL's final expiration time is this timestamp plus the validity period configured for URL signing on the domain.
// For example, if you set exp to the current time + 3600 seconds, the final expiration time is the current time + 3600 seconds + the validity period. If you set exp to the current time, the final 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();
}
}Use and verify the URLs
After generating the URLs, perform an end-to-end test to confirm they work well. First, use the ingest URL for live stream ingest, then use the associated streaming URL for live stream playback.
If you encounter issues during ingest or playback, use the troubleshooting tool to inspect the URL and verify that the address, authentication key, and other information are valid.