Last active
December 8, 2021 09:24
-
-
Save yuhui/9fbd4ce5172327cdba6edab0f1825273 to your computer and use it in GitHub Desktop.
Track Brightcove IFRAME video playback events with CustomEvents
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @fileoverview Detects video playback events in the Brightcove player and | |
* send a CustomEvent for each of them. | |
* | |
* @author yuhui | |
* @version 1.0.0 | |
* | |
* @see https://player.support.brightcove.com/coding-topics/overview-player-api.html | |
* Brightcove Player development overview | |
* @see https://docs.brightcove.com/brightcove-player/current-release/Player.html | |
* Brightcove Player API | |
* @see https://html.spec.whatwg.org/#mediaevents | |
* HTML5 media events | |
* | |
* @copyright 2021 Yuhui. | |
* | |
* @license GPL-3.0-or-later | |
* Licensed under the GNU General Public License, Version 3.0 (the "License"); | |
* you may not use this file except in compliance with the License. | |
* You may obtain a copy of the License at | |
* | |
* https://www.gnu.org/licenses/gpl-3.0.html | |
* | |
* Unless required by applicable law or agreed to in writing, software | |
* distributed under the License is distributed on an "AS IS" BASIS, | |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
* See the License for the specific language governing permissions and | |
* limitations under the License. | |
* | |
* @disclaimer This Software is provided "as-is" and any expressed or implied | |
* warranties, including, but not limited to, the implied warranties of | |
* merchantability and fitness for a particular purpose are disclaimed. In no | |
* event shall the regents or contributors be liable for any direct, indirect, | |
* incidental, special, exemplaray, or consequential damages (including, but | |
* not limited to, procurement of substitute goods or services; loss of use, | |
* data, or profits; or business interruption) however caused and on any theory | |
* of liability, whether in contract, strict liability, or tort (including | |
* negligence or otherwise) arising in any way out of the use of this software, | |
* even if advised of the possibility of such damage. | |
*/ | |
/** | |
* @private | |
* Given a playback event, get other metadata related to the event, | |
* then send the event's details in a CustomEvent. | |
* @param {Event} event The playback event. | |
* @this {object} The Brightcove player object. | |
*/ | |
function handlePlaybackEvent_(event) { | |
var eventType = event.type; | |
var eventTarget = event.target; | |
var player = this; | |
var eventName = ''; | |
switch (eventType) { | |
case 'loadeddata': | |
eventName = 'Loaded Data'; | |
break; | |
case 'volumechange': | |
eventName = 'Volume Change'; | |
break; | |
default: | |
eventName = eventType.charAt(0).toUpperCase() + eventType.slice(1); | |
break; | |
} | |
eventName = 'Video ' + eventName; | |
var videoName = player.mediainfo.name; | |
var eventDetail = { | |
player: player, | |
playerEventTarget: eventTarget, | |
playerState: eventType, | |
currentTime: player.currentTime(), | |
duration: player.duration(), | |
muted: player.muted(), | |
playbackRate: player.playbackRate(), | |
videoBufferedPercent: player.bufferedPercent(), | |
videoId: player.mediainfo.id, | |
videoName: videoName, | |
videoTitle: videoName, | |
videoUrl: player.currentSrc(), | |
volume: parseInt(player.volume() * 100), | |
}; | |
var eventInit = { | |
detail: eventDetail, | |
}; | |
var customEvent = new CustomEvent(eventName, eventInit); | |
(window.frameElement || window.parent).dispatchEvent(customEvent); | |
} | |
/** | |
* @public | |
* Post messages to the window frame for specific media playback events. | |
* @param {int} numTries Counter of tries to check that players are valid. | |
* @throws any error from Brightcove's `videojs` object. | |
*/ | |
function handleBrightcovePlayers(numTries) { | |
var players = videojs.getPlayers(); | |
var playerIds = Object.keys(players); | |
if (playerIds.length === 0) { | |
// players are not ready, try again | |
// give up after a total of about 7.5 seconds | |
if (numTries < 10) { | |
// use exponential backoff to delay | |
setTimeout(function() { | |
var numTries = numTries * 2; | |
handleBrightcovePlayers(numTries); | |
}, numTries * 500); | |
} | |
} else { | |
// a Brightcove IFRAME can only include one player | |
var playerId = playerIds[0]; | |
try { | |
videojs.getPlayer(playerId).ready(function() { | |
var player = this; | |
var playerEvents = [ | |
'ended', | |
'loadeddata', | |
'pause', | |
'play', | |
'stalled', | |
'timeupdate', | |
'volumechange', | |
]; | |
playerEvents.forEach(function(playerEvent) { | |
player.on(playerEvent, handlePlaybackEvent_); | |
}); | |
}); | |
} catch (e) { | |
// use a warning, not an error, so that other scripts can run normally | |
console.warn(e); | |
} | |
} | |
} | |
handleBrightcovePlayers(1); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment