SIGN UP

Streaming introduction

Streaming introduction

Today streaming platforms are on hype, as a host of talents around the globe tend to share their knowledge and make the maximum fun of it on a regular basis. As this market has been growing rapidly, there are tons of applications that can livestream video using your smartphone’s or notebook’s camera.

Perhaps you’re willing to implement a streaming functionality in your communication app too; if so, we’re glad to announce that Voximplant now allows developers to forward video calls over RTMP to any live streaming CDNs which support this protocol. Look at the scheme below:

A video call initiated from within a Web/Mobile application or SIP device goes to our cloud, which forwards the data stream to a CDN. A CDN provider sends audio and video streams to its end users, as typically does. Pay attention that RTMP supports only the H.264 codec, so it is crucial to specify it for streaming purposes.  

Such functionality became possible due to a new VoxEngine module that is called StreamingAgent. Follow this guide to learn the basics of this integration in just 5 steps.

WHAT YOU NEED

You will need:

  • Live streaming CDN account, e.g, Twitch or Youtube 
  • Voximplant developer account. If you don’t have one, sign up here.
  • Voximplant application, JS scenario, rule, and a user. Those will be created during this tutorial.
  • Web client to capture video and audio, we’ll use our videochat demo.

1. STREAMING ACCOUNT SETTINGS

We need to obtain two parameters from a streaming account in order to use them in a Voximplant JS scenario: stream name/key and server URL. The steps below show how to retrieve these values on examples of Twitch and YouTube.

 

Twitch

Log in to your account, then click to your profile picture in the top right corner and choose Video Producer.

Here, switch to the Channel tab in the Settings block, then click Copy at the top of the page to get your Primary Stream Key. Note that the key is available only for accounts with enabled two-factor authentication. Paste this value into your local text editor or leave this page open to copy-paste the value to a scenario further.

To find the server url value, visit https://stream.twitch.tv/ingests/, choose one of the recommended endpoints and copy it without the last slash, like this: rtmp://live-sfo.twitch.tv/app 

Similarly, either save this string locally or leave the page open.

 

YouTube

Log in to your account, then click to your profile picture in the top right corner and choose YouTube Studio (beta).

If you don’t have a YouTube channel, a special dialog will appear. Click Create channel and you’ll see the dashboard with the notification that you’ll be available to livestream within 24 hours.

Being in the YouTube Studio, choose Other features —> Live stream now on the left menu. A new page will open with the Encoder setup block at the bottom. You have to copy Server URL and Stream name/key values (or leave this page open for now).

2. VOXIMPLANT APPLICATION SETTINGS

Let’s set up the Voximplant side. First, log in to your account here: https://manage.voximplant.com/auth. On the left menu, select Applications, click New application and create a streaming application. Then go to your new application, switch to the Scenarios tab, and create a startStream scenario with the following code. Don't forget to substitute your streaming values retrieved in the previous step in lines 8 and 9.

require(Modules.StreamingAgent);

VoxEngine.setVideoCodec("H264");

VoxEngine.addEventListener(AppEvents.CallAlerting, function (e) {
  const streaming = VoxImplant.createStreamingAgent({
    protocol: "RTMP",
    url: "rtmp://live-sfo.twitch.tv/app",
    streamName: "live_********************",
    keyframeInterval: 4
  });

  e.call.sendMediaTo(streaming);

  streaming.addEventListener(StreamingAgentEvents.Connected, function (e) {
    Logger.write("LOG: StreamingAgentEvents.Connected: " + e.reason);
  });
  streaming.addEventListener(StreamingAgentEvents.Disconnected, function (e) {
    Logger.write("LOG: StreamingAgentEvents.Disconnected: " + e.reason);
  });
  streaming.addEventListener(StreamingAgentEvents.ConnectionFailed, function (e) {
    Logger.write("LOG: StreamingAgentEvents.ConnectionFailed: " + e.reason);
  });
  streaming.addEventListener(StreamingAgentEvents.Error, function (e) {
    Logger.write("LOG: StreamingAgentEvents.Error: " + e.reason);
  });
  streaming.addEventListener(StreamingAgentEvents.StreamStarted, function (e) {
    Logger.write("LOG: StreamingAgentEvents.StreamStarted: " + e.reason);
  });
  streaming.addEventListener(StreamingAgentEvents.StreamError, function (e) {
    Logger.write("LOG: StreamingAgentEvents.StreamError: " + e.reason);
  });
  streaming.addEventListener(StreamingAgentEvents.StreamStopped, function (e) {
    Logger.write("LOG: StreamingAgentEvents.StreamStopped: " + e.reason);
  });

  e.call.answer();

  e.call.addEventListener(CallEvents.Disconnected, function (e) {
    Logger.write("LOG: terminating in 6 secs");
    setTimeout(VoxEngine.terminate, 6000);
  });
});

