Introduction

Integrating RTMP (Real-Time Messaging Protocol) live streaming into your JavaScript video chat application can enhance your platform's capabilities, allowing users to broadcast their video chats in real time. With RTMP, you can seamlessly stream video and audio content to various platforms such as YouTube, Twitch, or your own streaming server.

Benefits of Integrating RTMP Livestream in a JavaScript video chat app:

  • Enhanced Interactivity: RTMP allows for real-time streaming, enabling users to engage in live interactions, and making video chats more dynamic and engaging.
  • Scalability: With RTMP, your app can handle a large number of concurrent streams, ensuring scalability as your user base grows.
  • Low Latency: RTMP provides low-latency streaming, reducing the delay between sending and receiving video data, resulting in smoother conversations.

Use Cases of Integrating RTMP Livestream in a JavaScript video chat app:

  • Live Events: Broadcasting live events such as conferences, webinars, or concerts where real-time interaction with viewers is crucial.
  • Online Education: Facilitating live classes or tutoring sessions with the ability for students to ask questions and interact with the instructor in real time.
  • Virtual Meetings: Enhancing video conferencing apps with real-time streaming capabilities for more engaging and productive meetings.

This tutorial will guide you through a step-by-step process, enabling you to build a JavaScript video chat app with RTMP integration & VideoSDK.

Getting Started with VideoSDK

Before we get into implementing RTMP Live Stream functionality, let's make sure you've completed the necessary prerequisites to take advantage of it with the VideoSDK capabilities.

Create a VideoSDK Account

Go to your VideoSDK dashboard and sign up if you don't have an account. This account gives you access to the required Video SDK token, which acts as an authentication key that allows your application to interact with VideoSDK functionality.

Generate your Auth Token

Visit your VideoSDK dashboard and navigate to the "API Key" section to generate your auth token. This token is crucial in authorizing your application to use VideoSDK features. Consider referring to the provided tutorial for a more visual understanding of the account creation and token generation process.

Prerequisites

Before proceeding, ensure that your development environment meets the following requirements:

  • VideoSDK Developer Account (if you do not have one, follow VideoSDK Dashboard)
  • Have Node and NPM installed on your device.

⬇️ Install VideoSDK

Import VideoSDK using the <script> tag or install it using the following npm command. Make sure you are in your app directory before you run this command.

<html>
  <head>
    <!--.....-->
  </head>
  <body>
    <!--.....-->
    <script src="https://sdk.videosdk.live/js-sdk/0.0.83/videosdk.js"></script>
  </body>
</html>
  • npm
npm install @videosdk.live/js-sdk
  • Yarn
yarn add @videosdk.live/js-sdk

Structure of the project

Your project structure should look like this.

  root
   ├── index.html
   ├── config.js
   ├── index.js

You will be working on the following files:

  • index.html: Responsible for creating a basic UI.
  • config.js: Responsible for storing the token.
  • index.js: Responsible for rendering the meeting view and the join meeting functionality.

Essential Steps to Implement Video Call Functionality

Once you've successfully installed VideoSDK in your project, you'll have access to a range of functionalities for building your video call application. RTMP is one such feature that leverages VideoSDK's capabilities. It leverages VideoSDK's capabilities to identify the user with the strongest audio signal (the one speaking)

Step 1: Design the user interface (UI)

Create an HTML file containing the screens, join-screen and grid-screen.

<!DOCTYPE html>
<html>
  <head> </head>

  <body>
    <div id="join-screen">
      <!-- Create new Meeting Button -->
      <button id="createMeetingBtn">New Meeting</button>
      OR
      <!-- Join existing Meeting -->
      <input type="text" id="meetingIdTxt" placeholder="Enter Meeting id" />
      <button id="joinBtn">Join Meeting</button>
    </div>

    <!-- for Managing meeting status -->
    <div id="textDiv"></div>

    <div id="grid-screen" style="display: none">
      <!-- To Display MeetingId -->
      <h3 id="meetingIdHeading"></h3>

      <!-- Controllers -->
      <button id="leaveBtn">Leave</button>
      <button id="toggleMicBtn">Toggle Mic</button>
      <button id="toggleWebCamBtn">Toggle WebCam</button>

      <!-- render Video -->
      <div class="row" id="videoContainer"></div>
    </div>

    <!-- Add VideoSDK script -->
    <script src="https://sdk.videosdk.live/js-sdk/0.0.83/videosdk.js"></script>
    <script src="config.js"></script>
    <script src="index.js"></script>
  </body>
</html>

Step 2: Implement Join Screen

Configure the token in the config.js file, which you can obtain from the VideoSDK Dashbord.

// Auth token will be used to generate a meeting and connect to it
TOKEN = "Your_Token_Here";

Next, retrieve all the elements from the DOM and declare the following variables in the index.js file. Then, add an event listener to the join and create meeting buttons.

// Getting Elements from DOM
const joinButton = document.getElementById("joinBtn");
const leaveButton = document.getElementById("leaveBtn");
const toggleMicButton = document.getElementById("toggleMicBtn");
const toggleWebCamButton = document.getElementById("toggleWebCamBtn");
const createButton = document.getElementById("createMeetingBtn");
const videoContainer = document.getElementById("videoContainer");
const textDiv = document.getElementById("textDiv");

// Declare Variables
let meeting = null;
let meetingId = "";
let isMicOn = false;
let isWebCamOn = false;

function initializeMeeting() {}

function createLocalParticipant() {}

function createVideoElement() {}

function createAudioElement() {}

function setTrack() {}

// Join Meeting Button Event Listener
joinButton.addEventListener("click", async () => {
  document.getElementById("join-screen").style.display = "none";
  textDiv.textContent = "Joining the meeting...";

  roomId = document.getElementById("meetingIdTxt").value;
  meetingId = roomId;

  initializeMeeting();
});

// Create Meeting Button Event Listener
createButton.addEventListener("click", async () => {
  document.getElementById("join-screen").style.display = "none";
  textDiv.textContent = "Please wait, we are joining the meeting";

  // API call to create meeting
  const url = `https://api.videosdk.live/v2/rooms`;
  const options = {
    method: "POST",
    headers: { Authorization: TOKEN, "Content-Type": "application/json" },
  };

  const { roomId } = await fetch(url, options)
    .then((response) => response.json())
    .catch((error) => alert("error", error));
  meetingId = roomId;

  initializeMeeting();
});

Step 3: Initialize Meeting

Following that, initialize the meeting using the initMeeting() function and proceed to join the meeting.

// Initialize meeting
function initializeMeeting() {
  window.VideoSDK.config(TOKEN);

  meeting = window.VideoSDK.initMeeting({
    meetingId: meetingId, // required
    name: "Thomas Edison", // required
    micEnabled: true, // optional, default: true
    webcamEnabled: true, // optional, default: true
  });

  meeting.join();

  // Creating local participant
  createLocalParticipant();

  // Setting local participant stream
  meeting.localParticipant.on("stream-enabled", (stream) => {
    setTrack(stream, null, meeting.localParticipant, true);
  });

  // meeting joined event
  meeting.on("meeting-joined", () => {
    textDiv.style.display = "none";
    document.getElementById("grid-screen").style.display = "block";
    document.getElementById(
      "meetingIdHeading"
    ).textContent = `Meeting Id: ${meetingId}`;
  });

  // meeting left event
  meeting.on("meeting-left", () => {
    videoContainer.innerHTML = "";
  });

  // Remote participants Event
  // participant joined
  meeting.on("participant-joined", (participant) => {
    //  ...
  });

  // participant left
  meeting.on("participant-left", (participant) => {
    //  ...
  });
}

Step 4: Create the Media Elements

In this step, Create a function to generate audio and video elements for displaying both local and remote participants. Set the corresponding media track based on whether it's a video or audio stream.

// creating video element
function createVideoElement(pId, name) {
  let videoFrame = document.createElement("div");
  videoFrame.setAttribute("id", `f-${pId}`);
  videoFrame.style.width = "300px";
    

  //create video
  let videoElement = document.createElement("video");
  videoElement.classList.add("video-frame");
  videoElement.setAttribute("id", `v-${pId}`);
  videoElement.setAttribute("playsinline", true);
  videoElement.setAttribute("width", "300");
  videoFrame.appendChild(videoElement);

  let displayName = document.createElement("div");
  displayName.innerHTML = `Name : ${name}`;

  videoFrame.appendChild(displayName);
  return videoFrame;
}

