End of Life for Twilio Programmable Video - Upgrade to VideoSDKLearn More

How to Build Dendrite WebRTC App with Go?

Learn how to set up and implement Dendrite WebRTC for secure, decentralized communication using the Matrix protocol. Step-by-step instructions and practical examples included.

Introduction to Dendrite WebRTC Technology

In the realm of real-time communications, the integration of decentralized systems is becoming increasingly significant. One such powerful combination is Dendrite, an implementation of the Matrix protocol, and WebRTC, a technology enabling peer-to-peer communication. Understanding the synergy between these two can open doors to creating robust, secure, and decentralized communication applications.

Overview of Dendrite and WebRTC

Dendrite is a second-generation Matrix homeserver written in Go, designed to support the decentralized, secure communication protocol defined by Matrix. It aims to provide a scalable and efficient alternative to Synapse, the original Matrix homeserver. Dendrite’s lightweight architecture and modern codebase make it an ideal choice for developers looking to build on the Matrix protocol.
WebRTC (Web Real-Time Communication) is an open-source project that enables web applications and sites to capture, and potentially broadcast, audio and/or video media. It also allows peer-to-peer data sharing and teleconferencing. WebRTC is a powerful tool for real-time communication, providing the foundation for video chat applications, file sharing services, and more, all without the need for intermediary servers.

What is Dendrite WebRTC?

Dendrite WebRTC represents the intersection of Dendrite’s decentralized communication capabilities and WebRTC’s real-time media communication strengths. By leveraging Dendrite, developers can build applications that benefit from Matrix’s secure and decentralized messaging features, while WebRTC adds the capability of real-time video, audio, and data communication.
The combination of these technologies ensures that communication remains secure, private, and decentralized, avoiding reliance on central servers that can become points of failure or targets for attacks. With Dendrite WebRTC, users can enjoy seamless, real-time interactions that are both secure and resilient, making it an ideal choice for applications requiring robust communication infrastructure.
In the following sections, we will delve into the practical aspects of setting up and implementing a Dendrite WebRTC application. From initial configuration to running your first application, this guide will provide step-by-step instructions to help you harness the power of these technologies effectively.

Getting Started with the Code

Building a Dendrite WebRTC application involves several key steps, starting from setting up the development environment to understanding the structure and architecture of the project. This section provides a comprehensive guide to get you started with your Dendrite WebRTC application.

Create a New Dendrite WebRTC App

The first step in building your Dendrite WebRTC application is setting up your development environment. Ensure you have Go installed on your system, as Dendrite is written in Go.

[a] Install Go

  • Download and install the latest version of Go from

    golang.org

    .
  • Verify the installation by running go version in your terminal.

[b] Clone the Dendrite Repository

Open your terminal and run:

sh

1     git clone https://github.com/matrix-org/dendrite
2     cd dendrite

Install Dependencies

Dendrite requires several dependencies to run correctly. These include database systems like PostgreSQL and some Go packages.

[a] Install PostgreSQL

Follow the installation instructions for PostgreSQL from

postgresql.org

. Start the PostgreSQL service and create a new database for Dendrite.

[b] Install Go Packages

In your terminal, navigate to the Dendrite directory and run:

sh

1     go get -u ./...

Structure of the Project

Understanding the structure of your Dendrite project is crucial for effective development. Here's a brief overview of the key directories and files:
  • cmd/: Contains the main binaries for running Dendrite.
  • internal/: Contains internal packages and libraries used by Dendrite.
  • scripts/: Utility scripts for various tasks.
  • config/: Configuration files for different environments.
  • tests/: Unit and integration tests.
Each of these directories serves a specific purpose, helping to organize the code and resources efficiently.

App Architecture

dendrite webrtc
The architecture of a Dendrite WebRTC application is designed to be modular and scalable. Key components include:
  1. Federation: Handles communication between different Matrix servers.
  2. Client-Server API: Manages interactions between clients and the server.
  3. Media Repository: Stores and serves media files.
  4. Sync API: Keeps clients updated with the latest state of the server.
Each component communicates through well-defined interfaces, ensuring a clean separation of concerns and facilitating easier maintenance and scalability.

Setting Up the Development Environment

Before you start coding, ensure that your development environment is correctly set up. This involves configuring environment variables, setting up your database, and ensuring all dependencies are correctly installed.

Configure Environment Variables

Create a .env file in your project root with the necessary environment variables for Dendrite and PostgreSQL.

Initialize the Database

Use the provided scripts to initialize your PostgreSQL database with the necessary schemas and data.

Run the Initial Setup

In your terminal, navigate to the Dendrite directory and run:

sh

1     go run ./cmd/dendrite-monolith-server --config config/dendrite.yaml
By following these steps, you will have a basic setup ready to start building your Dendrite WebRTC application. The next sections will guide you through specific implementation steps, including configuring Dendrite, creating user interfaces, and adding communication features.

Step 1: Get Started with the Configuration

With your development environment set up, the next step is to configure Dendrite for WebRTC functionality. This involves adjusting configuration files and settings to ensure seamless operation of your Dendrite WebRTC application.

Configuring Dendrite

Dendrite requires specific configurations to operate correctly, particularly for WebRTC features. The main configuration file for Dendrite is dendrite.yaml. Here’s how you can set it up:

[a] Locate the Configuration File

The primary configuration file, dendrite.yaml, is located in the config directory of your project.

[b] Edit the Configuration File

Open dendrite.yaml in your preferred text editor.

[c] Database Configuration

Ensure your PostgreSQL database settings are correctly configured:

YAML

1     database:
2       account: postgresql://username:password@localhost/dendrite
3       media_api: postgresql://username:password@localhost/dendrite
4       sync_api: postgresql://username:password@localhost/dendrite
5       room_server: postgresql://username:password@localhost/dendrite
6       federation_sender: postgresql://username:password@localhost/dendrite
7       key_server: postgresql://username:password@localhost/dendrite
8       server_key: postgresql://username:password@localhost/dendrite

[d] Set Up WebRTC Signaling

Configure WebRTC signaling servers. Dendrite can use a STUN/TURN server to facilitate peer-to-peer connections:

YAML

1     webrtc:
2       stun_servers:
3         - "stun:stun.l.google.com:19302"
4       turn_servers:
5         - url: "turn:turn.example.com:3478"
6           username: "user"
7           password: "pass"

[e] Federation Settings

Ensure your server is correctly set up to federate with other Matrix servers:

YAML

1     federation:
2       enabled: true
3       server_name: "your.server.name"
4       key_file: "path/to/server.key"
5       cert_file: "path/to/server.crt"

[f] Client API Settings

Configure the client API to handle WebRTC signaling messages:

YAML

1     client_api:
2       listen: "0.0.0.0:8008"
3       tls_cert_path: "path/to/tls.crt"
4       tls_key_path: "path/to/tls.key"

Important Configuration Settings for WebRTC

To ensure your Dendrite WebRTC setup is optimal, pay attention to these key settings:

STUN/TURN Servers

STUN servers help clients discover their public IP addresses, while TURN servers relay data when direct peer-to-peer connections are not possible. Using reliable STUN/TURN servers ensures better connectivity.

Federation

Enabling federation allows your Dendrite server to communicate with other Matrix servers, broadening the scope of your application and ensuring interoperability.

Security

Ensure your configuration includes proper TLS/SSL certificates to secure communications between clients and servers. This is critical for maintaining the privacy and integrity of data.

Performance

Optimize database connections and other performance-related settings based on your server’s capacity and expected load. Efficient configuration will help in handling multiple WebRTC connections smoothly.
By carefully configuring these settings, you can ensure your Dendrite WebRTC application is secure, efficient, and capable of providing robust real-time communication. In the next part, we will explore how to wireframe all the components for your application, providing a clear blueprint for implementation.

Step 2: Wireframe All the Components

Creating a wireframe is a crucial step in the development process as it provides a visual blueprint of your application. This section will guide you through the process of planning and designing the user interface (UI) components necessary for a Dendrite WebRTC application.

Planning the Interface

Before diving into the code, it’s essential to have a clear idea of what your application will look like and how users will interact with it. A wireframe helps you visualize the structure and flow of the application.

Identify Key Components

  • Join Screen: A screen where users can enter a room or initiate a call.
  • Controls: Buttons for functionalities like mute/unmute, start/stop video, and end call.
  • Participant View: Display of all participants in a call, including their video streams.
  • Chat Box: Optional text chat feature for messages alongside video communication.

Sketch the Layout

Use tools like Balsamiq, Sketch, or even pen and paper to sketch the layout of your application. Focus on placement and size of components.
Example Layout:
1 - **Header**: Logo and navigation options.
2 - **Main Area**: Split into sections for video streams and controls.
3 - **Sidebar**: Optional for additional features like a participant list or chat.

Key Components to Include in the Wireframe

Join Screen

  • Fields: Room ID, Username.
  • Buttons: Join Room.
  • Status Messages: Error messages or connection status.

Main Interface

  • Video Area: Grid of participant video streams.
  • Control Bar: Buttons for mute/unmute, video on/off, and end call.

Participant View

  • Video Stream: Display of each participant’s video.
  • Name Labels: Participant names below video streams.
  • Status Indicators: Icons for mute/unmute status.

Chat Box (Optional)

  • Message Input: Text field for entering messages.
  • Message Display: Area showing the chat history.

Tools for Creating Wireframes

  • Balsamiq: A user-friendly wireframing tool ideal for quick sketches.
  • Sketch: A more advanced design tool for detailed UI design.
  • Figma: A collaborative design tool that allows real-time collaboration and detailed wireframing.

Finalizing the Wireframe

After sketching the wireframe, review it to ensure all necessary components are included and properly placed. Share the wireframe with your team or stakeholders for feedback and make adjustments as needed.
By creating a detailed wireframe, you establish a clear plan for your Dendrite WebRTC application’s user interface. This visual guide will make the implementation phase smoother and ensure that all essential components are accounted for. In the next section, we will start implementing the join screen, bringing your wireframe to life with code.

Step 3: Implement Join Screen

With a clear wireframe in place, the next step is to start bringing your design to life. We'll begin by implementing the join screen, which serves as the entry point for users to connect to a Dendrite WebRTC session. This section provides step-by-step instructions and code snippets to help you create a functional and user-friendly join screen.

Developing the Join Screen

The join screen is where users will enter the necessary information to join a WebRTC session. This typically includes fields for a room ID and a username, along with a button to initiate the connection.

Setting Up the Project

[a] Initialize the Project

Make sure you are in the project directory. Initialize a new Go module if you haven't already:

sh

1     go mod init dendrite-webrtc-app

[b] Create the HTML Template

Create a file named index.html in the templates directory. This file will contain the HTML structure for the join screen.

HTML

1     <!DOCTYPE html>
2     <html lang="en">
3     <head>
4         <meta charset="UTF-8">
5         <meta name="viewport" content="width=device-width, initial-scale=1.0">
6         <title>Join Room</title>
7         <link rel="stylesheet" href="/static/style.css">
8     </head>
9     <body>
10         <div class="container">
11             <h1>Join a WebRTC Room</h1>
12             <form id="join-form">
13                 <label for="room-id">Room ID:</label>
14                 <input type="text" id="room-id" name="room-id" required>
15                 
16                 <label for="username">Username:</label>
17                 <input type="text" id="username" name="username" required>
18                 
19                 <button type="submit">Join Room</button>
20             </form>
21             <div id="status-message"></div>
22         </div>
23         <script src="/static/script.js"></script>
24     </body>
25     </html>

[c] Create the CSS File

Create a file named style.css in the static directory to style the join screen.

CSS

1     body {
2         font-family: Arial, sans-serif;
3         display: flex;
4         justify-content: center;
5         align-items: center;
6         height: 100vh;
7         background-color: #f0f0f0;
8         margin: 0;
9     }
10
11     .container {
12         background: white;
13         padding: 20px;
14         border-radius: 8px;
15         box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
16     }
17
18     h1 {
19         margin-bottom: 20px;
20     }
21
22     label {
23         display: block;
24         margin: 10px 0 5px;
25     }
26
27     input {
28         width: 100%;
29         padding: 8px;
30         box-sizing: border-box;
31         margin-bottom: 10px;
32     }
33
34     button {
35         padding: 10px 20px;
36         background-color: #007bff;
37         color: white;
38         border: none;
39         border-radius: 4px;
40         cursor: pointer;
41     }
42
43     button:hover {
44         background-color: #0056b3;
45     }
46
47     #status-message {
48         margin-top: 20px;
49         color: red;
50     }

