Warning: The code in this blog post is outdated as our Video SDK was in BETA at the time of writing.
Check out our getting started section instead if you want help using Twilio video. If you choose to follow this tutorial you’ll need to make significant edits to the code to run.
AngularJS is a popular JavaScript framework for building client side applications. Using it steers you towards creating well-factored apps with clear Separation of Concerns (SoC). To demonstrate how Angular does this let’s convert the existing JavaScript Quickstart for Video into an Angular application.
If you want to skip ahead and grab the source for this post, it’s all on Github. Otherwise let’s get started.
Setting It All Up
Before we jump into the code we’ll need to do some setup. First, if you don’t already have a Twilio account hop on over to twilio.com and create a new one. It’s easy and free for development.
Once you have an account we need to set up a new Api Key and Secret which we’ll use in a bit to authenticate with the Twilio API. Create a new Api Key by heading into the developer console and select the Create an Api Key option.
Make sure you put the Api Secret some place safe because you won’t be able to see it again once you leave the Key page.
Next, create a new Configuration Profile for our application. The Configuration profile is a collection of configuration values specific to the Twilio Video service. For our app we just need to create a new one and grab the Configuration Profile SID.
With the Api Key and Configuration Profile created we can starting writing some code. As the base for our application we’ll use a Twilio Video for JavaScript Quickstart application. These applications are intended to get you to a working video application in just a few minutes and are available with server sides in a variety of programming languages.
Download the starter app that matches the backend language you are most interested in and follow the setup instructions for setting up your Account SID, Api Key and Secret and Configuration Profile SID in the app.
When you’re ready, give the app a spin and wave to yourself in the camera!
Approaching Angular
With the Video Quickstart running, it’s time to start converting the client side to Angular.
Start by adding the Angular library to the application view. For most of the quickstarts this means locating and opening the index.html
file included in the project. For .NET developers you are looking for Index.cshtml
.
Once you’ve opened the file add a tag whose src attribute points to the Angular library. You can download the library from https://angularjs.org/ and include it directly in your project or you can leverage a CDN host like cdnjs.com. Whichever you choose, you’ll want to use the latest released version of AngularJS 1.x (version 1.5.5 at the time of writing).
Next add a new folder named app
wherever you want to serve the application specific JavaScript files from. Where you create this folder in the Quickstart project again depends on which language you chose. For Python you’ll create it in the static
folder. In Ruby, it will be under the public
folder. For C#, you’ll place it under the Scripts
folder.
In that folder create a new app.module.js
file and define our main Angular module in it:
1 2 3 4 5 6 7 8 9 |
(function () { 'use strict'; angular.module('app', [ 'app.core.services', 'app.core.directives', 'app.videochat' ]); })(); |
Create another file named videochat.controller.js
. This file will contain the Angular controller that we’ll use to drive our video chat UI.
Open the file and define a new Angular module, its dependencies and the controller:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
(function () { 'use strict'; angular .module('app.videochat', []) .controller('VideoChatController', VideoChatController); VideoChatController.$inject = ['$scope', '$log']; function VideoChatController($scope, $log) { var vm = this; } })(); |
Head back to the application’s main view and add a element after the Angular script that points to our new module JavaScript file.
In the same view add a new Run the application and verify that controller attached and check that there are no errors in the browser’s JavaScript console. With the Angular controller connected, let’s separate the existing UI elements from their logic, starting with the button that previews the local video. In the controller create a property named Next, define a new function named Notice that Finally, add a click event to the Run the application and press the preview button. You should get prompted for microphone and camera access. However, nothing else happens because we have not attached the media streams to any UI element. Let’s handle attaching media streams to UI elements next. Create a new file in the app directory named Restrict the directive to match only an element name, define the directive scope with a single media property and create the template our directive will output. Finally, add a $watch to the directives media property. This will let us check to see if there is a new media stream to attach to the div in our template. Back in the view add another ng-app
attribute to designate the root ng-controller
attribute:
Revving up some Video
previewMedia
that will hold an instance of the LocalMedia
object.
previewCamera
. Inside this function, create an instance of LocalMedia
and call its getLocalMedia
function. Use the addStream
function to add the returned media to the LocalMedia instance.
addStream
is called inside of Angular’s $apply
function. Later in the post we’ll hook a watch up to the previewMedia
object but because getUserMedia
s promise callback happens outside of the scope of Angular’s digest loop we have to explicitly tell Angular that we want to apply a change. You will use the pattern in multiple places as you move through the code in this post.button-preview
button using Angulars ng-click
attribute:
Directing Directives
LocalMedia
has an attach
method that creates new HTML elements and automatically attaches their media streams for us, but to use it I have to pass
attach
a DOM reference which breaks my seperation of concerns. To keep my controller clean I don’t want it to have any DOM references. Angular Directives are great ways of building intermediaries between a controller and view.video.directive.js
and define the new directive in it: