Cloudinary Blog

Google Analytics Video Tracking Made Simple

Google Analytics Video Tracking Made Simple

Most web analytics only look at page interactions. But what happens when the major content on your page is a video. You want to know when and how long your users are interacting with your media, when they paused to take a closer look at your media content and when they skipped some content because it wasn’t relevant to them. These - along with a lot of other reasons - are why you should not only analyze open/visits rates, but also drill down in the media content.

Still on media, with every post on the internet - whether image or video, low quality or high quality - one thing is constant: the ability to track certain data points related to these media assets is priceless because they make up a huge percentage of web content these days. For images, it could be the number of clicks on a linked image or the number of times it is seen on the platform. For videos, views are the most widely tracked data points.

Are these videos’ views metrics sufficient, and efficient, to track user engagement? Obviously not. We need more details on how people interact with our videos.

Cloudinary Video Player

Take video playback to the next level using the Cloudinary Video Player. Possessing features such as adaptive bitrate for various end users, recommended content, video playlist, and an event analytics feature, the Cloudinary Video Player gives us sheer control and optimal delivery from the Cloudinary CDN The Cloudinary Video Player enables us to integrate analysis.js through Google Analytics to track various metrics and events during video playback. These events include - but are not limited to - pause, play, video load, player load and percentage of video played.

In this article, we will show how to integrate Google Analytics into a Node app featuring the video player.

Prerequisite

For this post, knowledge of HTML, CSS and JavaScript is required. Knowledge of Google Analytics is not required, but a basic understanding of the Google Analytics interface is an added advantage.

Installation

First, you will need to create a Cloudinary account and obtain your cloud_name from your dashboard. Do that here. This account is the only one we need to create for now as this is all we need to get our app running, later on, we will create a google analytics account to manage events and analytics.

Since this is a Node app, you must have installed Node.js and NPM globally on your machine. If not install them from here. Verify if you have Node and NPM installed by running the following on your command line:

#Verify Node
node -v 
#Verify NPM
npm -v

The version numbers of both tools will be displayed on your console when you run those.

For the sake of this demo, this app can be built as a front-end project without a Node server, but we choose to host our app online on a free ngrok server, which resulted in building a little a backend server for our app.

Once we have Node and NPM installed, create a new project folder with any name of your choice. In the project folder, create a new Node project with:

npm init

This creates a new project a package.json file. Next up is to install required dependencies. For our app, the dependencies required are:

  • Body-parser: Used to parse requests and is available on req.body.
  • cors: Enables cross-origin requests.
  • express: This is a Node.js framework for building servers easily.
  • cloudinary-core: This is the Cloudinary core dependency
  • cloudinary-video-player: Installs the video player
  • lodash: Required by Cloudinary Video Player.

Install the above dependencies with:

    npm install express body-parser cors cloudinary-core cloudinary-video-player lodash --save

The --save flag saves the dependencies to our local project and creates these dependencies in our package.json file.

Note
The Cloudinary Video Player can be installed in multiple ways, but we choose the server-side installation. You can equally reference the required JavaScript and CSS files from a CDN and it would work properly. See other installation methods here.

Once these dependencies are installed, a node_modules folder is automatically created to house the dependencies. For our app, we simply require four config files which we will set up next.

Setting Up the Build Files

For this app, we will require an HTML file, CSS file for styling, a JavaScript file containing our front-end scripts and a server file which we call server.js. In the root directory, create the files index.html, index.css, index.js, and server.js. We will get to configuring these next.

Index.html This is the HTML script of our page and since it’s a single page this single file will suffice. A simple HTML script is set up with a <video> tag in the body element. This will house our media player.

<html>
<body>
    <div class="container">
        <header>
            <h1>Introducing The Cloudinary Video Player, With Analytics!</h1>
        </header>
        <main>
            <div class="video-box">
                <video
                class="cld-video-player"
                id="cl-vp">
                </video>
            </div>
            <div class="video-caption">
                <h2>Google Analytics</h2>
                <p>After setup, check out google analytics to see events captured.</p>
            </div>
        </main>
    </div>
    <!-- External Stylesheet -->
    <script src="index.js"></script>
</body>
</html>

Note the inclusion of the external stylesheet and the JavaScript file in our HTML.

We currently have our HTML page setup. However to have Cloudinary functional on our page, we will include it with script tags on our page. Since we are not importing from a CDN but rather installing it via NPM, we will import our script files from the node_modules folder in our root folder.

In the in the <head> tag of the HTML script, include Cloudinary with:

...
<!-- Dependencies -->
    <link href="node_modules/cloudinary-video-player/dist/cld-video-player.min.css" rel="stylesheet">
    <script src="node_modules/lodash/lodash.js" type="text/javascript"></script>
    <script src="node_modules/cloudinary-core/cloudinary-core.js" type="text/javascript"></script>
    <script src="node_modules/cloudinary-video-player/dist/cld-video-player.min.js" type="text/javascript"></script>
...

So far we have our HTML file set up. Let’s set up the JavaScript file next.

Index.js In the index.js file created, we create a Cloudinary Video Player instance with:

var cl = cloudinary.Cloudinary.new({cloud_name:'xxxxx', secure:true})
//instantiate the video player
 var myPlayer = cl.videoPlayer('cl-vp',{
     loop:true,
     controls:true,
     autoplay:true,
     analytics:true
 })
 myPlayer.source('merry-christmas', {info:{ title: 'Little Drummer Boy', subtitle:'Pentatonix'}})