[d] Create the JavaScript File

Create a file named script.js in the static directory to handle form submission.

JavaScript

1     document.getElementById('join-form').addEventListener('submit', function (e) {
2         e.preventDefault();
3
4         const roomId = document.getElementById('room-id').value;
5         const username = document.getElementById('username').value;
6
7         if (roomId && username) {
8             // Implement the logic to join the room here
9             // Example: Redirect to the room page
10             window.location.href = `/room.html?roomId=${roomId}&username=${username}`;
11         } else {
12             document.getElementById('status-message').textContent = 'Please enter both Room ID and Username.';
13         }
14     });

[e] Create the Go Server

Create a file named main.go to serve the HTML, CSS, and JavaScript files, and handle form submissions.

GO

1     package main
2
3     import (
4         "html/template"
5         "log"
6         "net/http"
7         "path/filepath"
8     )
9
10     func main() {
11         http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
12             tmpl, err := template.ParseFiles(filepath.Join("templates", "index.html"))
13             if err != nil {
14                 http.Error(w, err.Error(), http.StatusInternalServerError)
15                 return
16             }
17             tmpl.Execute(w, nil)
18         })
19
20         // Serve static files
21         http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static"))))
22
23         log.Println("Server started at :8080")
24         log.Fatal(http.ListenAndServe(":8080", nil))
25     }

Explanation of the Code

HTML Template (index.html)

  • Provides the structure of the join screen with input fields for the room ID and username, and a submit button.
  • Includes links to the CSS and JavaScript files for styling and functionality.

CSS File (style.css)

  • Styles the join screen to make it visually appealing and user-friendly.
  • Uses flexbox to center the form on the page and adds basic styling for input fields and buttons.

JavaScript File (script.js)

  • Handles form submission by preventing the default behavior and validating input fields.
  • Redirects to a room page with the room ID and username as query parameters if inputs are valid.

Go Server (main.go)

  • Serves the HTML template and static files (CSS and JavaScript).
  • Listens on port 8080 for incoming requests and logs server activity.
By following these steps and understanding the code, you have successfully implemented a join screen for your Dendrite WebRTC application. This screen allows users to enter the necessary details to join a WebRTC session. In the next part, we will focus on implementing the controls for the WebRTC functionality, including mute/unmute and start/stop video features.

Step 4: Implement Controls

In this section, we will add functionality to the Dendrite WebRTC application by implementing control features. These controls will allow users to manage their WebRTC session by muting/unmuting their microphone, starting/stopping their video, and ending the call. We will add buttons to the interface and use JavaScript to handle their functionality.

Adding Control Features

The control bar will include buttons for the following actions:
  • Mute/Unmute microphone
  • Start/Stop video
  • End call

[a] Updating the HTML Template

First, update the index.html file to include the control buttons.

HTML

1<!DOCTYPE html>
2<html lang="en">
3<head>
4    <meta charset="UTF-8">
5    <meta name="viewport" content="width=device-width, initial-scale=1.0">
6    <title>Join Room</title>
7    <link rel="stylesheet" href="/static/style.css">
8</head>
9<body>
10    <div class="container">
11        <h1>Join a WebRTC Room</h1>
12        <form id="join-form">
13            <label for="room-id">Room ID:</label>
14            <input type="text" id="room-id" name="room-id" required>
15            
16            <label for="username">Username:</label>
17            <input type="text" id="username" name="username" required>
18            
19            <button type="submit">Join Room</button>
20        </form>
21        <div id="status-message"></div>
22    </div>
23
24    <!-- Control bar for WebRTC session -->
25    <div class="controls" id="controls" style="display: none;">
26        <button id="mute-btn">Mute</button>
27        <button id="video-btn">Stop Video</button>
28        <button id="end-call-btn">End Call</button>
29    </div>
30
31    <script src="/static/script.js"></script>
32</body>
33</html>

[b] Updating the CSS File

Next, update the style.css file to style the control buttons.

CSS

1body {
2    font-family: Arial, sans-serif;
3    display: flex;
4    justify-content: center;
5    align-items: center;
6    height: 100vh;
7    background-color: #f0f0f0;
8    margin: 0;
9}
10
11.container {
12    background: white;
13    padding: 20px;
14    border-radius: 8px;
15    box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
16}
17
18h1 {
19    margin-bottom: 20px;
20}
21
22label {
23    display: block;
24    margin: 10px 0 5px;
25}
26
27input {
28    width: 100%;
29    padding: 8px;
30    box-sizing: border-box;
31    margin-bottom: 10px;
32}
33
34button {
35    padding: 10px 20px;
36    background-color: #007bff;
37    color: white;
38    border: none;
39    border-radius: 4px;
40    cursor: pointer;
41}
42
43button:hover {
44    background-color: #0056b3;
45}
46
47#status-message {
48    margin-top: 20px;
49    color: red;
50}
51
52.controls {
53    margin-top: 20px;
54}
55
56.controls button {
57    margin-right: 10px;
58}

[c] Adding JavaScript Functionality

Now, update the script.js file to handle the functionality of the control buttons.

JavaScript

1document.getElementById('join-form').addEventListener('submit', function (e) {
2    e.preventDefault();
3
4    const roomId = document.getElementById('room-id').value;
5    const username = document.getElementById('username').value;
6
7    if (roomId && username) {
8        // Implement the logic to join the room here
9        // Example: Redirect to the room page
10        window.location.href = `/room.html?roomId=${roomId}&username=${username}`;
11    } else {
12        document.getElementById('status-message').textContent = 'Please enter both Room ID and Username.';
13    }
14});
15
16// WebRTC control buttons
17let isMuted = false;
18let isVideoStopped = false;
19
20document.getElementById('mute-btn').addEventListener('click', function () {
21    isMuted = !isMuted;
22    // Implement the logic to mute/unmute the microphone
23    if (isMuted) {
24        // Mute the microphone
25        this.textContent = 'Unmute';
26    } else {
27        // Unmute the microphone
28        this.textContent = 'Mute';
29    }
30});
31
32document.getElementById('video-btn').addEventListener('click', function () {
33    isVideoStopped = !isVideoStopped;
34    // Implement the logic to start/stop the video
35    if (isVideoStopped) {
36        // Stop the video
37        this.textContent = 'Start Video';
38    } else {
39        // Start the video
40        this.textContent = 'Stop Video';
41    }
42});
43
44document.getElementById('end-call-btn').addEventListener('click', function () {
45    // Implement the logic to end the call
46    alert('Call ended');
47    // Redirect or reset the interface
48    window.location.href = '/';
49});

Explanation of the Code

HTML Template (index.html)

  • Added a control bar with buttons for muting/unmuting the microphone, starting/stopping the video, and ending the call.
  • The control bar is initially hidden and can be displayed after the user joins a room.

CSS File (style.css)

  • Styled the control bar and buttons for better user experience.

JavaScript File (script.js)

  • Added event listeners for the control buttons.
  • Implemented logic to toggle the state of the microphone and video.
  • Added functionality to handle the end call button, which currently redirects to the home page.
With these updates, your Dendrite WebRTC application now has a functional join screen and control features. Users can join a room, mute/unmute their microphone, start/stop their video, and end the call. In the next part, we will focus on implementing the participant view, allowing users to see and interact with other participants in the WebRTC session.

Get Free 10,000 Minutes Every Months

No credit card required to start.

Step 5: Implement Participant View

Now that we have the join screen and control features in place, the next step is to implement the participant view. This view will display the video streams of all participants in the WebRTC session. We'll modify our HTML to include a section for video streams and add the necessary JavaScript to handle the display and management of these streams.

Setting Up the Participant View

[a] Update the HTML Template

First, update the index.html file to include a section for the participant video streams.

HTML

1   <!DOCTYPE html>
2   <html lang="en">
3   <head>
4       <meta charset="UTF-8">
5       <meta name="viewport" content="width=device-width, initial-scale=1.0">
6       <title>Join Room</title>
7       <link rel="stylesheet" href="/static/style.css">
8   </head>
9   <body>
10       <div class="container">
11           <h1>Join a WebRTC Room</h1>
12           <form id="join-form">
13               <label for="room-id">Room ID:</label>
14               <input type="text" id="room-id" name="room-id" required>
15               
16               <label for="username">Username:</label>
17               <input type="text" id="username" name="username" required>
18               
19               <button type="submit">Join Room</button>
20           </form>
21           <div id="status-message"></div>
22       </div>
23
24       <!-- Control bar for WebRTC session -->
25       <div class="controls" id="controls" style="display: none;">
26           <button id="mute-btn">Mute</button>
27           <button id="video-btn">Stop Video</button>
28           <button id="end-call-btn">End Call</button>
29       </div>
30
31       <!-- Participant video streams -->
32       <div class="video-grid" id="video-grid" style="display: none;"></div>
33
34       <script src="/static/script.js"></script>
35   </body>
36   </html>

