Generate ingest and streaming URLs
To start a live stream, you need an ingest URL for broadcasting and a streaming URL for viewing. This topic describes how to generate signed ingest and streaming URLs with ApsaraVideo Live to secure your stream distribution.
Prerequisites
Before you generate an ingest URL or a streaming URL, you must add an ingest domain and a streaming domain and associate them. For more information, see Add domains.
Each domain supports multiple ingest and streaming URLs for concurrent streams. For an ingest domain, the limit is 300 concurrent streams in the China (Beijing), China (Shanghai), and China (Shenzhen) regions, and 50 in all other regions. For more information, see Limits.
URL structure
A streaming URL consists of a protocol, an ingest/streaming domain, AppName, StreamName, and an Token.
The following table describes the components of a live stream URL.
Parameter | Description | Example |
Protocol | The protocol used for the live stream. |
|
Ingest/Streaming domain | The domain that you have added. Use an ingest domain to generate an ingest URL, and a streaming domain to generate a streaming URL. |
|
AppName | A custom name for your live application, used to differentiate between applications or business scenarios. |
|
StreamName | A custom, unique identifier for the live stream. |
|
access token | An encrypted string generated using the MD5 algorithm and the domain's authentication key. This token secures the live stream. For details on the generation rules, see URL signing. |
|
Generate URLs
You can generate ingest and streaming URLs using one of the following methods:
Generate in the console: Recommended for initial trials and testing. The console generates URLs with an encrypted Token with a single click.
Generate programmatically: Recommended for production environments. Automating URL generation on your server allows for flexible management and distribution.
Generate in the console
Go to the URL Generators page.
Complete the following configurations and click Generate URLs to obtain the ingest and streaming URLs.
NoteThe URL generator does not support generating streaming URLs for live subtitles.
Generate programmatically
Step 1: Construct the URI
Construct the base URI in the following format: {protocol}://{domain}/{AppName}/{streamName}. For examples of different protocols, see Ingest URL examples or 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/liveStreamStep 2: Get the authentication key
The authentication key is used to generate the access token. Obtain the authentication key from the URL signing page in the console or by calling the DescribeLiveDomainConfigs API.
Use the authentication key of the ingest domain for ingest URLs and the key of the streaming domain for streaming URLs.
Step 3: Assemble the signed URL
The following example code for the RTMP protocol first generates an {Token} and then assembles a complete live streaming 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 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.
// The same signing method is used for both ingest and streaming URLs.
// The AppName and StreamName can be up to 256 characters long and can contain digits, uppercase and lowercase letters, hyphens (-), underscores (_), and equal signs (=).
String uri = "rtmp://example.aliyundoc.com/liveApp/liveStream";
// The authentication key. Use the key of the ingest domain for ingest URLs and the key of the streaming domain for streaming URLs.
String key = "<input private key>";
// The URL's final expiration time is the `exp` timestamp plus the validity period configured for the domain's URL signing. For example, if `exp` is `now + 3600`, the URL expires at `now + 3600 + 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()
if isinstance(src, str):
src = src.encode('utf-8')
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.
# The same signing method is used for both ingest and streaming URLs.
# The AppName and StreamName can be up to 256 characters long and can contain digits, uppercase and lowercase letters, hyphens (-), underscores (_), and equal signs (=).
uri = "rtmp://example.aliyundoc.com/liveApp/liveStream"
# The authentication key. Use the key of the ingest domain for ingest URLs and the key of the streaming domain for streaming URLs.
key = "<input private key>"
# The URL's final expiration time is the `exp` timestamp plus the validity period configured for the domain's URL signing. For example, if `exp` is `now + 3600`, the URL expires at `now + 3600 + 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.
// The same signing method is used for both ingest and streaming URLs.
// The AppName and StreamName can be up to 256 characters long and can contain digits, uppercase and lowercase letters, hyphens (-), underscores (_), and equal signs (=).
uri := "rtmp://example.aliyundoc.com/liveApp/liveStream"
// The authentication key. Use the key of the ingest domain for ingest URLs and the key of the streaming domain for streaming URLs.
key := "<input private key>"
// The URL's final expiration time is the `exp` timestamp plus the validity period configured for the domain's URL signing. For example, if `exp` is `now + 3600`, the URL expires at `now + 3600 + 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.
// The same signing method is used for both ingest and streaming URLs.
// The AppName and StreamName can be up to 256 characters long and can contain digits, uppercase and lowercase letters, hyphens (-), underscores (_), and equal signs (=).
$uri = "rtmp://example.aliyundoc.com/liveApp/liveStream";
// The authentication key. Use the key of the ingest domain for ingest URLs and the key of the streaming domain for streaming URLs.
$key = "<input private key>";
// The URL's final expiration time is the `exp` timestamp plus the validity period configured for the domain's URL signing. For example, if `exp` is `now + 3600`, the URL expires at `now + 3600 + 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.
// The same signing method is used for both ingest and streaming URLs.
// The AppName and StreamName can be up to 256 characters long and can contain digits, uppercase and lowercase letters, hyphens (-), underscores (_), and equal signs (=).
string uri= "rtmp://example.aliyundoc.com/liveApp/liveStream";
// The authentication key. Use the key of the ingest domain for ingest URLs and the key of the streaming domain for streaming URLs.
string key= "<input private key>";
DateTime dateStart = new DateTime(1970, 1, 1, 8, 0, 0);
// The URL's final expiration time is the `exp` timestamp plus the validity period configured for the domain's URL signing. For example, if `exp` is `now + 3600`, the URL expires at `now + 3600 + 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();
}
}Ingest URL examples
Protocol | Example URL | Description |
RTMP |
| Standard protocol for live stream ingest. |
RTMPS |
| Standard protocol for secure, encrypted live stream ingest. |
ARTC |
| Ingest URL for Real-Time Streaming (RTS). |
SRT |
| SRT is disabled by default. You must enable it for the ingest domain. For instructions, see SRT stream ingest. |
Streaming URL examples
URL type | Description | Protocol | Example URL |
Standard streaming URL | If you use SRT for live stream ingest, playback is supported over RTMP, FLV, HLS, and ARTC. | RTMP |
|
FLV |
| ||
HLS |
| ||
ARTC |
| ||
Transcoded streaming URL (Default Transcoding/Custom Transcoding) | For a transcoded stream, append | RTMP |
|
FLV |
| ||
HLS |
| ||
ARTC |
| ||
Transcoded streaming URL (Multi-bitrate Transcoding) | For an adaptive bitrate stream, append | HLS |
|
Delayed stream URL | For a delayed stream, append | RTMP |
|
FLV |
| ||
HLS |
| ||
ARTC |
| ||
Live subtitles stream URL | For a stream with live subtitles, append | RTMP |
|
FLV |
| ||
HLS |
|
Verify the generated URLs
To verify your URLs, we recommend ingesting the stream with our demo app on a mobile device and using VLC media player on a PC for playback. For more ingest and playback methods, see Live stream ingest and Live stream playback:
Verify the ingest URL:
On a mobile device (Android or iOS), scan the QR code to download and install the ApsaraVideo Live demo app.
NoteOn an iOS device, if a message appears indicating an untrusted enterprise developer, go to Settings > General > VPN & Device Management, find the profile for Taobao, and tap Trust.
Open the Demo App, and select Camera or Screen Recording Ingest. Enter the ingest URL. You can scan a QR code to enter the URL that is generated in the console.


Tap Start to begin ingesting the stream.
You can view the active stream on the Stream Management page in the ApsaraVideo Live console. If the stream is not displayed, review the previous steps for errors.

Verify the streaming URL:
Keep the ingest client running. Otherwise, playback will fail.
Download and install VLC media player.
Open VLC media player.
From the menu bar, select Media > Open Network Stream.
On the Network tab, enter the streaming URL. For example:
rtmp://pull-singapore.cloud-example.net/testApp/testStream?auth_key=1750150177-0-0-9b7*******31acc543a99c69********
Troubleshooting
If you encounter issues during live stream ingest or playback, use the troubleshooting tool to validate your URL, its signing, and other settings.