First, a new Cloudinary instance is created and instantiated with the cloud_name obtained from your Cloudinary dashboard. Next, we call the videoPlayer method on our Cloudinary instance. The video player is mounted on the dom element with the id of cl-vp which we created and assigned to the video element in our HTML script earlier. Video parameters are passed to an object as a second parameter to the method. Native video controls are also available to the Cloudinary Video Player.

The analytics property is included and assigned a value of true. This tracks all events. But you can specify which particular events to track in the analytics property. See events you can track here.

We specify the source of the video next using the .source() method. The first parameter is the public ID of any video you uploaded to your Cloudinary account. A second parameter is an object containing video details which can be title, subtitle, and description. See more parameters here. Once we have our JavaScript configured, configure styling in the index.css file with:

body, main, header{
    margin: 0px;
    padding: 0px;
    font-family:Verdana, Geneva, Tahoma, sans-serif;
}
h1{
    margin: 0px auto;
    padding: 70px 0px;
    width: 50%;
    text-align: center;
}
header{
    height: 200px;
    width: 100%;
    text-align: center;
    color: white;
    background-color: black;
    border-bottom: 2px solid grey;
}
main{
    width: 80%;
    margin: 20px auto;
}

Now we have all files ready, but we can’t serve our files yet. We need a node server to serve this. Optionally to see what was built beforehand, let’s open the HTML in our browser from our local folder.

Google Analytics Video Tracking Made Simple

Our video is playing, very good. But we want to create our Node server so we can expose our local server to the internet using a tool called ngrok.

Create Your App Server

In the server.js file, import the installed dependencies and create the server with:

var express = require('express')
var cors = require('cors')
var bodyParser = require('body-parser')
var cloudinary = require('cloudinary-core')
var path = require('path');
var app = express()
var port = 1995;
app.use(cors())
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({extended:false}))
app.use(express.static(__dirname + '/'))

//Create endpoint for the home route
app.get('/', (req,res) => {
    res.sendFile(path.join(__dirname + '/index.html'))
})
app.listen(port, (err) =>{
    if(err) throw err;
    console.log('App is booming on the legendary port 1995!!')
})

Once the server dependencies are imported, our express server is configured, a REST endpoint is created for our home route in which the index.html file is served.

Note
express.static() is used to issue access to static files in our project folder such as the CSS and the JavaScript file.

Our app is then served on the legendary port 1995, hehehe. To serve your app, run:

    node server.js

Open localhost:1995 in the browser to view the webpage, same as what was served from our local directory.

How do we expose our webpage to the internet? We use an awesome tool - ngrok - to expose our local host to the internet on a specified address.

Download ngrok from here. While your local server is still running, use ngrok to expose your local server with:

    ./ngrok http 1995

This creates a forwarding address, like http://1c69969f.ngrok.io/. Your app is available at this address. Next, let’s set up Google Analytics.

Setup Google Analytics

Create an account on Google Analytics with the temporary web address obtained from ngrok. You are issued a tracking code unique to the created account. If you are having a hard time finding the tracking code, it can be found on the admin panel, under the property tab of your account.

In the head tag of your HTML script, include the Google Analytics tracking script just after the opening head tag with:

...
<script>
    (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
    })(window,document,'script','https://www.google-analytics.com/analytics.js','ga');

    ga('create', 'tracking-code', 'auto');
    ga('send', 'pageview');
</script>
...

Replace tracking-code with the tracking code obtained on account creation.

Now refresh your browser, you should see Google Analytics gather data immediately from the video, navigate to the events tab under the Real-Time menu to see tracked data from the video played. All events are tracked immediately upon setup.

Google Analytics Video Tracking Made Simple

Conclusion

In this tutorial we showed the importance of properly understanding user engagement with media assets with the focus on videos, whether it is for marketing purposes or just to understand certain trends. This further demonstrates the power of the Cloudinary video player. Furthermore, we created the video player in an HTML page and integrated Google Analytics video tracking. The opportunities are endless once you have the right data. Feel free to make contributions to the repository here and leave your feedback. Be sure to create your FREE Cloudinary account!

Recent Blog Posts

Mobile Optimization: Optimize Your Mobile-Web User Experience

TL;DR

We live in a visual world, often while on the go, and consumers expect media-rich web content. Accordingly, the loading speed of images and videos is a big factor in user experience. To optimize customer satisfaction with your mobile content, you must focus on the quality, format, and size of your digital assets. With Cloudinary, optimization is simple, not only enhancing your mobile web and app performance, but also upping your SEO game and boosting customer experience.

Read more
Multi Codec Adaptive Bitrate Streaming

In Part I of this series, we discussed the optimal way to deliver progressive video streams, taking advantage of modern, efficient codecs. That approach works great for short-form videos (under 20 seconds) and for videos that are displayed at a low resolution (such as ads and previews). But what if you're delivering videos that are longer than 20 seconds for a higher-resolution experience? You can certainly still deliver them as a single file (progressive streaming), but you might run into issues, such as buffering or too high a resolution.

Read more
Why Visual Storytelling Matters

In my communications role here at Cloudinary, I get to speak to a lot of experts across a variety of subject matter areas, technology and not, about what it takes to connect to today’s consumer. The power of images and other forms of digital content is often at the center of these conversations given our focus at Cloudinary. And as a hobbyist and professional photographer for more than 20 years, I care deeply about images and their role in creating authentic connections and engagement.

Read more
How to Automatically Generate alt Text for Images

Images and videos are critical for ensuring user engagement on the web. For instance, on a retail website, images of a product from different angles or a 360-degree video of the product can lead to higher conversion rates. For a news website, users are more likely to read articles with visual media accompanying the content. It has been reported that posts that include images produce a 650-percent higher user-engagement rate than text-only posts.

Read more