How can we help?

Player Event Framework Follow

Objective

This document outlines the following topics:

What is a player event?

A player event is essentially a message containing information about the current state of the player. This message is sent out, or "dispatched" by one of two mechanisms. The web page must have a mechanism present in order to receive the event and do something meaningful with it.

An example of an event may happen on play or pause of the video. The event will signify that playback of the video has been invoked, or pause of the video has been invoked.

 

Behind the Scenes: Technologies Used to Dispatch Player Events

Create Event

The original event framework for videos used the standard JavaScript event framework

MDN 'createEvent' Documentation

The first version for the event framework required developers to add event listeners to the div element that the player is embedded into. This approach worked, however the event framework was limited to only JavaScript embeds.

The longer term solution for events needed to support both JavaScript and iFrame embeds.

PostMessage

MDN 'postMessage' Documentation

PostMessage safely enables cross-origin communication. Normally, scripts on different pages are allowed to access each other if and only if the pages that executed them are at locations with the same protocol (usually both https), port number (443 being the default for https), and host (document.domain being set by both pages to the same value). PostMessage provides a controlled mechanism to circumvent these restrictions in a secure way.

PostMessage allows for the player to broadcast events out of the player in a manner that is consistent across JavaScript and iFrame embeds.

Browser Support for PostMessage

PostMessage has full support for modern browsers (graphic provided by MDN):

PostMessageSupport.png

 

Event Types

The Zype event framework supports the following event types:

  • Ready (zype:ready)
  • Play (zype:play)
  • Pause (zype:pause)
  • Error (zype:error)
  • Complete (zype:complete)

Zype events are prefixed with 'zype:' to differentiate them from other messages that may appear on your page. Other players emit events as well, including YouTube and Vimeo. Having a naming convention such as ours allows for clear identification on which event is which.

 

Player Event Creation

Example Event Messages

Event Structure

Note: Event data is sent as a String for IE8 support. The data can be converted back to JSON format for consumption using JSON.parse().

"{
"event": "zype:pause",
"id": "57ed77530983884e57000041",
"info": {
"playlist_id": "564f70754272692607270000"
}
}"

Fields

  • Event: This is the name of the event (example: zype:ready, zype:play, etc.)
  • ID: This is the ID of the video that created the message
  • Info: This is an optional object that can be used to add custom metadata to our player events. It is currently used internally by the playlist player to identify which playlist is generating the message.

Event Origin

For iFrame based players, the origin of the event will start with 'https://player.zype.com'.

For JavaScript based players, the origin will be the current page.

Adding Custom Metadata to Dispatched Events

Consider the following URL: https://player.zype.com/embed/<VIDEO_ID>.html?app_key=<APP_KEY>

This URL is the standard structure for a player request.

If you wanted to pass along some custom metadata, you can add an 'info' object to the request. The info object will be parsed and presented by the player during event dispatch.

Example

In this example, I will add the 'info' object with a 'page' key/value pair. I will do this because I would like to tie the current page to the video event for identification purposes.

// Request
https://player.zype.com/embed/<VIDEO_ID>.html?app_key=<APP_KEY>&info[page]=home

// Output
"{
"event": "zype:play",
"id": "57ed77530983884e57000041",
"info": {
"page": "home"
}

}"

Behind the Scenes: Dispatching Player Events

Hooking Into the Underlying Player Framework

In order to dispatch events, we must hook into our underlying player framework: THEOplayer.

You can read more about THEOplayer events here

// Creating an instance of the player
var player = new THEOplayer.player()

// Hooking into the THEOplayer events
player.addEventListener('canplay', function(data) {
eventManager.dispatch('zype:ready')
})

player.addEventListener('pause', function(data) {
eventManager.dispatch('zype:pause')
})

player.addEventListener('error', function(data) {
eventManager.dispatch('zype:error')
})

player.addEventListener('play', function(data) {
eventManager.dispatch('zype:play')
})

player.addEventListener('ended', function(data) {
eventManager.dispatch('zype:complete')
})

Event Manager and Window Targeting

iFrame and JavaScript embeds operate in different window contexts. Because of this, events need to be dispatched differently in each use case.

In an iFrame embed, events must be sent to the parent of the window in order to be received by the page that the video is embedded on.

In a JavaScript embed, events can be sent to the window to be received by the same page that the video is embedded on.

Under the hood, we have a construct known as an 'EventManager'. Its purpose is to determine where to dispatch an event to.

 

How can I listen for player events?

Player events are easy to consume using the PostMessage API. To add a listener, you can utilize and customize the following script:

<script>
// add an event listener to listen for events!
window.addEventListener('message', receiveMessage, false)

function receiveMessage(message) {
// validate that the message is coming from Zype
if (message.origin.match(/zype\.com/) {
// parse the payload of the events message
var data = JSON.parse(message.data)

if (data.event === 'zype:ready') {
// do something on video ready
}

if (data.event === 'zype:play') {
// do something on video play
}

if (data.event === 'zype:pause') {
// do something on video pause
}

if (data.event === 'zype:error') {
// do something on video error
}

if (data.event === 'zype:complete') {
// do something on video complete
}
}
}
</script>

Comments

Article is closed for comments.