Track Interactions on (iFrame embedded) Youtube Videos

Every week, we will release tips to help you get the most out of Mixpanel. Want to see more? Click here to see other #mpknowledgedrop articles.

Table of Contents

Introduction

Game Plan

Building the Piping

Building the Logic

TLDR, take me to the code!

Introduction

Normally, when you embed content via an <iframe> on your website that fetches a resource on an external domain, the parent page (your page) doesn’t have access to execute scripts inside the child <iframe>… this can make it difficult to track user actions on the child <iframe> and has caused a few headaches when the use of embedded content (like a video, song, or media object) is an important of your data. “Did they watch the video?”, "How long did they make it?” … that stuff is important!

Luckily, YouTube provides an <iframe> API to us; this means we can write javascript on our parent page which is aware of ‘video player’ events that occur inside the embedded child iframe. The only requirement is that the end-user’s browser supports HTML5’s postMessage feature - which (at the time of writing) is supported by ALL major browsers.

In this case onPlayerReady() and onPlayerStateChange() are functions we define and control, which will allow us to granularly track in Mixpanel how each user interacts with the embedded video player.

Note that the binding - new YT.Player(‘myPlayer’) - requires us to add an ID like ‘myPlayer’ to our <iframe>, so our javascript code knows which embedded object to reference. We also need the query string parameter ?enablejsapi=1 in the iFrame’s src attribute, which enables the iFrame API for the player.

GAMEPLAN

Before we start writing our own code, it’s often helpful to draw a picture of our desired state. In this implementation of video tracking, our goal looks something like this:

Stop the time when the video ends (or the user leaves) and track the event

Each event should contain (at least) the video’s name, playback quality, length, author, and any other meta-attributes which describe the video (that we care about).

Ok, that’s our picture and our game plan... let’s start coding:

BUILDING THE PIPING

First we need to initialize Mixpanel with our project token; I’m also going to turn Mixpanel’s debugging on (so Mixpanel events output in the console). Finally, we’ll setup a timer, to properly time how long it takes the player to load, after the page is ready:

If we had multiple videos on a single page, we would name them accordingly (using their ID’s to delineate them) and call new YT.Player() for each one, with the appropriate event bindings for onPlayerReady() and onPlayerStateChange()

BUILDING THE LOGIC

Finally, we need to define the tracking logic for onPlayerReady() and onPlayerStateChange().

To make sure this is working, we’ll load our page in our browser, and we should see a ‘player loaded’ event with a ‘$duration’ property that represents the amount of time that elapsed from page initial page load to the player being loaded! (take a look at the picture below)

Rather than writing all of our business logic in onPlayerStateChange() we’re going to use delegation and split this up into two functions - onPlayerStateChange() will delegate its work to trackPlayerChanges()

Here’s how I would write both of those functions; I’ve added helpful comments along the way for reference:

Cookie policy

Cookie settings

We use 3 different kinds of cookies. You can choose which cookies you want to accept. We need basic cookies to make this site work, therefore these are the minimum you can select. Learn more about our cookies.