This project is read-only.

Tracking position and playtime in the player framework

Markers (Xaml & WP8 only)

Both the MediaElement that ships with Windows 8 and the Xaml version of the player framework have a built in mechanism called Markers for receiving notification in your app when specific positions are reached during playback. While this feature is very powerful and useful, it is also limited in the criteria for which you can receive notification.

TrackingEvents (Xaml, JS, & WP8)

In the player framework, we’ve introduced a new TrackingEvent feature that will enable applications to receive notification for scenarios not currently captured by the built in Marker feature as well as in the JavaScript version of the player framework.

The player framework currently offers two types of TrackingEvents: Position and PlayTime tracking events. Position tracking events are similar to the Marker feature but offer the following additional features:
  • Awareness of seeking and scrubbing. MediaElement markers will only fire when you play through a given marker. Seeking or scrubbing past will not cause the MarkerReached event to fire.
  • Forward and backward movement. Additionally, TrackingEvents will also fire when seeking or scrubbing backward in the timeline as well as Rewinding past a marker.
  • Percentage based tracking events. This allows you to easily track when you’ve reached the positions in your video relative to the total duration. For example, you could track when the midpoint or when a particular quartile has been reached without having to calculate the position based on the duration.

PlayTime tracking events are something new entirely and allow you to track when the specified amount of play time has elapsed. This is often useful for analytics purposes to allow you to know how long the user has spent actually watching your video regardless of the amount of time the video was pause or which portions of the video have been watched. For example, you may need to know when the user has actually watched 30 minutes of video regardless of whether or not they started from the beginning of that video and to exclude the time it was paused.

Usage

To use the position or playtime tracking features, you need to add an optional plugin to the player framework. This plugin ships with the core player framework assembly so there is no need to add additional references to your project. All you need to do is access the plugin, add the event you want to track and wire up to the events to receive notification.

Getting Started: JavaScript

Setup which events to track:

From code:
mediaPlayer.playTimeTrackingPlugin.trackingEvents.push({ playTime: 5 });
mediaPlayer.positionTrackingPlugin.trackingEvents.push({ positionPercentage: 0.5 });

Or, from HTML:
<div data-win-control="PlayerFramework.MediaPlayer" data-win-options="{
    width: 640,
    height: 360,
    autoplay: true,
    src: 'http://smf.blob.core.windows.net/samples/videos/wildlife.mp4',
    playTimeTrackingPlugin: {
        trackingEvents: [
            { playTime: 5 }
        ]
    },
    positionTrackingPlugin: {
        trackingEvents: [
            { positionPercentage: 0.50 }
        ]
    }
}"></div>

Monitor those events:

mediaPlayer.playTimeTrackingPlugin.addEventListener("eventtracked", onPlayTimeEventTracked, false);
mediaPlayer.positionTrackingPlugin.addEventListener("eventtracked", onPositionEventTracked, false);

function onPlayTimeEventTracked(e) {
    if (!isNaN(e.detail.trackingEvent.playTimePercentage)) {
        Utilities.log("Type: " + e.type + ", Timestamp: " + e.detail.timestamp + ", Play Time Percentage: " + e.detail.trackingEvent.playTimePercentage);
    } else {
        Utilities.log("Type: " + e.type + ", Timestamp: " + e.detail.timestamp + ", Play Time: " + e.detail.trackingEvent.playTime);
    }
}

function onPositionEventTracked(e) {
    if (!isNaN(e.detail.trackingEvent.positionPercentage)) {
        Utilities.log("Type: " + e.type + ", Timestamp: " + e.detail.timestamp + ", Position Percentage: " + e.detail.trackingEvent.positionPercentage + ", Skipped Past: " + e.detail.skippedPast);
    } else {
        Utilities.log("Type: " + e.type + ", Timestamp: " + e.detail.timestamp + ", Position: " + e.detail.trackingEvent.position + ", Skipped Past: " + e.detail.skippedPast);
    }
}

Getting Started: Xaml and WP8 versions

Setup which events to track:

In code:
var positionTrackingPlugin = new PositionTrackingPlugin();
player.Plugins.Add(positionTrackingPlugin);
positionTrackingPlugin.TrackingEvents.Add(new PositionTrackingEvent() { PositionPercentage = .50, Data = "midpoint " });

positionTrackingPlugin.TrackingEvents.Add(new PositionTrackingEvent() { Position = TimeSpan.FromSeconds(5), Data = "5 seconds" });
var playTimeTrackingPlugin = new PlayTimeTrackingPlugin();
player.Plugins.Add(playTimeTrackingPlugin);

playTimeTrackingPlugin.TrackingEvents.Add(new PlayTimeTrackingEvent() { PlayTime = TimeSpan.FromSeconds(5), Data = "watched 5 seconds" });
playTimeTrackingPlugin.TrackingEvents.Add(new PlayTimeTrackingEvent() { PlayTime = TimeSpan.FromSeconds(15), Data = "watched 15 seconds" });

Or from XAML:
<mmppf:MediaPlayer x:Name="player" Source="http://smf.blob.core.windows.net/samples/videos/wildlife.mp4">
    <mmppf:MediaPlayer.Plugins>
        <mmppf:PositionTrackingPlugin>
            <mmppf:PositionTrackingPlugin.TrackingEvents>
                <mmppf:PositionTrackingEvent PositionPercentage=".5" Data="midpoint"/>
                <mmppf:PositionTrackingEvent Position="00:00:05" Data="5 seconds"/>
            </mmppf:PositionTrackingPlugin.TrackingEvents>
        </mmppf:PositionTrackingPlugin>
        <mmppf:PlayTimeTrackingPlugin>
            <mmppf:PlayTimeTrackingPlugin.TrackingEvents>
                <mmppf:PlayTimeTrackingEvent PlayTime="00:00:05" Data="watched 5 seconds"/>
                <mmppf:PlayTimeTrackingEvent PlayTime="00:00:15" Data="watched 15 seconds"/>
            </mmppf:PlayTimeTrackingPlugin.TrackingEvents>
        </mmppf:PlayTimeTrackingPlugin>
    </mmppf:MediaPlayer.Plugins>
</mmppf:MediaPlayer>

Monitor those events:

positionTrackingPlugin.EventTracked += trackingPlugin_EventTracked; 
playTimeTrackingPlugin.EventTracked += trackingPlugin_EventTracked;

void trackingPlugin_EventTracked(object sender, EventTrackedEventArgs e)
{
    Debug.WriteLine(string.Format("{1} - tracked: {0}", e.TrackingEvent.Data, e.Timestamp));
}

Event arguments

The EventArgs passed to the EventTracked event also supplies additional data to help you make decisions about what to do with the notification. Specifically, it provides:
DateTimeOffset Timestamp Gets the timestamp when the event occurred.
Bool SkippedPast Gets a flag indicating whether or not the user was seeking or scrubbing when the event occurred.
TrackingEventBase TrackingEvent Gets the tracking event instance that occurred. Note: the TrackingEventBase class has a Data property of type object that you can easily insert any custom data into in order to easily pass information along to the event handler.

Position tracking Additional features

By default, the PositionTrackingPlugin will only raise events when moving forward in the timeline. This means rewind and seeking or scrubbing backwards will not fire an event. However, you can easily enable this behavior by setting PositionTrackingPlugin.EvaluateOnForwardOnly = false.

The PositionTrackingEvent also allows you to set PositionPercentage to 0 to indicate that the video has started and 1 to indicate it has finished.

Position tracking events will fire each time the position is reached, not just the first time. If you only care about the first time, you should maintain a list of the tracking events that have already fired and ignore subsequent notifications.

PlayTime tracking Additional features

You can also set PlayTimes greater than the duration of your video that will fire in cases where the user watches the video again. The clock is only reset once you load a new video.

The PlayTimeTrackingEvent also includes a PlayTimePercentage feature to allow you to receive notification when the total time watched is a percentage of the duration. For example, PlayTimePercentage = .5 will fire when the user has watched 1 hour of a 2 hour video (regardless of the position they are at or started from).

The plugin also includes PlayTime and PlayTimePercentage properties that you can query on your own regardless of whether or not you have supplied any tracking events to the plugin.

Precision

Both plugins evaluate events every 250 milliseconds as to give you relatively high precision without creating performance problems.

StartupPosition

The player framework offers a StartupPosition property that you can set to immediately start your video where you left off. If you set this property, position tracking events before the startup position will not be fired in order to simulate state.

Playlists

If you are using the playlist feature in the player framework, you can also supply unique tracking events per PlaylistItem. To do this in the Xaml or WP8 versions, set the attached property:
var playlistItem = new PlaylistItem();
var trackingCollection = new TrackingEventCollection();
trackingCollection.Add(new PositionTrackingEvent() { PositionPercentage = .50, Data = "PositionTrackingEvent: 50%" });
trackingCollection.Add(new PlayTimeTrackingEvent() { PlayTime = TimeSpan.FromSeconds(5), Data = "PlayTimeTrackingEvent: 5 seconds" });
Tracking.SetTrackingEvents(playlistItem, trackingCollection);

Note: all types of tracking events can be supplied and the appropriate plugin will recognize which events are relevant.

Extensibility

You can also create your own tracking events and plugins. Simply create classes that inherit TrackingPluginBase<T> and TrackingEventBase<T> or TrackingPluginBase in JavaScript to build your own. Download the source code to see how the 2 default tracking plugins were built in order to serve as a reference.

Last edited Jan 22, 2013 at 10:20 PM by timgreenfield, version 1