Jump to content

User:Yaron Koren/tmh-engagement.js

From Wikimedia Commons, the free media repository
Note: After saving, you have to bypass your browser's cache to see the changes. Internet Explorer: press Ctrl-F5, Mozilla: hold down Shift while clicking Reload (or press Ctrl-Shift-R), Opera/Konqueror: press F5, Safari: hold down Shift + Alt while clicking Reload, Chrome: hold down Shift while clicking Reload.
// "TimedMediaHandler engagement" script
// Tries to get the amount of time (in seconds) that a user watched/listened to any audio/video file
// handled by the TimedMediaHandler extension. This information is then sent to the API at
// https://commons-play-listener.toolforge.org/, along with the filename and total duration of that
// audio/video (but *no* identifying personal information). All of the information is then aggregated
// together to get a sense of "engagement" for media files, i.e. what percentage is consumed.

// You can have this script get called for your Wikipedia, etc. viewing by adding the following line
// to the /common.js subpage of your user page:
// mw.loader.load( '//commons.wikimedia.org/w/index.php?title=User:Yaron_Koren/tmh-engagement.js&action=raw&ctype=text/javascript' );

// Created by Yaron Koren for the Wiki Project Med Foundation.

( function( mw, $ ) {
	
var allActivePlayers = {};

onPlay = function(event) {
	let player = event.target.player;
	if ( player.timeoutID ) {
		// Cancel the 30-minute "pause" timer.
		clearTimeout(player.timeoutID);
	}

	if ( player.fileName == undefined ) {
		// Initialize data.
		player.fileName = player.tagAttributes['data-mwtitle'];
		allActivePlayers[player.fileName] = player;
	}
};

/**
 * Despite its name, this function is called when the video/audio is either paused or ends naturally.
 */
onPause = function(event) {
	let player = event.target.player;
	if ( player.playAmountSubmitted ) {
		return;
	}
	let totalSeconds = player.duration();
	let playedSeconds = getSecondsPlayed( player );
	if ( playedSeconds >= totalSeconds ) {
		submitPlayerData( player, totalSeconds, playedSeconds );
		player.playAmountSubmitted = true;
		delete allActivePlayers[player.fileName];
		return;
	}
	
	// If the pause goes on for 30 minutes without a restart, assume the user has finished
	// watching/listening, and send the metrics along.
	player.timeoutID = setTimeout(() => {
		if (! player.playAmountSubmitted ) {
			let playedSeconds = getSecondsPlayed( player );
			submitPlayerData( player, player.duration(), playedSeconds );
			player.playAmountSubmitted = true;
			delete allActivePlayers[player.fileName];
		}
		}, 30 * 60 * 1000);
};

mw.hook('tmh.player.loaded').add( ( videojsPlayer ) => {
	videojsPlayer.on('play', onPlay);
	videojsPlayer.on('pause', onPause);
});

window.onpagehide = (event) => {
  for ( const fileName in allActivePlayers ) {
  	let curPlayer = allActivePlayers[fileName];
	let playedSeconds = getSecondsPlayed( curPlayer );
	submitPlayerData( curPlayer, curPlayer.duration(), playedSeconds );
	delete allActivePlayers[fileName];
  }
};

getSecondsPlayed = function( player ) {
	// Calculate total amount played so far.
	let playedRanges = player.played();
	let playedSeconds = 0;
	for (let i = 0; i < playedRanges.length; i++ ) {
		playedSeconds += ( playedRanges.end(i) - playedRanges.start(i) );
	}
	return playedSeconds;
}

submitPlayerData = function( player, totalSeconds, playedSeconds) {
	$.post( 'https://commons-play-listener.toolforge.org',
		{ filename: player.fileName, totalDuration: totalSeconds, amountPlayed: playedSeconds });
}

}( mediaWiki, jQuery ) );