Mux.com allows you to pilot your live streams either through their dashboard or using REST API calls. In this article I will show you how to first use the Mux dashboard to create your first live stream, then I will share some C# code to illustrate how to call the Mux REST APIs and the Dolby.io APIs to start a new live stream programmatically.
Using the Mux Dashboard
Log into your Mux account and go to the VIDEO and Live Streams section.

On the Live Streams page, click on Create New Live Stream.

In the POST body editor, you can configure your live stream; check the Mux Reference documentation for more information on configuration settings. You can leave the default to start. Click the Run Request button.

Click on View Live Stream.

Click on Show Stream Key and copy it. You will need it to generate the URL of where to send the RTMP stream to. Now, during your conference, you will need to make a REST API call to the Dolby API with the URL of the RTMP endpoint, e.g. rtmps://global-live.mux.com:443/app/11111111-aaaa-2222-bbbb-333333333333
curl https://session.voxeet.com/v1/api/conferences/mix/{conference_id}/live/start \
-H "Content-Type: application/json" \
-X POST \
-d '{ "uri": "rtmps://global-live.mux.com:443/app/{stream_key}" }' \
-u {DOLBY_CONSUMER_KEY}:{DOLBY_CONSUMER_SECRET}
A few seconds after calling the API, you will be able to see the live stream starting on the Live Stream page.
If you need to stop the live stream before the conference ends, call the following API:
curl https://session.voxeet.com/v1/api/conferences/mix/{conference_id}/live/stop \
-H "Content-Type: application/json" \
-X POST \
-u {DOLBY_CONSUMER_KEY}:{DOLBY_CONSUMER_SECRET}
Note: if the conference you want to live stream is protected using enhanced conference access control, you must use a conference access token to authenticate against the APIs and point to the /v2/ endpoints (Documentation).
Using REST APIs with C#
Log into your Mux account as an administrator and go to the VIDEO and Get Started section.

