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
In our examples, we’ll take advantage of the YouTube Player API, the Google Tag Manager data layer, and Google Analytics custom dimensions, but the same overall process would apply equally to other video hosts, tag management systems, and analytics platforms.

 

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.

Video tracking in Google Analytics is often implemented with events that corresponded to “milestones”, i.e., thresholds of percentages or viewing time completed, as well as initial play and pause

 

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:

“Heartbeat” vs. “Milestone” Video Tracking
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.
If we wanted, we could approximate heartbeat tracking in Google Analytics by setting a trigger to fire every few seconds, but this approach could flood Google Analytics with event hits, thereby requiring a switch to Google Analytics 360, or a higher Google Analytics 360 tier.
As a compromise, the approach that we take in this blog post increases the frequency of the milestones. We’ll also use a custom metric for greater reporting flexibility, and we’ll capture engagement between the most recent milestone event and the time when the user disengages.

 

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:

  1. Your Company Tour video, embedded on the About Us Page, is 30 minutes long.
  2. You’re tracking at 10% intervals, which works out to every three minutes.
  3. A user plays the video.
  4. At 3 minutes, a video event is triggered.
  5. At 5:59, the user navigates away from the About Us page.
  6. 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.

We’re now also tracking unload events for video, thereby providing more complete tracking of video engagement.

 

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.

Total play time per video.

For the custom report below, we display a calculated metrics (Avg. Play Time/Session) by traffic source.

This custom report displays an Avg. Play Time Per Session calculated metric against Source/Medium.

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.

NameDescriptionExampleType
video_nameThe display name of the videoEverybody Loves Raymond S03 E09String
show_nameThe name of the showEverybody Loves RaymondString
genresThe style of media: fantasy, romance, comedy, science fiction, mystery,…ComedyString
media_typeThe type of media this art applies to: movie, show, season, episode,…EpisodeString
episode_noThe number of the episodeE01String
season_noThe number of the seasonS06String
premium_contentWhether the video is guarded behind loginNoString
tv_channelThe TV channel in which the show airedCBSString
certificateThe rating of the showTV-PGString
languageLanguage of the videoEnglishString
release_yearThe year in which the show was first aired1996String
video_lengthThe total length (in seconds) of the video1,200Number
play_timeThe total play time (in seconds) of the video345Number

 

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:

  1. 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.
  2. Configure Google Tag Manager to generate Google Analytics events based on the video data that we write to the data layer.

 

Video Play

Eventevent=”video_play”
DescriptionThe video began playing (either via auto-play or user click)
Play Time0
SampledataLayer.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

Eventevent=”video_pause”
DescriptionThe video playback changed to paused.
Play TimeThe time duration between the last milestone and the pause event, in seconds.
SampledataLayer.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’,
},
});

Tracking time between last milestone (3) and pause (4).

HitEventPlay Time
1Play0 seconds
2,3Milestone60 seconds each
4Pause10 seconds

 

Video Milestone

Eventevent=”video_milestone”
DescriptionThe video playback reached a specific percentage milestone.
Play TimeOne-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.
SampledataLayer.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’,
},
});

Time tracked at regular milestones.

HitEventPlay Time
1Play0 seconds
2 – 11Milestone60 seconds each

 

Video Seek

Eventevent=”video_seek”
DescriptionVideo playback was advanced forward (not backward) to a new play position.
Play TimeThe time between the last milestone and the seek event.
SampledataLayer.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’,
},
});

Tracking time between last milestone (5) and the point where the user began the seek action (6).

HitEventPlay Time
1Play0 seconds
2, 3, 4, 5Milestone60 seconds each
6Seek49 seconds
7Milestone55 seconds each

 

Video Unload

Eventevent=”video_unload”
DescriptionThe user navigates away from the page by clicking on the forward or back buttons or closing the browser/tab.
Play TimeThe time duration between the last milestone and the unload event.
SampledataLayer.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’,
},
});

Tracking time between video start (or last milestone) and unload.

HitEventPlay Time
1Play0 seconds
2Unload40 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.

In the Google Analytics Event tag for video unload, you set the transport field to beacon.

 

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;

 

EventPlay Time (in seconds)Example
(Video Length = 2 mins)
Play00
PauseThe time duration between the last milestone and the pause event.7 sec
10% progressVideo Length / 1012 sec
20% progressVideo Length / 1012 sec
30% progressVideo Length / 1012 sec
40% progressVideo Length / 1012 sec
50% progressVideo Length / 1012 sec
60% progressVideo Length / 1012 sec
70% progressVideo Length / 1012 sec
80% progressVideo Length / 1012 sec
90% progressVideo Length / 1012 sec
100% progressVideo Length / 1012 sec
SeekThe time between the last milestone and the seek event30 sec
unloadThe time duration between the last milestone and the unload event7 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.

Custom report showing the Play Time custom metric against the Genres custom dimension.

 

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.

Questions about tracking user engagement, improving user experience, and optimizing customer acquisition? Contact E-Nor today.

About the Author

Allaedin Ezzedin
VP Analytics Engineering
Allaedin wisely guides friends, family and colleagues with honesty and care. He is a long time digital analytics industry veteran leading E-Nor’s analytics team with over a decade of experience as a digital marketing and senior analytics consultant.