This is a simple scenario that starts a stream and also tracks all possible streaming conditions, such as Connected, Connection failed, StreamStarted, etc. We’ll discuss this scenario nuances below. As for now, switch to the Routing tab of your streaming application and click New rule. Name it streamRule; use the created JS scenario in the rule and leave the default call pattern ( .* ).

The last action to perform here is to create a user for your application. Switch to the Users tab, click Create user, set username (e.g., user1) and password, then click Create. We’ll need this login-password pair to authenticate in the web client.

The configuration is ready for action, but first, let’s dive into how the StreamingAgent module actually works in our scenario.

3. SCENARIO DETAILS

The StreamingAgent enables developers to start live streams over RTMP via popular streaming platforms. To use the module in our scenario, we have to mount it at the very beginning of the scenario:

require(Modules.StreamingAgent);

Next, we have to explicitly specify the codec which will be used for streaming. Since Twitch and YouTube both use RTMP for delivering streams, which in turn uses H.264, we should specify this codec:

VoxEngine.setVideoCodec("H264");

If the codec is not specified, it could envoke the StreamingAgentEvents.StreamError event with the following text:

"Video codec mismatch. " + codecName + " granted, but should be H.264"

Next, we add a handler for the CallAlerting event to handle a call from our web client (remember, we’ll get it a bit later in this article). First and foremost, we call the createStreamingAgent method. This method allows specifying the following parameters, most of them are required, optional ones are marked appropriately:

  • protocol – currently only RMTP is supported
  • url – server URL, see step 1
  • streamName – stream name/key, see step 1
  • applicationName (optional) – the part of streamName, e.g, live2. The parameter is platform dependent, use it if it's required by your streaming platform
  • keyframeInterval (optional, seconds) – how often a keyframe in a stream will be created. If not specified, it’s 2 by default

In the full scenario listing above, the createStreamingAgent call looks like this:

VoxEngine.addEventListener(AppEvents.CallAlerting, function (e) {
  const streaming = VoxImplant.createStreamingAgent({
    protocol: "RTMP",
    url: "rtmp://live-sfo.twitch.tv/app",
    streamName: "live_********************",
    keyframeInterval: 4
  });

But we can omit keyframeInterval and also use applicationName, like this:

VoxEngine.addEventListener(AppEvents.CallAlerting, function (e) {
  const streaming = VoxImplant.createStreamingAgent({
    protocol: "RTMP",
    url: "rtmp://a.rtmp.youtube.com/",
    applicationName: "live2",
    streamName: "somename"
  });

After the streaming object is created, we continue to manage the call inside a handler. Next, we send the incoming call data to the created streaming object:

e.call.sendMediaTo(streaming);

Then we use all possible streaming events for debugging purposes: the appropriate handlers do nothing but write info to a session log. You are free to get rid of them if you want to.

After the events handling part, we answer an incoming call:

e.call.answer();

Finally, we should add proper handling for stream ending when the web client stops sending video. Technically speaking, we can omit this handler too, but in such a case the Voximplant session will terminate only in 60 seconds after the web client stops translation. Waiting for it doesn’t make sense, so it’s better to terminate sessions based on the Disconnected event:

e.call.addEventListener(CallEvents.Disconnected, function (e) {
    Logger.write("LOG: terminating in 6 secs");
    setTimeout(VoxEngine.terminate, 6000);
  });

Understanding the scenario logic, we are ready to prepare the last (but not least) part of our configuration.

4. WEB CLIENT

Simply clone or download our videochat demo. Then go to the target folder and open the WebApp/JS/app.js file in your text editor/IDE. Change the name of application on line 5 to streaming and save the file:

Well, that’s it.

5. HOW TO USE IT

Now you have to run the WebApp folder either locally or put in on your web server. To run a folder as a local server, you can use live-server or Web Server for Chrome.

You have to pass your Voximplant account name to the running web client, like this: http://127.0.0.1:8080/index.html#accname=johngalt

Enter the login-password pair of the user created in step 2:

Finally, enter an arbitrary string next to the @ symbol and click Call. If everything went properly, your stream will begin in just no time :) Enjoy our new functionality, have fun and stay up to date. 

Tags:voxenginestreamingtwitchyoutubeRTMP
B6A24216-9891-45D1-9D1D-E7359CEB8282 Created with sketchtool.

Comments(0)

Add your comment

Please complete this field.

Recommended

Sign up for a free Voximplant developer account or talk to our experts
SIGN UP