You are on page 1of 16

Level up your Twilio API skills in TwilioQuest, an Download

educational game for Mac, Windows, and Linux. Now

BLOG DOCS LOG IN SIGN UP TWILIO

Build the future of S TA R T B U I L D I N G F O R F R E E


communications.

B Y M A R C U S B AT T L E ▪ 2 0 2 0 - 0 4 - 1 4

TWITTER FA C E B O O K LINKEDIN

Create a Video Conference App using


Laravel, PHP, and Vue.js
During times where we can’t be together physically, video conferencing helps reinforce and
establish relationships by allowing us to monitor visual cues sometimes lost over the phone.
Conference calls are great, but studies show that when we can’t see who’s talking, we’re more
likely to get distracted by our favorite apps. Not only is video conferencing an excellent way to
increase focus during meetings, but it’s also a great method for keeping in touch with family
and friends during the coronavirus pandemic.

In this tutorial you will learn how to create your own video conferencing app in Vue.js, using the
Laravel framework and Twilio Programmable Video. There is no software to download, nor
tutorials to follow. The final result is a link to a mobile-friendly video chat room, capable of
hosting up to 50 participants.

NOTE: This tutorial is written specifically for Laravel 7+ (although it may work for previous
versions).

Technical Overview and Prerequisites


When your application loads in the browser, a unique identifier is generated for the user to
authenticate their connection to the chat room. Once verified by Twilio’s servers, the user will
be added to the existing chat room.

Our project will use Vue.js and Laravel to generate the front and backend respectively.

In order to get started, you will need the following requirements set up and ready to go:

Composer globally installed

Laravel installer

A Twilio account (this link will give you $10 in Twilio spend when you upgrade)

Let’s get started by creating a new Laravel project.

Create a new Laravel project


In order to create the base application, open the folder where you normally store your projects
and run the following command:

1 $ laravel new laravel-video-chat-room && cd laravel-video-chat-room


Add the Twilio PHP SDK to the Project
We’ll need an easy method to connect to the Twilio Video API so that chat rooms and tokens
can be created and authenticated for the users. Luckily, this method has already been created
for us in the Twilio PHP SDK. Let’s add it as a requirement of our project using Composer.

1 $ composer require twilio/sdk

Create an API Endpoint to Generate Tokens


Creating APIs in Laravel is a pretty seamless process. As a modern web application framework,
Laravel provides the necessary scaffolding to create the controller and route needed to
generate tokens on the server-side.

Create a New Controller to Generate Access Tokens


A controller, or class that defines application logic, will need to be created to generate all user
access tokens via the Twilio Video API. To begin, run the artisan command in your terminal for
creating new controllers:

1 $ php artisan make:controller API/AccessTokenController

This command created a new file for us at


app/Http/Controllers/API/AccessTokenController.php .

Open the newly created controller and take a moment to inspect it. You’ll notice that right now
it’s empty. Outside of a couple of namespace declarations, the artisan command has generated
an empty class.
1 <?php
2
3 namespace App\Http\Controllers\API;
4
5 use App\Http\Controllers\Controller;
6 use Illuminate\Http\Request;
7
8 class AccessTokenController extends Controller
9 {
10 //
11 }

We’re now ready to add a couple of namespaces to the controller that will autoload the Twilio
SDK for use. Add the following lines of code beneath the use Illuminate\Http\Request;
namespace.

1 use Twilio\Jwt\AccessToken;
2 use Twilio\Jwt\Grants\VideoGrant;

The preceding declarations give us the support needed to actually connect to the Twilio Video
API and generate an access token. Now, you need to create a method to utilize the classes
declared.

Add the following generate_token method below to the AccessTokenController class:


1 public function generate_token()
2 {
3 // Substitute your Twilio Account SID and API Key details
4 $accountSid = env('TWILIO_ACCOUNT_SID');
5 $apiKeySid = env('TWILIO_API_KEY_SID');
6 $apiKeySecret = env('TWILIO_API_KEY_SECRET');
7
8 $identity = uniqid();
9
10 // Create an Access Token
11 $token = new AccessToken(
12 $accountSid,
13 $apiKeySid,
14 $apiKeySecret,
15 3600,
16 $identity
17 );
18
19 // Grant access to Video
20 $grant = new VideoGrant();
21 $grant->setRoom('cool room');
22 $token->addGrant($grant);
23
24 // Serialize the token as a JWT
25 echo $token->toJWT();
26 }

You’ll notice the first three lines of our method search for environment variables to define our
Twilio credentials. These lines reference three variables that we haven’t defined in our
dotenv .env file yet. Let’s open the Twilio console to access them.

You’ll need to copy the Account SID from your account dashboard. An API Key and API
Secret will need to be created from your API Keys list.
All three of these values will need to be copied to the .env file located in the project directory
as follows:

1 TWILIO_ACCOUNT_SID="Insert your Account SID"