Click the button Create an API Access Token, then select the environment you wish to use for your live stream. In the permissions section, for Mux Video, select Full Access. Provide a name for this token and click Generate Token. Keep this access token secure, do not expose it in your source code. Follow the Mux documentation.
Setup of the C# Code
Install the NuGet package Newtonsoft to parse the JSON payload.
Use the following imports in your C# file:
using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
Create an HttpClient
in order to make the REST API calls to both Mux.com and Dolby.io.
private static readonly HttpClient httpClient = new HttpClient();
Call the Mux API
This is the description of the payload message we will receive from the Mux API.
public sealed class DataResponse<T>
{
[JsonProperty("data")]
public T Data { get; set; }
}
public sealed class CreateLiveStreamResponse
{
[JsonProperty("id")]
public string Id { get; set; }
[JsonProperty("stream_key")]
public string StreamKey { get; set; }
}
This function will create the live stream on Mux and return the RTMP endpoint URL.
/// <summary>
/// Creates a new live stream on mux.com.
/// </summary>
/// <param name="accessTokenId">Mux Access Token ID.</param>
/// <param name="secretKey">Mux Secret Key.</param>
/// <returns>URL of the RTMP endpoint.</returns>
public async Task<string> CreateLiveStreamAsync(string accessTokenId, string secretKey)
{
// URL where to send the creation request
const string url = "https://api.mux.com/video/v1/live-streams";
// Payload to use to create and configure the live stream
// Reference: https://docs.mux.com/reference#create-a-live-stream
const string json = "{ \"playback_policy\": [\"public\"], \"new_asset_settings\": { \"playback_policy\": [\"public\"] } }";
try
{
HttpRequestMessage httpRequest = new HttpRequestMessage(HttpMethod.Post, url);
// Generate the Authorization header for the HTTP request
byte[] bytes = Encoding.UTF8.GetBytes($"{accessTokenId}:{secretKey}");
string base64 = Convert.ToBase64String(bytes);
httpRequest.Headers.TryAddWithoutValidation("Authorization", $"Basic {base64}");
httpRequest.Content = new StringContent(json, Encoding.UTF8, "application/json");
using HttpResponseMessage response = await httpClient.SendAsync(httpRequest);
response.EnsureSuccessStatusCode();
string strResponse = await response.Content.ReadAsStringAsync();
DataResponse<CreateLiveStreamResponse> createLiveStreamResponse =
JsonConvert.DeserializeObject<DataResponse<CreateLiveStreamResponse>>(strResponse);
// Generate the RTMP endpoint URL
// Source: https://docs.mux.com/docs/live-streaming#2-start-broadcasting
return $"rtmps://global-live.mux.com:443/app/{createLiveStreamResponse.Data.StreamKey}";
}
catch (Exception ex)
{
Console.WriteLine($"Exception: {ex.Message}");
throw;
}
}
Call the Dolby.io APIs for Enhanced Conference Access Control
If the conference you want to live stream is protected using enhanced conference access control, you must follow this section. Otherwise, jump to the next section.
First, create the function to request a conference access token that we will use for the REST API calls on dolby.io (Documentation).
/// <summary>
/// Requests a conference access token.
/// </summary>
/// <param name="consumerKey">Dolby.io Consumer Key.</param>
/// <param name="consumerSecret">Dolby.io Consumer Secret.</param>
/// <returns>The access token to use to call the APIs.</returns>
private async Task<string> GetAccessTokenAsync(string consumerKey, string consumerSecret)
{
const string url = "https://api.voxeet.com/v1/auth/token";
const string json = "{ \"grant_type\": \"client_credentials\" }";
try
{
HttpRequestMessage httpRequest = new HttpRequestMessage(HttpMethod.Post, url);
// Generate the Authorization header for the HTTP request
byte[] bytes = Encoding.UTF8.GetBytes($"{consumerKey}:{consumerSecret}");
string base64 = Convert.ToBase64String(bytes);
httpRequest.Headers.TryAddWithoutValidation("Authorization", $"Basic {base64}");
httpRequest.Content = new StringContent(json, Encoding.UTF8, "application/json");
using HttpResponseMessage response = await httpClient.SendAsync(httpRequest);
response.EnsureSuccessStatusCode();
string strResponse = await response.Content.ReadAsStringAsync();
JwtToken jwtToken = JsonConvert.DeserializeObject<JwtToken>(strResponse);
return jwtToken.AccessToken;
}
catch (Exception ex)
{
Console.WriteLine($"Exception: {ex.Message}");
throw;
}
}
public class JwtToken
{
[JsonProperty("access_token")]
public string AccessToken { get; set; }
[JsonProperty("expires_in")]
public int ExpiresIn { get; set; }
[JsonProperty("token_type")]
public string TokenType { get; set; }
}
Now here are the functions to start and stop the RTMP stream.
/// <summary>
/// Starts an RTMP stream.
/// </summary>
/// <param name="consumerKey">Dolby.io Consumer Key.</param>
/// <param name="consumerSecret">Dolby.io Consumer Secret.</param>
/// <param name="conferenceId">Conference identifier.</param>
/// <param name="rtmpUrl">URL of the RTMP endpoint.</param>
public async Task StartRtmpStreamAsync(string consumerKey, string consumerSecret, string conferenceId, string rtmpUrl)
{
string url = $"https://api.voxeet.com/v2/conferences/mix/{conferenceId}/rtmp/start";
string json = $"{{ \"uri\": \"{rtmpUrl}\" }}";
try
{
HttpRequestMessage httpRequest = new HttpRequestMessage(HttpMethod.Post, url);
// Generate the Authorization header for the HTTP request
string accessToken = await GetAccessTokenAsync(consumerKey, consumerSecret);
httpRequest.Headers.TryAddWithoutValidation("Authorization", $"Bearer {accessToken}");
httpRequest.Content = new StringContent(json, Encoding.UTF8, "application/json");
using HttpResponseMessage response = await httpClient.SendAsync(httpRequest);
response.EnsureSuccessStatusCode();
}
catch (Exception ex)
{
Console.WriteLine($"Exception: {ex.Message}");
throw;
}
}
/// <summary>
/// Stops an RTMP live stream.
/// </summary>
/// <param name="consumerKey">Dolby.io Consumer Key.</param>
/// <param name="consumerSecret">Dolby.io Consumer Secret.</param>
/// <param name="conferenceId">Conference identifier.</param>
public async Task StopRtmpStreamAsync(string consumerKey, string consumerSecret, string conferenceId)
{
string url = $"https://api.voxeet.com/v2/api/conferences/mix/{conferenceId}/live/stop";
try
{
HttpRequestMessage httpRequest = new HttpRequestMessage(HttpMethod.Post, url);
// Generate the Authorization header for the HTTP request
string accessToken = await GetAccessTokenAsync(consumerKey, consumerSecret);
httpRequest.Headers.TryAddWithoutValidation("Authorization", $"Bearer {accessToken}");
using HttpResponseMessage response = await httpClient.SendAsync(httpRequest);
response.EnsureSuccessStatusCode();
}
catch (Exception ex)
{
Console.WriteLine($"Exception: {ex.Message}");
throw;
}
}
Call the Dolby.io APIs Regular Conferences
If the conference you want to live stream is not protected using enhanced conference access control, you must follow this section. The only difference in the code that follows is around the authentication. We will use Basic authentication for the API calls.
/// <summary>
/// Starts an RTMP live stream.
/// </summary>
/// <param name="consumerKey">Dolby.io Consumer Key.</param>
/// <param name="consumerSecret">Dolby.io Consumer Secret.</param>
/// <param name="conferenceId">Conference identifier.</param>
/// <param name="rtmpUrl">URL of the RTMP endpoint.</param>
public async Task StartRtmpStreamAsync(string consumerKey, string consumerSecret, string conferenceId, string rtmpUrl)
{
string url = $"https://session.voxeet.com/v1/api/conferences/mix/{conferenceId}/live/start";
string json = $"{{ \"uri\": \"{rtmpUrl}\" }}";
try
{
HttpRequestMessage httpRequest = new HttpRequestMessage(HttpMethod.Post, url);
// Generate the Authorization header for the HTTP request
byte[] bytes = Encoding.UTF8.GetBytes($"{consumerKey}:{consumerSecret}");
string base64 = Convert.ToBase64String(bytes);
httpRequest.Headers.TryAddWithoutValidation("Authorization", $"Basic {base64}");
httpRequest.Content = new StringContent(json, Encoding.UTF8, "application/json");
using HttpResponseMessage response = await httpClient.SendAsync(httpRequest);
response.EnsureSuccessStatusCode();
}
catch (Exception ex)
{
Console.WriteLine($"Exception: {ex.Message}");
throw;
}
}
/// <summary>
/// Stops an RTMP live stream.
/// </summary>
/// <param name="consumerKey">Dolby.io Consumer Key.</param>
/// <param name="consumerSecret">Dolby.io Consumer Secret.</param>
/// <param name="conferenceId">Conference identifier.</param>
public async Task StopRtmpStreamAsync(string consumerKey, string consumerSecret, string conferenceId)
{
string url = $"https://session.voxeet.com/v1/api/conferences/mix/{conferenceId}/live/stop";
try
{
HttpRequestMessage httpRequest = new HttpRequestMessage(HttpMethod.Post, url);
// Generate the Authorization header for the HTTP request
byte[] bytes = Encoding.UTF8.GetBytes($"{consumerKey}:{consumerSecret}");
string base64 = Convert.ToBase64String(bytes);
httpRequest.Headers.TryAddWithoutValidation("Authorization", $"Basic {base64}");
using HttpResponseMessage response = await httpClient.SendAsync(httpRequest);
response.EnsureSuccessStatusCode();
}
catch (Exception ex)
{
Console.WriteLine($"Exception: {ex.Message}");
throw;
}
}
Test Your Code
Now that the code is ready, create a conference in your environment and call the different functions to create a live stream on Mux then start and stop the broadcast. After a few seconds, you will see the conference being broadcasted on Mux.com and a minute later it will stop.
public async Task StartAndStopAsync(string conferenceId)
{
// Store these credentials somewhere safe
const string MUX_ACCESS_TOKEN_ID = "";
const string MUX_SECRET_KEY = "";
const string DOLBY_CONSUMER_KEY = "";
const string DOLBY_CONSUMER_SECRET = "";
// Create the Live Stream on Mux.com and get the RTMP URL
string rtmpsUrl = await CreateLiveStreamAsync(MUX_ACCESS_TOKEN_ID, MUX_SECRET_KEY);
// Start the RTMP streaming from Dolby.IO to Mux.com
await StartRtmpStreamAsync(DOLBY_CONSUMER_KEY, DOLBY_CONSUMER_SECRET, conferenceId, rtmpsUrl);
// Wait a minute before stopping the RTMP stream
System.Threading.Thread.Sleep(60 * 1000);
// Stop the RTMP stream
await StopRtmpStreamAsync(DOLBY_CONSUMER_KEY, DOLBY_CONSUMER_SECRET, conferenceId);
}
Conclusion
Look for more samples soon for integrating your video conferences with various streaming platforms over RTMP.