// creating audio element
function createAudioElement(pId) {
  let audioElement = document.createElement("audio");
  audioElement.setAttribute("autoPlay", "false");
  audioElement.setAttribute("playsInline", "true");
  audioElement.setAttribute("controls", "false");
  audioElement.setAttribute("id", `a-${pId}`);
  audioElement.style.display = "none";
  return audioElement;
}

// creating local participant
function createLocalParticipant() {
  let localParticipant = createVideoElement(
    meeting.localParticipant.id,
    meeting.localParticipant.displayName
  );
  videoContainer.appendChild(localParticipant);
}

// setting media track
function setTrack(stream, audioElement, participant, isLocal) {
  if (stream.kind == "video") {
    isWebCamOn = true;
    const mediaStream = new MediaStream();
    mediaStream.addTrack(stream.track);
    let videoElm = document.getElementById(`v-${participant.id}`);
    videoElm.srcObject = mediaStream;
    videoElm
      .play()
      .catch((error) =>
        console.error("videoElem.current.play() failed", error)
      );
  }
  if (stream.kind == "audio") {
    if (isLocal) {
      isMicOn = true;
    } else {
      const mediaStream = new MediaStream();
      mediaStream.addTrack(stream.track);
      audioElement.srcObject = mediaStream;
      audioElement
        .play()
        .catch((error) => console.error("audioElem.play() failed", error));
    }
  }
}

Step 5: Handle participant events

Thereafter, implement the events related to the participants and the stream.

The following are the events to be executed in this step:

  1. participant-joined: When a remote participant joins, this event will trigger. In the event callback, create video and audio elements previously defined for rendering their video and audio streams.
  2. participant-left: When a remote participant leaves, this event will trigger. In the event callback, remove the corresponding video and audio elements.
  3. stream-enabled: This event manages the media track of a specific participant by associating it with the appropriate video or audio element.
// Initialize meeting
function initializeMeeting() {
  // ...

  // participant joined
  meeting.on("participant-joined", (participant) => {
    let videoElement = createVideoElement(
      participant.id,
      participant.displayName
    );
    let audioElement = createAudioElement(participant.id);
    // stream-enabled
    participant.on("stream-enabled", (stream) => {
      setTrack(stream, audioElement, participant, false);
    });
    videoContainer.appendChild(videoElement);
    videoContainer.appendChild(audioElement);
  });

  // participants left
  meeting.on("participant-left", (participant) => {
    let vElement = document.getElementById(`f-${participant.id}`);
    vElement.remove(vElement);

    let aElement = document.getElementById(`a-${participant.id}`);
    aElement.remove(aElement);
  });
}

Step 6: Implement Controls

Next, implement the meeting controls, such as toggleMic, toggleWebcam, and leave the meeting.

// leave Meeting Button Event Listener
leaveButton.addEventListener("click", async () => {
  meeting?.leave();
  document.getElementById("grid-screen").style.display = "none";
  document.getElementById("join-screen").style.display = "block";
});

// Toggle Mic Button Event Listener
toggleMicButton.addEventListener("click", async () => {
  if (isMicOn) {
    // Disable Mic in Meeting
    meeting?.muteMic();
  } else {
    // Enable Mic in Meeting
    meeting?.unmuteMic();
  }
  isMicOn = !isMicOn;
});

// Toggle Web Cam Button Event Listener
toggleWebCamButton.addEventListener("click", async () => {
  if (isWebCamOn) {
    // Disable Webcam in Meeting
    meeting?.disableWebcam();

    let vElement = document.getElementById(`f-${meeting.localParticipant.id}`);
    vElement.style.display = "none";
  } else {
    // Enable Webcam in Meeting
    meeting?.enableWebcam();

    let vElement = document.getElementById(`f-${meeting.localParticipant.id}`);
    vElement.style.display = "inline";
  }
  isWebCamOn = !isWebCamOn;
});

You can check out the complete guide here:

quickstart/js-rtc at main · videosdk-live/quickstart
A short and sweet tutorial for getting up to speed with VideoSDK in less than 10 minutes - videosdk-live/quickstart
Video SDK Image

