/* // JavaScript for Able Player // HTML5 Media API: // http://www.w3.org/TR/html5/embedded-content-0.html#htmlmediaelement // http://dev.w3.org/html5/spec-author-view/video.html // W3C API Test Page: // http://www.w3.org/2010/05/video/mediaevents.html // Uses JW Player as fallback // JW Player configuration options: // http://support.jwplayer.com/customer/portal/articles/1413113-configuration-options-reference // (NOTE: some options are not documented, e.g., volume) // JW Player 6 API reference: // http://support.jwplayer.com/customer/portal/articles/1413089-javascript-api-reference // YouTube Player API for iframe Embeds https://developers.google.com/youtube/iframe_api_reference // YouTube Player Parameters https://developers.google.com/youtube/player_parameters?playerVersion=HTML5 */ /*jslint node: true, browser: true, white: true, indent: 2, unparam: true, plusplus: true */ /*global $, jQuery */ "use strict"; (function ($) { $(document).ready(function () { $('video, audio').each(function (index, element) { if ($(element).data('able-player') !== undefined) { new AblePlayer($(this),$(element)); } }); }); // YouTube player support; pass ready event to jQuery so we can catch in player. window.onYouTubeIframeAPIReady = function() { AblePlayer.youtubeIframeAPIReady = true; $('body').trigger('youtubeIframeAPIReady', []); }; // $(window).keydown(function(e) { if (AblePlayer.nextIndex === 1) { // Only one player on the page; dispatch global key presses to it. AblePlayer.lastCreated.onPlayerKeyPress(e); } }); // Construct an AblePlayer object // Parameters are: // media - jQuery selector or element identifying the media. window.AblePlayer = function(media) { // Keep track of the last player created for use with global events. AblePlayer.lastCreated = this; this.setDefaults(); this.media = media; if ($(media).length === 0) { console.log('ERROR: No media specified.'); return; } if ($(media).attr('autoplay') !== undefined && $(media).attr('autoplay') !== "false") { this.autoplay = true; } else { this.autoplay = false; } // override defaults with values of data-* attributes var includeTranscript = media.data('include-transcript'); if (includeTranscript === undefined || includeTranscript === "") { // If there are caption tracks and no default provided, include transcript. if (media.find('track[kind="captions"], track[kind="subtitles"]').length > 0) { includeTranscript = true; } } if (includeTranscript) { this.includeTranscript = true; } else { this.includeTranscript = false; } if ($(media).data('start-time') !== undefined && $(media).data('start-time') !== "") { this.startTime = $(media).data('start-time'); } else { this.startTime = 0; } if ($(media).data('transcript-div') !== undefined && $(media).data('transcript-div') !== "") { this.transcriptDivLocation = $(media).data('transcript-div'); } if ($(media).data('use-transcript-button') !== undefined && $(media).data('use-transcript-button') === false) { this.useTranscriptButton = false; } if ($(media).data('lyrics-mode') !== undefined && $(media).data('lyrics-mode') !== "false") { this.lyricsMode = true; } if ($(media).data('transcript-title') !== undefined) { // NOTE: empty string is valid; results in no title being displayed this.transcriptTitle = $(media).data('transcript-title'); } if ($(media).data('youtube-id') !== undefined && $(media).data('youtube-id') !== "") { this.youtubeId = $(media).data('youtube-id'); } if ($(media).data('youtube-desc-id') !== undefined && $(media).data('youtube-desc-id') !== "") { this.youtubeDescId = $(media).data('youtube-desc-id'); } if ($(media).data('debug') !== undefined && $(media).data('debug') !== "false") { this.debug = true; } if ($(media).data('volume') !== undefined && $(media).data('volume') !== "") { var volume = $(media).data('volume'); if (volume >= 0 && volume <= 1) { this.defaultVolume = volume; } } if ($(media).data('icon-type') !== undefined && $(media).data('icon-type') !== "") { var iconType = $(media).data('icon-type'); if (iconType === 'font' || iconType == 'image') { this.iconType = iconType; } } if ($(media).data('seek-interval') !== undefined && $(media).data('seek-interval') !== "") { var seekInterval = $(media).data('seek-interval'); if (/^[1-9][0-9]*$/.test(seekInterval)) { // must be a whole number greater than 0 this.seekInterval = seekInterval; this.useFixedSeekInterval = true; // do not override with 1/10 of duration } } if ($(media).data('show-now-playing') !== undefined && $(media).data('show-now-playing') !== "false") { this.showNowPlaying = true; } if ($(media).data('fallback') !== undefined && $(media).data('fallback') !== "") { var fallback = $(media).data('fallback'); if (fallback === 'jw') { this.fallback = fallback; } } if ($(media).data('test-fallback') !== undefined && $(media).data('test-fallback') !== "false") { this.testFallback = true; } if ($(media).data('fallback-path') !== undefined && $(media).data('fallback-path') !== "false") { this.fallbackPath = $(media).data('fallback-path'); } if ($(media).data('translation-path') !== undefined && $(media).data('translation-path') !== "false") { this.translationPath = $(media).data('translation-path'); } if ($(media).data('lang') !== undefined && $(media).data('lang') !== "") { var lang = $(media).data('lang'); if (lang.length == 2) { this.lang = lang; } } if ($(media).data('force-lang') !== undefined && $(media).data('force-lang') !== "false") { this.forceLang = true; } if ($(media).data('meta-div') !== undefined && $(media).data('meta-div') !== "") { this.metaDiv = $(media).data('meta-div'); } if ($(media).data('search') !== undefined && $(media).data('search') !== "") { // conducting a search currently requires an external div in which to write the results if ($(media).data('search-div') !== undefined && $(media).data('search-div') !== "") { this.searchString = $(media).data('search'); this.searchDiv = $(media).data('search-div'); } } this.ableIndex = AblePlayer.nextIndex; AblePlayer.nextIndex += 1; this.title = $(media).attr('title'); // populate translation object with localized versions of all labels and prompts // use defer method to defer additional processing until text is retrieved this.tt = []; var thisObj = this; $.when(this.getTranslationText()).then( function () { if (thisObj.countProperties(thisObj.tt) > 50) { // close enough to ensure that most text variables are populated thisObj.setup(); if (thisObj.startTime > 0 && !thisObj.autoplay) { // scrub ahead to startTime, but don't start playing // can't do this in media event listener // because in some browsers no media events are fired until media.play is requested // even if preload="auto" thisObj.onMediaUpdateTime(); } } else { // can't continue loading player with no text console.log('ERROR: Failed to load translation table'); } } ); }; // Index to increment every time new player is created. AblePlayer.nextIndex = 0; AblePlayer.prototype.setup = function() { var thisObj = this; if (this.debug && this.startTime > 0) { console.log('Will start media at ' + this.startTime + ' seconds'); } this.reinitialize().then(function () { if (!thisObj.player) { // No player for this media, show last-line fallback. thisObj.provideFallback(); } else { thisObj.setupInstance().then(function () { thisObj.recreatePlayer(); }); } }); }; AblePlayer.youtubeIframeAPIReady = false; AblePlayer.loadingYoutubeIframeAPI = false; })(jQuery);