2 TWILIO_API_KEY_SID="Insert your API Key"
3 TWILIO_API_KEY_SECRET="Insert your API Secret"

The last step in generating an access token is to create a route (or API endpoint) that connects
to our AccessTokenController . This route will provide a publicly accessible endpoint to the
application logic we previously created.

Open routes/api.php and add the following declaration:

1 Route::get('access_token', 'API\AccessTokenController@generate_token');

This line of code registers the endpoint http://127.0.0.1:8000/api/access_token and responds


to the GET verb.

To test our work thus far, run the following artisan command in your terminal:

1 $ php artisan serve

The serve command will load the PHP web server and deploy our Laravel application locally.
Install Laravel UI and Vue Packages
Because the back-end functionality is complete for our application, we are ready to scaffold the
front end. As of version 6, Laravel has decoupled the JavaScript and CSS scaffolding from the
application logic, so we will need to add it back using the new Laravel UI package. Once
installed, it will open up our application to easily use any popular styling or scripting framework
to modify the user interface and experience.

Run the following command in your terminal:

1 $ composer require laravel/ui

Now that the base package has been installed, we are ready to install the Vue.js front-end
scaffolding. To install, run the following:

1 $ php artisan ui vue

Followed by:

1 $ npm install && npm run dev

In order to see what we’ve done and test that Vue is loaded and working, we need to update
the Laravel blade responsible for displaying the homepage at
resources/views/welcome.blade.php . Open the file and replace its contents with the following:
1 <!DOCTYPE html>
2 <html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
3 <head>
4 <meta charset="utf-8">
5 <meta name="viewport" content="width=device-width, initial-scal
6 <title>Laravel Video Chat</title>
7 <link href="https://fonts.googleapis.com/css2?family=Oxygen&dis
8 <link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.mi
9
10 <style>
11 * {
12 font-family: 'Oxygen', sans-serif;
13 }
14 </style>
15 </head>
16 <body>
17 <div id="app">
18 <example-component></example-component>
19 </div>
20 <script src="{{ asset('js/app.js') }}"></script>
21 </body>
22 </html>

NOTE: Because our HTML has been modified, it needs to be compiled in order to see the
changes. To see your changes run npm run dev again or npm run watch for live reloading.

This HTML will load the app.js file, which is responsible for transforming the #app div into
the stage of our Vue.js UI. By default, the Laravel UI package installs an
ExampleComponent which is seen on the line reading <example-component></example-
component> . This sample Vue component simply displays some HTML rendered as:

1 Example Component
2 I'm an example component.

If you see this in your browser, then everything is working as expected!

Create a New Vue.js Component


Let’s create a new Vue component VideoChat.vue in the resources/js/components folder
that will house our video chat room logic. This component will be responsible for connecting to
the endpoint we created earlier and rendering the chat window.

After the component has been created, add the following code:

1 <template>
2 <div class="p-5">
3 <h1 class="text-2xl mb-4">Laravel Video Chat</h1>
4 <div class="grid grid-flow-row grid-cols-3 grid-rows-3 gap-4 bg
5 <div id="my-video-chat-window"></div>
6 </div>
7 </div>
8 </template>
9
10 <script>
11 export default {
12 name: 'video-chat'
13 }
14 </script>

This component will just display the title “Laravel Video Chat”. Vue.js doesn’t recognize it yet
so we will need to update the welcome.blade.php blade again to display our component.

Replace the <example-component></example-component> line in


resources/views/welcome.blade.php with <video-chat></video-chat> .

Lastly, open resources/js/app.js and add the following line of code underneath the
ExampleComponent to globally define our new component:

1 Vue.component('video-chat', require('./components/VideoChat.vue').defau

Connect the VideoChat Component to the


Route
Before we make an AJAX request to our access token endpoint, the Twilio Programmable Video
JavaScript SDK needs to be installed. This SDK, written in JavaScript, is responsible for
managing all of the API requests for Twilio Programmable Video.

In your terminal, install the Twilio Programmable Video JavaScript SDK by running the following
command:
1 $ npm install --save twilio-video@2.0.0

Now that the SDK is installed, we can add the getAccessToken() method to connect to our
endpoint.

Replace the code in welcome.blade.php with the following:


late>
div class="p-5">
<h1 class="text-2xl mb-4">Laravel Video Chat</h1>
<div class="grid grid-flow-row grid-cols-3 grid-rows-3 gap-4 bg-black/]">
<div id="my-video-chat-window"></div>
</div>
/div>
plate>

pt>
t default {
ame: 'video-chat',
ata: function () {
return {
accessToken: ''
}

ethods : {
getAccessToken : function () {

const _this = this


const axios = require('axios')

// Request a new token


axios.get('/api/access_token')
.then(function (response) {
_this.accessToken = response.data
})
.catch(function (error) {
console.log(error);
})
.then(function () {
console.log( _this.accessToken )
});
}

ounted : function () {
console.log('Video chat room loading...')

this.getAccessToken()

ipt>
The code above defines an empty variable accessToken and assigns it an empty string. Once
the component is mounted, getAccessToken() is called to request a new access token from
http://127.0.0.1:8000/api/access_token . Upon a successful response, the data is assigned to
accessToken .

We’re now ready to add the code which will connect us to the room we defined in our
controller earlier and display a live feed from our local device.

Add the following code to the list of available methods after the getAccessToken method:

1 connectToRoom : function () {
2
3 const { connect, createLocalVideoTrack } = require('twilio-
4
5 connect( this.accessToken, { name:'cool room' }).then(room
6
7 console.log(`Successfully joined a Room: ${room}`);
8
9 const videoChatWindow = document.getElementById('video-
10
11 createLocalVideoTrack().then(track => {
12 videoChatWindow.appendChild(track.attach());
13 });
14
15 room.on('participantConnected', participant => {
16 console.log(`A remote Participant connected: ${part
17 });
18 }, error => {
19 console.error(`Unable to connect to Room: ${error.messa
20 });
21 }

The connectToRoom method takes the accessToken we initialized in getAccessToken and


creates a local video track upon successful authentication. You’ll notice that there’s also a
placeholder for when a participant connects to the chat room. We’ll add that logic shortly.

For now, let’s call this method from the final then promise in getAccessToken as follows:
1 getAccessToken : function () {
2
3 const _this = this
4 const axios = require('axios')
5
6 // Request a new token
7 axios.get('/api/access_token')
8 .then(function (response) {
9 _this.accessToken = response.data
10 })
11 .catch(function (error) {
12 console.log(error);
13 })
14 .then(function () {
15 _this.connectToRoom()
16 });
17 },

Finally, we’re ready to add the logic to display the other participants in the video chat. Replace
the room.on('participantConnected', participant => { code with the following:

1 room.on('participantConnected', participant => {


2 console.log(`Participant "${participant.identity}"
3
4 participant.tracks.forEach(publication => {
5 if (publication.isSubscribed) {
6 const track = publication.track;
7 videoChatWindow.appendChild(track.attach())
8 }
9 });
10
11 participant.on('trackSubscribed', track => {
12 videoChatWindow.appendChild(track.attach());
13 });
14 });

This function will listen for any new connections from remote participants, and upon
connection, add them to the gallery of chat windows.

Testing
In case you haven’t done so in a while, you’ll need to re-compile the code for Vue to detect the
changes we’ve made. Run npm run dev , make sure you’re running php artisan serve in a
separate terminal, and refresh your browser.

Using two windows or browsers, load http://127.0.0.1:8000/ and wait for your participants to
connect.

Conclusion
This tutorial has not only taught us how to implement Twilio’s Programmable Video, but it also
helped us to develop a starter Video Chat application. If you’re interested in extending this
code further, you could:

Display the number of participants

Hide the chat room behind a secure portal/wall

Add a text-chat feature

With all of the world turning towards remote work and video-conferencing, there’s no better
time than now to have your own custom implementation. I can’t wait to see what you build!

Marcus Battle is Twilio’s PHP Developer of Technical Content where he prompts and rallies PHP
developers to build the future of communications. You can download the full repo from Github
or contact him for any questions regarding this tutorial at:

Email: mbattle@twilio.com
Twitter: @themarcusbattle

Github: https://github.com/themarcusbattle

R AT E T H I S P O S T AUTHORS Marcus Battle

Search

Build the future of communications. Start today with Twilio's APIs and services.

S TA R T B U I L D I N G F O R F R E E

P O S T S B Y S TA C K

J AVA .NET RUBY PHP PYTHON SWIFT ARDUINO J AVA S C R I P T

POSTS BY PRODUCT

SMS AUTHY VOICE TWILIO CLIENT MMS VIDEO TA S K R O U T E R FLEX SIP I OT

P R O G R A M M A B L E C H AT STUDIO

C AT E G O R I E S

Code, Tutorials and Hacks

Customer Highlights

Developers Drawing The Owl

News

Stories From The Road

The Owl’s Nest: Inside Twilio

TWITTER FA C E B O O K

Developer stories
b
to your inbox.
Subscribe to the Developer Digest, a monthly dose of all things code.

Enter your email…

You may unsubscribe at any time using the unsubscribe link in the digest email See our privacy policy for more information

NEW!

Tutorials
Sample applications that cover common use cases in a variety of languages. Download, test drive,
and tweak them yourself.

Get started

S I G N U P A N D S TA R T B U I L D I N G

Not ready yet? Talk to an expert.

ABOUT
LEGAL
COPYRIGHT © 2021 TWILIO INC.
A L L R I G H TS R E S E RV E D.
P R O T E C T E D B Y R E C A P T C H A – P R I VA C Y – T E R M S

Could not connect to the reCAPTCHA service. Please check your internet connection and reload to get a
reCAPTCHA challenge.

You might also like