After you've installed the video SDK in your video call application, you're ready to explore the exciting world of RTMP live streaming. RTMP is a popular protocol designed specifically for real-time video and audio transmission. This enables broadcasters to share live experiences, host presentations, or run live tutorials within your app, expanding its reach and functionality.

Integrate RTMP Livestream

RTMP is a widely used protocol for live streaming video content from VideoSDK to platforms like YouTube, Twitch, Facebook, and others.

To initiate live streaming from VideoSDK to platforms supporting RTMP ingestion, you simply need to provide the platform-specific stream key and stream URL. This enables VideoSDK to connect to the platform's RTMP server and transmit the live video stream.

Furthermore, VideoSDK offers flexibility in configuring livestream layouts. You can achieve this by either selecting different prebuilt layouts in the configuration or by providing your own custom template for live streaming, catering to your specific layout preferences.

This guide will provide an overview of how to implement starting and stopping RTMP live streaming with VideoSDK.

Start Live Stream

The startLivestream() method, accessible from the meeting object, is used to initiate the RTMP live stream of a meeting. This method accepts the following two parameters:

  • 1. outputs: This parameter takes an array of objects containing the RTMP url and streamKey specific to the platform where you want to initiate the live stream.
  • 2. config (optional): This parameter defines the layout configuration for the live stream.
let meeting;

// Initialize Meeting
meeting = VideoSDK.initMeeting({
  // ...
});

const startLivestreamBtn = document.getElementById("startLivestreamBtn");
startLivestreamBtn.addEventListener("click", () => {
  // Start Livestream
  meeting?.startLivestream(
    [
      {
        url: "rtmp://a.rtmp.youtube.com/live2",
        streamKey: "key",
      },
    ],
    {
      layout: {
        type: "GRID",
        priority: "SPEAKER",
        gridSize: 4,
      },
      theme: "DARK",
    }
  );
});

Stop Live Stream

The stopLivestream() method, accessible from the meeting object is used to stop the RTMP live stream of a meeting.

let meeting;

// Initialize Meeting
meeting = VideoSDK.initMeeting({
  // ...
});


const stopLivestreamBtn = document.getElementById("stopLivestreamBtn");
stopLivestreamBtn.addEventListener("click", () => {
  // Stop Livestream
  meeting?.stopLivestream();
});

Event associated with Livestream

  • livestream-state-changed: Whenever a livestream state changes, then livestream-state-changed the event will trigger.
let meeting;

// Initialize Meeting
meeting = VideoSDK.initMeeting({
  // ...
});

const Constants = VideoSDK.Constants;

meeting.on("livestream-state-changed", (data) => {
  const { status } = data;

  if (status === Constants.livestreamEvents.LIVESTREAM_STARTING) {
    console.log("Meeting livestream is starting");
  } else if (status === Constants.livestreamEvents.LIVESTREAM_STARTED) {
    console.log("Meeting livestream is started");
  } else if (status === Constants.livestreamEvents.LIVESTREAM_STOPPING) {
    console.log("Meeting livestream is stopping");
  } else if (status === Constants.livestreamEvents.LIVESTREAM_STOPPED) {
    console.log("Meeting livestream is stopped");
  } else {
    //
  }
});

Custom Template

With VideoSDK, you have the option to employ your own custom-designed layout template for livestreaming a meeting. To use a custom template, follow this guide to create and set up the template. Once the template is configured, you can initiate recording using the REST API, specifying the templateURL parameter.

✨ Want to Add More Features to JavaScript Video Calling App?

If you found this guide helpful and want to explore more features for your JavaScript video-calling app,

Check out these additional resources:

  • Active Speaker Indication: Link
  • Image Capture: Link
  • Screen Share Feature: Link
  • Picture-in-Picture (PiP) Mode: Link

Conclusion

Whether it's for hosting live events, broadcasting presentations, or enabling interactive streaming sessions, RTMP Livestream opens up new possibilities for your app. Take your video chat app to the next level with VideoSDK and empower your users with high-quality live streaming. Get started today and revolutionize your app's video capabilities

If you are new here and want to build an interactive JavaScript app with free resources, you can Sign up with VideoSDK and get? 10000 free minutes every month. This will help your new video-calling app go to the next level without any costs associated with initial usage, allowing you to focus on building and scaling your application effectively.