Is your investment in video generating ad revenue, decreasing support costs, or providing an engaging end-user experience overall?
Regardless of the vertical, you’re working in, it’s important to track video engagement as accurately and descriptively as possible. For a publisher, a technical support provider, or an educational destination that offers a multitude of video content, it’s critical for understanding the effectiveness of the content that you’re producing and posting.
This post outlines specialized techniques for achieving two objectives:
1. More Accurate Tracking of Video Play Time (without Swamping Google Analytics)
As our primary objective, we’ll reorient the usual milestone approach to video tracking and provide a more accurate assessment of view time. We’ll also take advantage of custom metrics so we’re tracking video play time not just as text-based events but as numeric data. This will allow us to calculate and display play time by video, session, and user. To achieve this, we’ll take advantage of the following Google Analytics features:
- Google Analytics custom metrics
- Google Analytics navigator.sendBeacon() transfer mechanism
- jQuery .unload() function
2. Video Reporting with Additional Descriptors
The APIs for most video players provide quite a rich taxonomy for us to read and then write to our analytics tool for additional reporting opportunities, as the second objective of our enhanced video tracking. The values that we’ll read from the API and write into Google Analytics as custom dimensions include:
- genre
- channel
- rating
Video Tracking: Milestone Approach
In Google Analytics, video tracking is normally approached as “milestones”, meaning that you generate an event in Google Analytics when the video reaches a threshold expressed as percentage duration or time viewed.
While useful, the usual milestone approach has some fundamental limitations:
- frequency: the frequency of event tracking may not be great enough to provide an accurate idea of engagement.
- engagement after last event hit: we’re missing any video play time between the last video event you sent to Google Analytics and the moment the user disengages
- text vs. numeric data: since we’re tracking video interactions with text-based Google Analytics event dimensions, we can’t calculate overall video engagement time for by video title, per session, or per user: you can only report on milestones reached.
We’ll address all three of these limitations below:
The “heartbeat” approach to video tracking is ideal when it’s feasible. It is exactly what it sounds like: user engagement with a video is tracked at very regular intervals. Some video hosts provide this degree of specificity in their native built-in analytics.
1. Frequency
This adjustment is easy: we’ll send events to Google Analytics at 10% intervals instead of 25%. In this way, we’ll get a little bit closer to heartbeat frequency without overwhelming Google Analytics with event hits.
2. Capturing Activity Between Last Hit and User Disengagement
Broadly speaking, there has been a historical struggle in Google Analytics to measure user interaction/engagement after the last hit that was sent.
Let’s see how this would apply to video tracking:
- Your Company Tour video, embedded on the About Us Page, is 30 minutes long.
- You’re tracking at 10% intervals, which works out to every three minutes.
- A user plays the video.
- At 3 minutes, a video event is triggered.
- At 5:59, the user navigates away from the About Us page.
- The next event would have fired in one more second, but only 10% (3 minutes) of playing time is tracked, rather than nearly 6 minutes that the user has actually viewed.
To approach this challenge, we’ll take advantage of the jQuery .unload() function and the new navigator.sendBeacon.
.unload() Function
Use the .unload() function to trigger a Google Analytics event that carries the playtime in seconds for the video time watched right before the browser exit event.
The unload event is sent to the window element when the user navigates away from the page. This could mean that the user took any of the following actions:
- clicked on a link to leave the page
- typed in a new URL in the address bar
- clicked on the forward or back buttons
- closed the browser
- refreshed the page
navigator.sendBeacon Transport Mechanism for Google Analytics
By default, analytics.js picks the HTTP method and transport mechanism with which to optimally send hits. The three options are:
- image (using an image object)
- xhr (using an XMLHttpRequest object)
- beacon (using the navigator.sendBeacon method)
The navigator.sendBeacon method is a new HTML feature created that we can use to track hits that are sent if the page is being unloaded.
Note: .unload() and navigator.sendBeacon Not Supported on All Browsers
3. Custom Metric for Play Time
As another enhancement to the video time tracking, we’ll pass a custom metric for elapsed video play time with the following events:
- progress
- pause
- watch to end
- unload
Regarding a Google Analytics custom metric for video watch time – rather than just text-based Google Analytics threshold and interaction events – will provide much greater opportunities for reporting, including play time:
- per video for a given time period
- trended for an individual video or all videos
- per user or session
- by geography (total, or by user or session)
- by traffic source (total, or by user or session)
- by technology (total, or by user or session)
Below is a simple custom report displaying the Video Play Time custom metric for the video titles, which have been recorded as an event label.
For the custom report below, we display a calculated metrics (Avg. Play Time/Session) by traffic source.
Traffic sources with high play times/session might be good candidates for increased marketing efforts.
How the video tracker works
Video Data Points (Data Layer Definition)
As one of the benefits of reading from the video API ourselves, we’ll be able to tag advantage of quite a detailed back-end taxonomy. Below is the list of video-specific variables (Data Layer Attributes) you can pass along when you send video events and then use in the Google Analytics UI.
Name | Description | Example | Type |
---|---|---|---|
video_name | The display name of the video | Everybody Loves Raymond S03 E09 | String |
show_name | The name of the show | Everybody Loves Raymond | String |
genres | The style of media: fantasy, romance, comedy, science fiction, mystery,… | Comedy | String |
media_type | The type of media this art applies to: movie, show, season, episode,… | Episode | String |
episode_no | The number of the episode | E01 | String |
season_no | The number of the season | S06 | String |
premium_content | Whether the video is guarded behind login | No | String |
tv_channel | The TV channel in which the show aired | CBS | String |
certificate | The rating of the show | TV-PG | String |
language | Language of the video | English | String |
release_year | The year in which the show was first aired | 1996 | String |
video_length | The total length (in seconds) of the video | 1,200 | Number |
play_time | The total play time (in seconds) of the video | 345 | Number |
Event Tracking
Let’s just dive straight into a few examples of how the video tracker works. Note: While we aren’t going to share the details of the tracker in this post, it is important to know that we are using the video player’s built-in API and Event Listeners.
Imagine a user is watching the 9th episode in the 3rd season of Everybody Loves Raymond. During the 20-minute video, the user performed the following actions:
- start the video
- watch the video for a significant percentage of its duration
- pause the video
- use the seek function
- navigate away from the page before completing the video
Our steps for capturing these actions (along with additional descriptors) as web analytics data will include:
- Scripting specific YouTube API listeners (in Google Tag Manager Custom HTML tags) to write to the GTM data layer on the page, as in the examples below.
- Configure Google Tag Manager to generate Google Analytics events based on the video data that we write to the data layer.
Video Play
Event | event=”video_play” |
Description | The video began playing (either via auto-play or user click) |
Play Time | 0 |
Sample | dataLayer.push({ ‘event’: ‘video_play’, ‘event_category’: ‘video’, ‘event_action’: ‘play’, ‘event_label’: ‘Everybody Loves Raymond S03 E09’, ‘event_value’: 0, ‘non_interaction’: 0, ‘video’: { ‘video_name’: ‘Everybody Loves Raymond S03 E09’, ‘show_name’: ‘Everybody Loves Raymond’, ‘genres’: ‘Comedy’, ‘media_type’: ‘Episode’, ‘episode_no’: ‘E01’, ‘season_no’: ‘S06’, ‘premium_content’: ‘No’, ‘tv_channel’: ‘CBS’, ‘certificate’: ‘TV-PG’, ‘language’: ‘English’, ‘release_year’: ‘1996’, ‘play_time’: ‘0’, ‘video_length’: ‘120’ }, }); |
Video Pause
Event | event=”video_pause” |
Description | The video playback changed to paused. |
Play Time | The time duration between the last milestone and the pause event, in seconds. |
Sample | dataLayer.push({ dataLayer.push({ ‘event’: ‘video_pause’, ‘event_category’: ‘video’, ‘event_action’: ‘pause’, ‘event_label’: ‘Everybody Loves Raymond S03 E09’, ‘event_value’: 0, ‘non_interaction’: 0, ‘video’: { ‘video_name’: ‘Everybody Loves Raymond S03 E09’, ‘show_name’: ‘Everybody Loves Raymond’, ‘genres’: ‘Comedy’, ‘media_type’: ‘Episode’, ‘episode_no’: ‘E01’, ‘season_no’: ‘S06’, ‘premium_content’: ‘No’, ‘tv_channel’: ‘CBS’, ‘certificate’: ‘TV-PG’, ‘language’: ‘English’, ‘release_year’: ‘1996’, ‘play_time’: ’10’, ‘video_length’: ‘600’, }, }); |
Hit | Event | Play Time |
---|---|---|
1 | Play | 0 seconds |
2,3 | Milestone | 60 seconds each |
4 | Pause | 10 seconds |
Video Milestone
Event | event=”video_milestone” |
Description | The video playback reached a specific percentage milestone. |
Play Time | One-tenth of the video duration. Note: In the case of the “video seek”, Play Time is calculated based on the time between the new starting position and the next milestone. |
Sample | dataLayer.push({ ‘event’: ‘video_milestone’, ‘event_category’: ‘video’, ‘event_action’: ‘10% progress’, ‘event_label’: ‘Everybody Loves Raymond S03 E09’, ‘event_value’: 0, ‘non_interaction’: 0, ‘video’: { ‘video_name’: ‘Everybody Loves Raymond S03 E09’, ‘show_name’: ‘Everybody Loves Raymond’, ‘genres’: ‘Comedy’, ‘media_type’: ‘Episode’, ‘episode_no’: ‘E01’, ‘season_no’: ‘S06’, ‘premium_content’: ‘No’, ‘tv_channel’: ‘CBS’, ‘certificate’: ‘TV-PG’, ‘language’: ‘English’, ‘release_year’: ‘1996’, ‘play_time’: ’12’, ‘video_length’: ‘600’, }, }); |
Hit | Event | Play Time |
---|---|---|
1 | Play | 0 seconds |
2 – 11 | Milestone | 60 seconds each |
Video Seek
Event | event=”video_seek” |
Description | Video playback was advanced forward (not backward) to a new play position. |
Play Time | The time between the last milestone and the seek event. |
Sample | dataLayer.push({ ‘event’: ‘video_seek’, ‘event_category’: ‘video’, ‘event_action’: ‘seek’, ‘event_label’: ‘Everybody Loves Raymond S03 E09’, ‘event_value’: 0, ‘non_interaction’: 0, ‘video’: { ‘video_name’: ‘Everybody Loves Raymond S03 E09’, ‘show_name’: ‘Everybody Loves Raymond’, ‘genres’: ‘Comedy’, ‘media_type’: ‘Episode’, ‘episode_no’: ‘E01’, ‘season_no’: ‘S06’, ‘premium_content’: ‘No’, ‘tv_channel’: ‘CBS’, ‘certificate’: ‘TV-PG’, ‘language’: ‘English’, ‘release_year’: ‘1996’, ‘play_time’: ’30’, ‘video_length’: ‘600’, }, }); |
Hit | Event | Play Time |
---|---|---|
1 | Play | 0 seconds |
2, 3, 4, 5 | Milestone | 60 seconds each |
6 | Seek | 49 seconds |
7 | Milestone | 55 seconds each |
Video Unload
Event | event=”video_unload” |
Description | The user navigates away from the page by clicking on the forward or back buttons or closing the browser/tab. |
Play Time | The time duration between the last milestone and the unload event. |
Sample | dataLayer.push({ ‘event’: ‘video_unload’, ‘event_category’: ‘video’, ‘event_action’: ‘unload’, ‘event_label’: ‘Everybody Loves Raymond S03 E09’, ‘event_value’: 0, ‘non_interaction’: 0, ‘video’: { ‘video_name’: ‘Everybody Loves Raymond S03 E09’, ‘show_name’: ‘Everybody Loves Raymond’, ‘genres’: ‘Comedy’, ‘media_type’: ‘Episode’, ‘episode_no’: ‘E01’, ‘season_no’: ‘S06’, ‘premium_content’: ‘No’, ‘tv_channel’: ‘CBS’, ‘certificate’: ‘TV-PG’, ‘language’: ‘English’, ‘release_year’: ‘1996’, ‘play_time’: ’40’, ‘video_length’: ‘600’, }, }); |
Hit | Event | Play Time |
---|---|---|
1 | Play | 0 seconds |
2 | Unload | 40 seconds each |
Tracking the Events to Google Analytics through Google Tag Manager
Once you have your API listeners set up in GTM Custom Event tags, you’re ready to configure one or more Custom Event triggers and Google Analytics tags to record the events in Google Analytics.
Time Calculation
You can use the JavaScript Video Duration property to retrieve the length of the played video, in seconds. This duration can be the basis of the Play Time custom metric.
var video_length = document.getElementById(“myVideo”).duration;
Event | Play Time (in seconds) | Example (Video Length = 2 mins) |
---|---|---|
Play | 0 | 0 |
Pause | The time duration between the last milestone and the pause event. | 7 sec |
10% progress | Video Length / 10 | 12 sec |
20% progress | Video Length / 10 | 12 sec |
30% progress | Video Length / 10 | 12 sec |
40% progress | Video Length / 10 | 12 sec |
50% progress | Video Length / 10 | 12 sec |
60% progress | Video Length / 10 | 12 sec |
70% progress | Video Length / 10 | 12 sec |
80% progress | Video Length / 10 | 12 sec |
90% progress | Video Length / 10 | 12 sec |
100% progress | Video Length / 10 | 12 sec |
Seek | The time between the last milestone and the seek event | 30 sec |
unload | The time duration between the last milestone and the unload event | 7 sec |
Reporting with Custom Dimensions
In addition to the enhanced time reporting that the increased tracking frequency and custom metrics will allow, we can also report against any of the custom dimensions.
Understand Engagement with the Assets You Produce
With a few relatively straightforward implementation steps – more frequent intervals for video events, additional view time through unload, a custom metric for play time, and an assortment of custom dimensions – we have achieved more accurate tracking of user engagement with video and much more flexible and descriptive reporting, which will provide better inputs for your marketing focus and content strategy.