Random thoughts & observations

From the mundane to the profound and everything in between here’s what’s rocking our world

Embedding YouTube Videos in Ionic Apps

Posted: October 12, 2015
Written by: Saints At Play
Category: Ionic Framework

In this article we're going to take you through embedding a YouTube video within an Ionic App.

We are going to assume that you have the following software installed on your system (we are using Mac OS X - so some screengrabs may differ to what you see on your own system):

It's also assumed that you have some familiarity developing with AngularJS too.

If you can tick all of the above then let's get started!

Create Your Project

Firstly we'll need to create an Ionic/Cordova project (this will contain the necessary libraries, plugins, files and directory structure that form the foundation for our App).

To do this open the Ionic Lab tool and click on the NEW APP link at the top right hand side of the window and enter the name of your App, select the location where the App will be created, choose Blank starter from the drop down menu and leave Enable Sass and Enable Cordova selected:

Create an Ionic App with Ionic Lab

Depending on your system/network speed the process of creating the App should take no more than 30 seconds.

Once completed you should see a screen that looks like the following (iOS is installed by default. To create an App for Android you would need to click the INSTALL link next to the Android Platform in the ACTIONS tab):

App created within Ionic Lab

From here you can choose to add additional plugins to your App (those already selected in the below screenshot are default selections made by the Ionic Lab tool):

Adding plugins to an App with Ionic Lab

The remaining step in creating your App will be to run the Build command (located in the Sharing section of the middle column displayed in the screenshot below) which will build your App for both iOS and, if installed, Android.

We find this helps, on iOS at least, with changing the default name of the App from Hello Cordova to the actual name provided at the creation stage (in this case, YTApp):

Build Ionic App for iOS

At this point, if you navigate to where your App was created, you should have a Cordova/Ionic project with the following file structure:

bower.json
config.xml
gulpfile.js
hooks/
ionic.project
package.json
platforms/
plugins/
scss/
www/

In the www/ directory create the following sub-directory:

assets/templates

Later on in the tutorial we are going to use this sub-directory to store the relevant views for our application.

With the initial foundation and structure for our project created we can now turn our attention to defining the logic for our application.

Define your controller

As Ionic, in its current incarnation, requires the Angular JS framework (this is changing though) we will need to define a controller for our application logic.

In the www/js directory of our recently created YTApp create a script called controllers.js, place the following code into there and then save this file:

"use strict";
angular.module('YTApp.controllers', [])


/**
 *
 * Home
 * @class HomeController
 * @static
 * @uses $scope
 *
 */
.controller('HomeController', function($scope)
{
  // Choose whatever URL you want for your YouTube video :)
  $scope.video 			=	"https://www.youtube.com/embed/7GqClqvlObY";
});

For the purpose of this article we are creating a single controller titled HomeController which contains a single variable: video. This variable contains the URL for the YouTube video that we want to embed and display on the landing screen of our App. As the video variable is scoped to the HomeController this means that wherever this controller is attached/called we can simply embed the variable within the associated view template file (we'll get to this after the next section).

Note the structure of the video URL:

https://www.youtube.com/embed/7GqClqvlObY

This is important as the above URL will render while, in our experiences, the following won't:

https://www.youtube.com/watch?v=7GqClqvlObY

So be sure to replace:

watch?v=

With the following instead:

embed/

And that should resolve any rendering issues with the video URL itself.

Now that we have created our controller we need to configure the default app.js file generated by Ionic/Cordova for bootstrapping/initialising our App.

Let's look at doing this now.

Bootstrapping the App

Open the app.js file located in the following directory at the root of your project:

www/js

And edit the code located there so that it resembles the following:

var YTApp = angular.module('YTApp', ['ionic', 'YTApp.controllers'])

.run(function($ionicPlatform, $rootScope) 
{
  $ionicPlatform.ready(function() 
  {

    // Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
    // for form inputs)
    if(window.cordova && window.cordova.plugins.Keyboard) 
    {
      cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
    }


    if(window.StatusBar) 
    {
      StatusBar.styleDefault();
    }

  });
})


.config(function($sceDelegateProvider) 
{
    $sceDelegateProvider.resourceUrlWhitelist(['self', new RegExp('^(http[s]?):\/\/(w{3}.)?youtube\.com/.+$')]);
})


.config(function($stateProvider, $urlRouterProvider)
{
    $stateProvider
        // Home 
        .state('index',
        {
            url                                 :   '/',
            templateUrl                         :   'assets/templates/home.html',
            controller                          :   'HomeController'
        });

        // Default
        $urlRouterProvider.otherwise("/");

});

That's a modest amount of code but let's break it down in detail so we understand what's happening at the most relevant stages.

The first thing that we do in our app.js file is to define the module for our app that will include all required dependencies like so:

var YTApp = angular.module('YTApp', ['ionic', 'YTApp.controllers'])

Note that, in the above snippet, we inject the controller module we created earlier, after the default Ionic dependency.

In the following section we are configuring a whitelist of safe URL's to be used within our application::

.config(function($sceDelegateProvider) 
{
    $sceDelegateProvider.resourceUrlWhitelist(['self', new RegExp('^(http[s]?):\/\/(w{3}.)?youtube\.com/.+$')]);
})

We accomplish this through passing a provider, $sceDelegateProvider, into our configuration definition which allows for Strict Contextual Escaping using the resourceUrlWhitelist method. This instructs angular that the URL contained within is safe for use in our templates.

Note that a regular expression is used to match the youtube.com url using either the http or https protocol.

Next we configure the routes for our application using the $stateProvider:

.config(function($stateProvider, $urlRouterProvider)
{
  $stateProvider
    // Home 
    .state('index',
    {
      url                                 :   '/',
      templateUrl                         :   'assets/templates/home.html',
      controller                          :   'HomeController'
    });

    // Default
    $urlRouterProvider.otherwise("/");

});

This allows us to define each route to be used in our application as a state, along with the controller and the template to be used for each specific state (as it stands we only have a single state - but this could be built upon and expanded further if we decided to do so).

Now that we have broken down and investigated, step-by-step, the logic for our application let's take a look at the views that need to be implemented.

What's in a view?

Firstly, we need to look at the view that will display the embedded video for our application.

In the previous section we saw that our route was using the following template:

assets/templates/home.html

You'll need to create the home.html in the above directory structure and then place the following code into this file:

<ion-view title="Video">
  <ion-content>
    <iframe frameborder="0" height="200" src="" width="100%"></iframe>
    <p>Embedding YT video</p>
  </ion-content>
</ion-view>

If you're familiar with using Ionic/Angular you won't find anything out of the ordinary or challenging with the above.

The video variable that we defined in our HomeController is embedded in the src of an iframe tag which is wrapped within ion-content and ion-view tags. This will allow our YouTube video to be loaded within the iframe when we view our app on a mobile device.

Finally, we need to ensure that the index.html file at the root of our application (/www) is configured correctly.

Open this file and ensure that the HTML contained within matches the following:

<!DOCTYPE html>
  <html>
    <head>
      <meta charset="utf-8">
      <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
      <title></title>
      <link href="lib/ionic/css/ionic.css" rel="stylesheet">
      <link href="css/style.css" rel="stylesheet">
      <script src="lib/ionic/js/ionic.bundle.js"></script>
      <script src="cordova.js"></script>
      <script src="js/controllers.js"></script>
      <script src="js/app.js"></script>
    </head>
    <body ng-app="YTApp" class="platform-ios platform-cordova platform-webview">
      <ion-nav-bar class="bar bar-header bar-header-custom-blue" animation="nav-title-slide-ios7">
        <ion-nav-back-button class="button button-dark remove-btn-border">Back</ion-nav-back-button>
      </ion-nav-bar>
      <ion-nav-view animation="slide-left-right"></ion-nav-view>
    </body>
  </html>

The most important things to note with the above are that the controller.js and app.js files are being called in the head of our HTML file, after both the ionic.bundle.js and cordova.js files.

We also need to ensure our application is initialised with the ng-app directive containing the name of our application as defined in our app.js file.

Before we launch our app it's important to go back through the above code and double check the following are completed and in place:

  • HomeController defined within our js/controller.js file
  • URL whitelist configured for youTube videos within our js/app.js file
  • Routes for our app are configured, as states, within our js/app.js file
  • View for embedding/displaying our YouTube video configured within assets/templates/home.html
  • ALL required JavaScript files included within our index.html file along with ng-app directive implemented

If all of the above criteria are satisfied then we can launch our app (using the Run link in Ionic Lab, through typing ionic run iOS or ionic run android via the Ionic CLI or, if developing solely for iOS, publishing to our mobile device using Xcode) and see our YouTube video being displayed.

Potential Issues

The course of development never runs as smoothly as we might want it to and bugs/issues are an ever present challenge to even the most seasoned of developers.

Here's a couple of issues we encountered that you may also come across:

  1. Videos taking time to load (simply add a preloader GIF - as a CSS background image - to the parent wrapper that the iframe sits within to indicate to your intended audience that something is happening - otherwise they'll be greeted with a blank space until the video finally loads)
  2. Audio issues on iOS (this seems to happen if the mute button has been locked - simply unlock this button and all associated audio should play without issue)
« Return to Posts

Comments

There are no comments

Posting comments after three months has been disabled.