Build the future of communications.
Start building for free

iOS and Web Browser Video Calls with Python and Swift


Twilio Video makes it easy for you connect the people you care about via video on the devices they already own by coding with the programming language you already know. In this post, we’ll use the JavaScript and iOS SDKs to do the heavy lifting so that you can quickly add video to your applications. Follow along and you’ll be up and running with video calls between web browsers and iOS mobile apps.

Tools We’ll Need

Python and Swift will serve as the two main programming languages we’ll use to get our web and mobile apps running. We’re going to set up the Python application first so let’s take a look at those resources we will need along the way:

The other half of our project will run on iOS, so we will also need the following Swift resources in this post:

There is a GitHub repository named video-calls-python-swift with the completed project code in case you want to try the end result before going through the rest of the tutorial.

Creating Our Twilio Video Credentials

There are several Twilio credentials that we need to create to run our application. These four environment variables are named TWILIO_ACCOUNT_SID, TWILIO_API_KEY, TWILIO_API_SECRET and TWILIO_CONFIGURATION_SID in the Python quickstart. Here is what each of those variables represents and where to grab them from your Twilio account:

  • TWILIO_ACCOUNT_SID: Your primary Twilio account identifier found on the account dashboard
  • TWILIO_API_KEY: An API account identifier for authenticating between servers, generated along with the API Secret here in the console
  • TWILIO_API_SECRET: A shared secret key used to authenticate between servers, generated with the API key
  • TWILIO_CONFIGURATION_SID: Set of configuration values for webhooks and other options for Video, generated in the console.

Grab the TWILIO_ACCOUNT_SID from the Video dashboard by clicking the “Show API Credentials” link.


After grabbing the Account SID, click the “Configuration Profiles” link next to “Getting Started”. You’ll come to a page like the following screenshot.


Click the “Create a Configuration Profile” button to get to the next screen, shown below.


Enter a name for the configuration profile, like “My Video App Config” and scroll down to the bottom of the page. Check “Enable Network Traversal” to ensure devices on a non-accessible IP address behind Network Address Translation are still reachable.


Click the “Save” button then copy the new Configuration Profile SID shown at the top of the page.

We just need to create the API key and secret then we can get our app up and running. In the navigation bar, click “Dev Tools”, then “API Keys”.


Press the “Create an API Key” button to continue. Enter a name for your new API key. Typically, the name should remind you of which application is granted permission to your account.


Press the “Create API Key” button and snag the API Key and API Secret from the screen that appears. Make sure to keep the API Secret somewhere safe as it will cannot be shown via the dashboard again.

Now that we have the four credentials in hand, we need to set them in the terminal before we run our Python app. Use the export command to set the environment variables as shown below. Make sure to use your credentials instead of the placeholders for the actual values.

export TWILIO_ACCOUNT_SID='ACxxxxxxxxxxxxxxxxxxxx'
export TWILIO_API_KEY='yyyyyyyyyyyyyyyyyyyyyyyyy'
export TWILIO_API_SECRET='zzzzzzzzzzzzzzzzzzzzzzz'
export TWILIO_CONFIGURATION_SID='aaaaaaaaaaaaaaaaaa'

The credentials for our account are now exposed as environment variables for applications we run on the command line. Let’s move ahead to the Python code that will use those credentials to run our video application.

Web Browser Video Calling with Python

Now that our environment variables are set, it’s time to get started with the browser-based version of our video call application. First we’ll need a Python virtualenv to store our application dependencies.

Virtualenv is a dependency isolation library that makes it much easier to switch between Python versions and various code packages you’re using on different projects. Create a virtualenv in a location you’ll remember using the following command. In my case, I have a folder called Envs under my home directory that keeps my virtualenv organized.

virtualenv ~/Envs/videocalls
source ~/Envs/videocalls/bin/activate

Now we have our virtualenv activated and should see our command prompt show the name of our virtualenv, such as (videocalls)$. With the virtualenv in place and activated, we can use pip to install our dependencies.
Head to the JavaScript Video quickstart page and click the “Download for Python” button. Extract the files from the quickstart and change into that directory from the commandline.

The Python code library dependencies for this quickstart are listed in the requirements.txt file. Those dependencies are:


Install the dependencies into our virtualenv with the following pip command:

pip install -r requirements.txt

Open the file in the Python quickstart project. Let’s break down what’s in the source code file and why we need it to run our application.

import os
from flask import Flask, jsonify, request
from faker import Factory
from twilio.access_token import AccessToken, ConversationsGrant

The first four lines in are imports. The os module is used to grab environment variables that we just set. flask is a Python web micro framework that allows us to serve a web application. In this application, faker is used to generate random usernames. The twilio library is used to generate temporary access tokens based on our credentials specified in the environment variables.

app = Flask(__name__)
fake = Factory.create()

def index():
    return app.send_static_file('index.html')

After the import statements, we instantiate the Flask application and create a variable to hold the Faker library’s factory. We then define a route for the root URL to serve up a webpage for our application.

def token():
    # get credentials for environment variables
    account_sid = os.environ['TWILIO_ACCOUNT_SID']
    api_key = os.environ['TWILIO_API_KEY']
    api_secret = os.environ['TWILIO_API_SECRET']
    # Create an Access Token
    token = AccessToken(account_sid, api_key, api_secret)

    # Set the Identity of this token
    token.identity = fake.user_name()
    # Grant access to Conversations
    grant = ConversationsGrant()
    grant.configuration_profile_sid = os.environ['TWILIO_CONFIGURATION_SID']

    # Return token info as JSON
    return jsonify(identity=token.identity, token=token.to_jwt())

In the above code we define another route that can be accessed at the /token URL. This token function generates a temporary JSON web token (JWT) as an access token that can be passed to the client. The client will then have access to our Twilio account only for the grants that were added to the token in this function.

if __name__ == '__main__':

Finally, we have a simple conditional that runs the app when this file is directly run through the python command.

Now that we understand what the code is doing, it is time to start up the server by running with Python.


When the server starts, pull up http://localhost:5000 in a browser to try the application.
This is the simple user interface for our browser-based video application. You can click the “Preview My Camera” button then give the browser permission to access your camera to try it out.

However, we really want to connect two users in two separate windows together. Pull up http://localhost:5000/ in two browsers, such as Chrome and Firefox. You’ll be able to use the name shown in one browser window to create a video call to the other browser window.


Alright, we just made a video call between two browsers!

Connecting people together using video in a browser is interesting, but the real excitement starts when you mix devices, say a browser and an iPhone. Let’s move on to the iOS app to see how we can make cross-device video calling work.

iOS Mobile App Video Calling with Swift

It’s time to set up the other side of our video application that will run on iOS. Go to the iOS video quickstart page and download the Swift version of the quickstart.

Twilio uses CocoaPods to distribute the dependencies necessary to work with video on iOS. We need to install the necessary pods to properly run the iOS app. However, we need to make sure we have the latest pods which may not be in the quickstart files. Open Podfile within the Swift quickstart and ensure the file matches the following lines.

source ''
pod 'TwilioConversationsClient', :podspec => ''
pod 'TwilioCommon', :podspec => ''

Head back to the terminal and run the following commands to install the pods and then open the VideoQuickStart app once.

cd video-quickstart-swift-master/
pod install
open VideoQuickStart.xcworkspace

The open command brings up Xcode with our Swift video quickstart project along with the installed pods. In the Project Navigator on the left side, open VideoQuickStart -> VideoQuickStart -> Source -> ViewController.swift.


Within ViewController.swift look for the following lines at the top of the file. Modify the tokenUrl so it matches the highlighted line below.

import UIKit

class ViewController: UIViewController {
  // MARK: View Controller Members
  // Configure access token manually for testing, if desired! Create one manually in the console 
  // at<a href=""> </a><a href=""></a>
  var accessToken = "TWILIO_ACCESS_TOKEN"
  // Configure remote URL to fetch token from
  var tokenUrl = "http://localhost:5000/token"
  // Video SDK components
  var accessManager: TwilioAccessManager?
  var client: TwilioConversationsClient?
  var localMedia: TWCLocalMedia?

Our Python server running on localhost:5000 already generates access tokens, including ones that will allow our iOS app to use Twilio Video. With that change in place, we can run the simulator and start up our iOS app. Click the little ‘ ‘ icon in the top right corner of the iOS app and invite the randomly generated username presented in the browser application. You can now connect the two devices together.


Woohoo! Now we have the iOS Video app running, but there’s something strange going on. Why is there no video going from the iOS app to the web browser? Unfortunately, the iOS simulator is limited and does not have camera functionality. We need to test with an external device.

What happens though if we want to test our iOS app on a device that can’t connect to localhost because it’s only available in our development environment? We’ll handle that in the next section.

Browser, Meet iOS App, iOS App, Meet Browser

Our simulator and devices connected to your development computer can access the web application running on localhost port 5000, but what about when we want to test our video calling on the iOS app outside the development environment? We’ll use a localhost tunneling tool named ngrok to create a URL that can be access by anyone on the Web. Our ngrok set up is quick, but if you want to learn more about the tool check out this handy detailed ngrok post by my colleague Phil Nash.

Download the appropriate ngrok file for your operating system. In the terminal, change into the directory where ngrok is located. Start ngrok up with an HTTP (and HTTPS) connection to your Python server running locally on port 5000. Use the the following command:

./ngrok http 5000

You should see ngrok start up like in this screenshot:


Highlight and copy the HTTPS forwarding URL, for example in the above screenshot you’d copy We’re going to use that URL in our Swift application.

In Xcode, update the same line we modified earlier. This time change the tokenUrl variable to the ngrok URL by pasting in our HTTPS Forwarding URL we just copied above.

import UIKit

class ViewController: UIViewController {
  // MARK: View Controller Members
  // Configure access token manually for testing, if desired! Create one manually in the console 
  // at<a href=""> </a><a href=""></a>
  var accessToken = "TWILIO_ACCESS_TOKEN"
  // Configure remote URL to fetch token from
  var tokenUrl = ""
  // Video SDK components
  var accessManager: TwilioAccessManager?
  var client: TwilioConversationsClient?
  var localMedia: TWCLocalMedia?

Restart your application on the iOS device. Now we can test the iOS app when it’s not connected to our development environment, as shown in the following screenshot.

We can also test against the iOS simulator, knowing that the simulator won’t be able to broadcast video back. Another iOS device with a camera will be able to do video calls for a full test.

Video All the Things!
Nice work completing this tutorial! Connecting people on the devices they already use is way easier now that you know how to Twilio Video.

Our quickstart web and mobile apps are just a taste of what you can build with the Video SDKs. What else do you want to create with it? Drop a comment below or contact contact me via:

Sign up and start building
Not ready yet? Talk to an expert.