[b] Update the CSS File

Next, update the style.css file to style the participant video streams.

CSS

1   body {
2       font-family: Arial, sans-serif;
3       display: flex;
4       justify-content: center;
5       align-items: center;
6       height: 100vh;
7       background-color: #f0f0f0;
8       margin: 0;
9   }
10
11   .container {
12       background: white;
13       padding: 20px;
14       border-radius: 8px;
15       box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
16   }
17
18   h1 {
19       margin-bottom: 20px;
20   }
21
22   label {
23       display: block;
24       margin: 10px 0 5px;
25   }
26
27   input {
28       width: 100%;
29       padding: 8px;
30       box-sizing: border-box;
31       margin-bottom: 10px;
32   }
33
34   button {
35       padding: 10px 20px;
36       background-color: #007bff;
37       color: white;
38       border: none;
39       border-radius: 4px;
40       cursor: pointer;
41   }
42
43   button:hover {
44       background-color: #0056b3;
45   }
46
47   #status-message {
48       margin-top: 20px;
49       color: red;
50   }
51
52   .controls {
53       margin-top: 20px;
54   }
55
56   .controls button {
57       margin-right: 10px;
58   }
59
60   .video-grid {
61       display: grid;
62       grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
63       gap: 10px;
64       margin-top: 20px;
65   }
66
67   .video-grid video {
68       width: 100%;
69       border-radius: 8px;
70       box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
71   }

[c] Update the JavaScript File

Finally, update the script.js file to handle the participant video streams.

JavaScript

1   document.getElementById('join-form').addEventListener('submit', function (e) {
2       e.preventDefault();
3
4       const roomId = document.getElementById('room-id').value;
5       const username = document.getElementById('username').value;
6
7       if (roomId && username) {
8           // Implement the logic to join the room here
9           // Example: Redirect to the room page
10           window.location.href = `/room.html?roomId=${roomId}&username=${username}`;
11       } else {
12           document.getElementById('status-message').textContent = 'Please enter both Room ID and Username.';
13       }
14   });
15
16   // WebRTC control buttons
17   let isMuted = false;
18   let isVideoStopped = false;
19
20   document.getElementById('mute-btn').addEventListener('click', function () {
21       isMuted = !isMuted;
22       // Implement the logic to mute/unmute the microphone
23       if (isMuted) {
24           // Mute the microphone
25           this.textContent = 'Unmute';
26       } else {
27           // Unmute the microphone
28           this.textContent = 'Mute';
29       }
30   });
31
32   document.getElementById('video-btn').addEventListener('click', function () {
33       isVideoStopped = !isVideoStopped;
34       // Implement the logic to start/stop the video
35       if (isVideoStopped) {
36           // Stop the video
37           this.textContent = 'Start Video';
38       } else {
39           // Start the video
40           this.textContent = 'Stop Video';
41       }
42   });
43
44   document.getElementById('end-call-btn').addEventListener('click', function () {
45       // Implement the logic to end the call
46       alert('Call ended');
47       // Redirect or reset the interface
48       window.location.href = '/';
49   });
50
51   // WebRTC functionality for managing participant video streams
52   const videoGrid = document.getElementById('video-grid');
53
54   function addVideoStream(video, stream) {
55       video.srcObject = stream;
56       video.addEventListener('loadedmetadata', () => {
57           video.play();
58       });
59       videoGrid.append(video);
60   }
61
62   function joinRoom(roomId, username) {
63       // Example code to join the room using WebRTC
64       const video = document.createElement('video');
65       video.muted = true;
66
67       navigator.mediaDevices.getUserMedia({
68           video: true,
69           audio: true
70       }).then(stream => {
71           addVideoStream(video, stream);
72
73           // Add logic to connect to the WebRTC room and handle other participants' streams
74           // This is a simplified example; actual implementation will involve WebRTC signaling and peer connections
75       });
76
77       document.getElementById('controls').style.display = 'block';
78       videoGrid.style.display = 'grid';
79   }
80
81   // Example: Automatically join the room if room ID and username are provided in the URL
82   const urlParams = new URLSearchParams(window.location.search);
83   const roomId = urlParams.get('roomId');
84   const username = urlParams.get('username');
85
86   if (roomId && username) {
87       joinRoom(roomId, username);
88   }

Explanation of the Code

HTML Template (index.html)

  • Added a video-grid div to hold the video streams of participants.
  • Updated the join form to redirect to a room page with room ID and username as query parameters.

CSS File (style.css)

  • Styled the video-grid div to display video streams in a responsive grid layout.
  • Styled the video elements to fit within the grid cells and added some basic styling.

JavaScript File (script.js)

  • Added functionality to create video elements and add video streams to the video-grid.
  • Implemented a joinRoom function that initializes the user's video stream and prepares for WebRTC connections.
  • Automatically joins the room if room ID and username are provided in the URL.
With these updates, your Dendrite WebRTC application now includes a participant view that displays the video streams of all participants in a grid layout. Users can join a room, see other participants, and manage their own video and audio streams. In the next part, we will cover how to run and test your application, ensuring everything works as expected.

Step 6: Run Your Code Now

After implementing the participant view and adding the control features, it's time to run and test your Dendrite WebRTC application. This section will guide you through the steps to ensure your application runs smoothly and how to troubleshoot common issues.

Running the Application

Start the Go Server

Ensure your Go server is running to serve the HTML, CSS, and JavaScript files. Open your terminal, navigate to the project directory, and run:

sh

1   go run main.go
This command starts the server and listens on port 8080.

Access the Application

Open your web browser and navigate to http://localhost:8080. You should see the join screen where you can enter a room ID and username to join a WebRTC session.

Testing the Application

Join a Room

Enter a room ID and username, then click the "Join Room" button. You should be redirected to a new page where your video stream is displayed, and the control buttons (Mute, Stop Video, End Call) are visible.

Test the Control Features

  • Mute/Unmute: Click the "Mute" button to mute your microphone. The button text should change to "Unmute." Click it again to unmute your microphone.
  • Start/Stop Video: Click the "Stop Video" button to stop your video stream. The button text should change to "Start Video." Click it again to start your video stream.
  • End Call: Click the "End Call" button to end the call. You should be redirected back to the join screen.

Test with Multiple Participants

Open multiple browser windows or tabs, enter the same room ID with different usernames, and verify that each participant's video stream is displayed correctly. Ensure the controls work for each participant independently.

Common Issues and Troubleshooting

No Video or Audio

  • Ensure you have granted permission for the browser to access your camera and microphone.
  • Check the console for any errors related to media devices and resolve them accordingly.

Participants Not Visible

  • Verify that all participants are joining the same room ID.
  • Check the WebRTC signaling and peer connection logic to ensure that streams are correctly shared between participants.

Control Buttons Not Working

  • Check the JavaScript console for any errors related to the control buttons.
  • Ensure the event listeners are correctly attached and the state changes (mute/unmute, start/stop video) are properly handled.

Final Code Overview

Here’s a summary of the key files and their purposes:
  1. index.html: The main HTML template with the join screen, control buttons, and video grid.
  2. style.css: The CSS file for styling the join screen, control buttons, and video grid.
  3. script.js: The JavaScript file for handling form submissions, control button functionality, and managing video streams.
  4. main.go: The Go server file for serving the HTML, CSS, and JavaScript files and handling HTTP requests.
With these components in place and properly tested, your Dendrite WebRTC application should be fully functional. Users can join rooms, manage their audio and video streams, and see other participants in real-time.

Conclusion

In this guide, we've walked through the process of setting up a Dendrite WebRTC application, from configuring the environment and creating the join screen to implementing control features and participant views. By following these steps, you can build a robust, decentralized, and secure communication platform using Dendrite and WebRTC.

Want to level-up your learning? Subscribe now

Subscribe to our newsletter for more tech based insights

FAQ