With the pandemic making remote work more prevalent than ever, video conferencing has become one of the primary ways we communicate with our friends, family, and coworkers. This change in how we communicate makes now an excellent time to learn how to build a video conferencing web app.

This post was originally published in Vonage.

This tutorial will show you how to quickly build a video conferencing web app using PythonFlask, JavaScript, and Vonage’s Video API


To follow along with this tutorial, you need to have a basic understanding of Python and web development.

You also need to install Ngrok.

Finally, you will need to register for a free Vonage Video API account (formerly TokBox).

Initial Setup

To get started, we need to do some initial setup.

First, create your Video API account.

Once you’ve created your account, you need to create a project.

Click on “Projects” and then “Create New Project.”

Next, select “Create Custom Project.”

Now create a new project named “my_project.”

Then click “Create.”

Now click “View project.” 

Make sure to save your project API key and secret; you will need them later.

Next, you need to clone the GitHub repository containing this project’s code.

git clone https://github.com/calthoff/vonageunlocked.git

cd into your Github repository and open up the empty .env file that comes with it. 

cd vonageunlocked
vim .env

Add your Vonage Video API key and secret (that you saved earlier) to the .env file like this:


Next, create a virtual environment and activate it.

pip3 install virtualenv
virtualenv venv
source venv/bin/activate

Then, download the project’s dependencies:

pip3 install -r requirements.txt

Once you’ve done that, start up your Flask test server by running app.py:

python3 app.py

Finally, fire up ngrok on the same port as your Flask test server (you can read Ngrok’s documentation to better understand how ngrok works):

ngrok http 5000  

Now, head to the URL Ngrok gives you to see the video conferencing web app in action (the URL should look like this: http://d584-172-112-188-34.ngrok.io). 

You can now video conference with yourself using your phone and your computer or share the link with a friend to video conference with someone else. 

Go to https://your_ngrok_link/admin to stream video, and then https://your_ngrok_link/join to view it from another browser or device (make sure to log into the admin page first). 

You should see a website that looks like this:

This web app also lets you chat!

How It Works 

Let’s take a look at how it works. 

First, it imports the Flask, Decouple, and Opentok (the Vonage Video API) libraries. Flask is a popular Python web development framework.

from flask import Flask, render_template, request
from decouple import config
from opentok import Client

Next, it loads your Vonage Video API key and secret from environmental variables. 

opentok_api = config('OPENTOK_API')
opentok_secret = config('OPENTOK_SECRET')

Then it creates a Vonage Video API client and passes it your API key and secret, which it then uses to create a new Vonage Video API session. 

client = Client(opentok_api, opentok_secret)
session_id = client.create_session().session_id

When you use the Vonage Video API, everything happens in a session. You can publish a video to a session and consume video from a session. Each session has a unique ID. In this case, you create a new session and save the session’s ID in session_id

Next, this code creates a Flask app:

app = Flask(__name__, static_url_path='')

With Flask, you can easily map a URL to a function like this:

@app.route('/test', methods=['POST', 'GET'])
def index():
    return "Hello, World!"

If you add this code to app.py and visit /test on your local server, you should see “Hello, World!”

This project maps three URLs to HTML templates using Flask’s render_template method. One function maps /admin to admin.html, and the other maps /join to join.html

def admin():
   return render_template('admin.html')

def join():
   return render_template('join.html')

These two HTML templates let you log in either as an admin or a regular viewer.  You see them when you go to /join or /admin in the web app. 

You can find the complete HTML for each template in the templates folder of your repository. 

Let’s take a look at how the index function in app.py works.

@app.route('/', methods=['POST', 'GET'])
def index():
   if request.method == 'POST':
       token = client.generate_token(session_id)
       admin = False
       if 'admin' in request.form:
           admin = True
       name = request.form['name']
       return render_template('index.html', session_id=session_id, token=token, is_admin=admin, name=name,
   return 'please log in'

Every user that joins a Vonage Video API session needs a unique token.

So when a  post request comes in, the code generates a new token using the Vonage Video API. Next, the code checks to see if the user is an admin or not by checking if ‘admin’ is in request.form (of course, you wouldn’t want to do this in a production application). 

if 'admin' in request.form:
    admin = True

Then, this code grabs the user’s name from request.form

name = request.form['name']

Finally, this code uses render_template to render index.html and pass in the session ID you created earlier, the token you created earlier, whether the user is an admin, and their name to the index.html template. 

return render_template('index.html', session_id=session_id, token=token, is_admin=admin, name=name,

The index.html template then uses those variables to display the video to whoever joins. 

Let’s quickly take a look at what happens on the front-end. 

First, the index.html template loads this script:

<script src="https://static.opentok.com/v2/js/opentok.min.js"></script>

If the user isn’t an admin, a JavasScript file with the following code from viewer_video.js runs:

const sessionId = document.querySelector('#session_id').dataset.name;
const apiKey = document.querySelector('#api_key').dataset.name;
const token = document.querySelector('#token').dataset.name;

// Initialize session
const session = OT.initSession(apiKey, sessionId)

session.on("streamCreated", function (event) {


This JavaScript code gets the session ID, API key, and token from the backend.

const sessionId = document.querySelector('#session_id').dataset.name;
const apiKey = document.querySelector('#api_key').dataset.name;
const token = document.querySelector('#token').dataset.name;

Then, it creates a session object (note that it does not create a new session).

const session = OT.initSession(apiKey, sessionId)

Next, your front-end code subscribes to the session. 

session.on("streamCreated", function (event) {

Finally, you connect to the session by calling session.connect and pass the token you generated on the back-end.


If the user is an admin, the code from admin_video.js runs instead. The way it works is similar to viewer_video.js.

Your code creates a session object.

const session = OT.initSession(apiKey, sessionId)

Next, it creates a publisher so that the admin can stream the video to the viewers. 

const publisher = OT.initPublisher("opentok-publishers", {
 videoSource: c1.captureStream().getVideoTracks()[0],
 width: 320,
 height: 240

Once your code connects to the session, it publishes the publisher. 

session.connect(token, () => {

And finally, it subscribes the user to the stream, so the admin can see their video while streaming. 

session.on('streamCreated', event => {
 session.subscribe(event.stream, "opentok-subscribers")

Final Thoughts

You now know how to quickly add video conferencing to a web app using Vonage’s Video API and Flask.  There is some extra code in the project on the front-end. You are encouraged to take a deeper look at the repository to understand how the code works as a whole Thanks for reading.

Radiostud.io Staff

About the author

Showcasing and curating a knowledge base of tech use cases from across the web.

{"email":"Email address invalid","url":"Website address invalid","required":"Required field missing"}
TechForCXO Weekly Newsletter
TechForCXO Weekly Newsletter

TechForCXO - Our Weekly Newsletter Delivering Technology Use Case Insights for CXOs