diff --git a/build/ableplayer.js b/build/ableplayer.js index 43c2df6a..52a43ea0 100644 --- a/build/ableplayer.js +++ b/build/ableplayer.js @@ -35,7 +35,7 @@ "use strict"; // maintain an array of Able Player instances for use globally (e.g., for keeping prefs in sync) -var AblePlayerInstances = []; +export var AblePlayerInstances = []; (function ($) { $(document).ready(function () { @@ -791,9 +791,10 @@ var AblePlayerInstances = []; svg[1] = 'M10.15 0.179h0.623c0.069 0 0.127 0.114 0.127 0.253v19.494c0 0.139-0.057 0.253-0.127 0.253h-1.247c-0.069 0-0.126-0.114-0.126-0.253v-19.494c0-0.139 0.057-0.253 0.126-0.253h0.623z'; break; + //I override it case 'captions': svg[0] = '0 0 20 20'; - svg[1] = 'M0.033 3.624h19.933v12.956h-19.933v-12.956zM18.098 10.045c-0.025-2.264-0.124-3.251-0.743-3.948-0.112-0.151-0.322-0.236-0.496-0.344-0.606-0.386-3.465-0.526-6.782-0.526s-6.313 0.14-6.907 0.526c-0.185 0.108-0.396 0.193-0.519 0.344-0.607 0.697-0.693 1.684-0.731 3.948 0.037 2.265 0.124 3.252 0.731 3.949 0.124 0.161 0.335 0.236 0.519 0.344 0.594 0.396 3.59 0.526 6.907 0.547 3.317-0.022 6.176-0.151 6.782-0.547 0.174-0.108 0.384-0.183 0.496-0.344 0.619-0.697 0.717-1.684 0.743-3.949v0 0zM9.689 9.281c-0.168-1.77-1.253-2.813-3.196-2.813-1.773 0-3.168 1.387-3.168 3.617 0 2.239 1.271 3.636 3.372 3.636 1.676 0 2.851-1.071 3.035-2.852h-2.003c-0.079 0.661-0.397 1.168-1.068 1.168-1.059 0-1.253-0.91-1.253-1.876 0-1.33 0.442-2.010 1.174-2.010 0.653 0 1.068 0.412 1.13 1.129h1.977zM16.607 9.281c-0.167-1.77-1.252-2.813-3.194-2.813-1.773 0-3.168 1.387-3.168 3.617 0 2.239 1.271 3.636 3.372 3.636 1.676 0 2.851-1.071 3.035-2.852h-2.003c-0.079 0.661-0.397 1.168-1.068 1.168-1.059 0-1.253-0.91-1.253-1.876 0-1.33 0.441-2.010 1.174-2.010 0.653 0 1.068 0.412 1.13 1.129h1.976z'; + svg[1] = 'M 1.37,3.33 C 6.99,3.35 12.61,3.37 18.22,3.40M 2.54,4.25 C 2.54,4.25 17.35,4.25 17.35,4.25 17.88,4.24 18.56,4.29 18.54,3.90 18.53,3.51 17.85,2.82 17.35,2.82 17.35,2.82 2.54,2.82 2.54,2.82 2.01,2.83 1.60,3.16 1.62,3.55 1.63,3.94 2.03,4.24 2.54,4.25 Z M 1.19,18.83 C 1.19,18.83 2.56,18.83 2.56,18.83 2.61,18.69 1.26,15.41 1.25,10.98 1.25,6.69 2.60,2.77 2.56,2.70 2.56,2.70 1.19,2.70 1.19,2.70 1.14,2.84 -0.08,6.58 -0.08,11.01 -0.07,15.30 1.14,18.69 1.19,18.83 Z M 17.32,18.48 C 17.32,18.48 18.46,18.48 18.46,18.48 18.50,18.34 19.95,14.71 19.95,10.41 19.95,6.24 18.49,2.88 18.46,2.82 18.46,2.82 17.32,2.82 17.32,2.82 17.28,2.95 18.62,6.49 18.62,10.79 18.62,14.95 17.28,18.34 17.32,18.48 17.32,18.48 17.32,18.48 17.32,18.48 Z M 2.56,18.83 C 2.56,18.83 17.37,18.83 17.37,18.83 17.90,18.82 18.58,18.87 18.56,18.48 18.55,18.09 17.87,17.40 17.37,17.40 17.37,17.40 2.56,17.40 2.56,17.40 2.03,17.41 1.62,17.74 1.64,18.13 1.65,18.52 2.05,18.82 2.56,18.83 2.56,18.83 2.56,18.83 2.56,18.83 Z M 4.05,16.73 C 4.05,16.73 15.64,16.73 15.64,16.73 16.05,16.72 16.37,16.24 16.36,15.68 16.34,15.14 16.03,14.70 15.64,14.69 15.64,14.69 4.05,14.69 4.05,14.69 3.63,14.71 3.32,15.18 3.33,15.74 3.34,16.29 3.65,16.72 4.05,16.73 Z M 6.33,13.87 C 6.33,13.87 3.65,13.87 3.65,13.87 3.42,13.86 3.24,13.38 3.24,12.82 3.25,12.28 3.43,11.84 3.65,11.83 3.65,11.83 6.33,11.83 6.33,11.83 6.57,11.85 6.75,12.32 6.74,12.88 6.74,13.43 6.56,13.86 6.33,13.87 Z M 15.85,13.87 C 15.85,13.87 8.48,13.87 8.48,13.87 8.22,13.86 8.01,13.38 8.02,12.82 8.03,12.28 8.23,11.84 8.48,11.83 8.48,11.83 15.85,11.83 15.85,11.83 16.11,11.85 16.32,12.32 16.31,12.88 16.30,13.43 16.10,13.86 15.85,13.87 Z'; break; case 'descriptions': @@ -801,9 +802,10 @@ var AblePlayerInstances = []; svg[1] = 'M17.623 3.57h-1.555c1.754 1.736 2.763 4.106 2.763 6.572 0 2.191-0.788 4.286-2.189 5.943h1.484c1.247-1.704 1.945-3.792 1.945-5.943-0-2.418-0.886-4.754-2.447-6.572v0zM14.449 3.57h-1.55c1.749 1.736 2.757 4.106 2.757 6.572 0 2.191-0.788 4.286-2.187 5.943h1.476c1.258-1.704 1.951-3.792 1.951-5.943-0-2.418-0.884-4.754-2.447-6.572v0zM11.269 3.57h-1.542c1.752 1.736 2.752 4.106 2.752 6.572 0 2.191-0.791 4.286-2.181 5.943h1.473c1.258-1.704 1.945-3.792 1.945-5.943 0-2.418-0.876-4.754-2.447-6.572v0zM10.24 9.857c0 3.459-2.826 6.265-6.303 6.265v0.011h-3.867v-12.555h3.896c3.477 0 6.274 2.806 6.274 6.279v0zM6.944 9.857c0-1.842-1.492-3.338-3.349-3.338h-0.876v6.686h0.876c1.858 0 3.349-1.498 3.349-3.348v0z'; break; + //I override it case 'sign': - svg[0] = '0 0 20 20'; - svg[1] = 'M10.954 10.307c0.378 0.302 0.569 1.202 0.564 1.193 0.697 0.221 1.136 0.682 1.136 0.682 1.070-0.596 1.094-0.326 1.558-0.682 0.383-0.263 0.366-0.344 0.567-1.048 0.187-0.572-0.476-0.518-1.021-1.558-0.95 0.358-1.463 0.196-1.784 0.167-0.145-0.020-0.12 0.562-1.021 1.247zM14.409 17.196c-0.133 0.182-0.196 0.218-0.363 0.454-0.28 0.361 0.076 0.906 0.253 0.82 0.206-0.076 0.341-0.488 0.567-0.623 0.115-0.061 0.422-0.513 0.709-0.82 0.211-0.238 0.363-0.344 0.564-0.594 0.341-0.422 0.412-0.744 0.709-1.193 0.184-0.236 0.312-0.307 0.481-0.594 0.886-1.679 0.628-2.432 1.475-3.629 0.26-0.353 0.552-0.442 0.964-0.653 0.383-2.793-0.888-4.356-0.879-4.361-1.067 0.623-1.644 0.879-2.751 0.82-0.417-0.005-0.636-0.182-1.048-0.145-0.385 0.015-0.582 0.159-0.964 0.29-0.589 0.182-0.91 0.344-1.529 0.535-0.393 0.11-0.643 0.115-1.050 0.255-0.348 0.147-0.182 0.029-0.427 0.312-0.317 0.348-0.238 0.623-0.535 1.222-0.371 0.785-0.326 0.891-0.115 0.987-0.14 0.402-0.174 0.672-0.14 1.107 0.039 0.331-0.101 0.562 0.255 0.825 0.483 0.361 1.499 1.205 1.757 1.217 0.39-0.012 1.521 0.029 2.096-0.368 0.13-0.081 0.167-0.162 0.056 0.145-0.022 0.037-1.433 1.136-1.585 1.131-1.794 0.056-1.193 0.157-1.303 0.115-0.091 0-0.955-1.055-1.477-0.682-0.196 0.12-0.287 0.236-0.363 0.452 0.066 0.137 0.383 0.358 0.675 0.54 0.422 0.27 0.461 0.552 0.881 0.653 0.513 0.115 1.060 0.039 1.387 0.081 0.125 0.034 1.256-0.297 1.961-0.675 0.65-0.336-0.898 0.648-1.276 1.131-1.141 0.358-0.82 0.373-1.362 0.483-0.503 0.115-0.479 0.086-0.822 0.196-0.356 0.086-0.648 0.572-0.312 0.825 0.201 0.167 0.827-0.066 1.445-0.086 0.275-0.005 1.391-0.518 1.644-0.653 0.633-0.339 1.099-0.81 1.472-1.077 0.518-0.361-0.584 0.991-1.050 1.558zM8.855 9.799c-0.378-0.312-0.569-1.212-0.564-1.217-0.697-0.206-1.136-0.667-1.136-0.653-1.070 0.582-1.099 0.312-1.558 0.653-0.388 0.277-0.366 0.363-0.567 1.045-0.187 0.594 0.471 0.535 1.021 1.561 0.95-0.344 1.463-0.182 1.784-0.142 0.145 0.010 0.12-0.572 1.021-1.247zM5.4 2.911c0.133-0.191 0.196-0.228 0.368-0.454 0.27-0.371-0.081-0.915-0.253-0.849-0.211 0.096-0.346 0.508-0.599 0.653-0.093 0.052-0.4 0.503-0.682 0.82-0.211 0.228-0.363 0.334-0.564 0.599-0.346 0.407-0.412 0.729-0.709 1.161-0.184 0.258-0.317 0.324-0.481 0.621-0.886 1.669-0.631 2.422-1.475 3.6-0.26 0.38-0.552 0.461-0.964 0.682-0.383 2.788 0.883 4.346 0.879 4.336 1.068-0.609 1.639-0.861 2.751-0.825 0.417 0.025 0.636 0.201 1.048 0.174 0.385-0.025 0.582-0.169 0.964-0.285 0.589-0.196 0.91-0.358 1.499-0.54 0.422-0.12 0.672-0.125 1.080-0.285 0.348-0.128 0.182-0.010 0.427-0.282 0.312-0.358 0.238-0.633 0.508-1.217 0.398-0.8 0.353-0.906 0.142-0.991 0.135-0.412 0.174-0.677 0.14-1.107-0.044-0.336 0.101-0.572-0.255-0.82-0.483-0.375-1.499-1.22-1.752-1.222-0.395 0.002-1.526-0.039-2.101 0.339-0.13 0.101-0.167 0.182-0.056-0.11 0.022-0.052 1.433-1.148 1.585-1.163 1.794-0.039 1.193-0.14 1.303-0.088 0.091-0.007 0.955 1.045 1.477 0.682 0.191-0.13 0.287-0.245 0.368-0.452-0.071-0.147-0.388-0.368-0.68-0.537-0.422-0.282-0.464-0.564-0.881-0.655-0.513-0.125-1.065-0.049-1.387-0.11-0.125-0.015-1.256 0.317-1.956 0.68-0.66 0.351 0.893-0.631 1.276-1.136 1.136-0.339 0.81-0.353 1.36-0.479 0.501-0.101 0.476-0.071 0.82-0.172 0.351-0.096 0.648-0.577 0.312-0.849-0.206-0.152-0.827 0.081-1.44 0.086-0.28 0.020-1.396 0.533-1.649 0.677-0.633 0.329-1.099 0.8-1.472 1.048-0.523 0.38 0.584-0.967 1.050-1.529z'; + svg[0] = '0 0 15 20'; + svg[1] = 'm 6.4715267,4.8146068 c 0,-0.6982433 0.5444396,-1.2649335 1.2152669,-1.2649335 0.6708273,0 1.2152668,0.5666902 1.2152668,1.2649335 0,0.6982434 -0.5444395,1.2649336 -1.2152668,1.2649336 -0.6708273,0 -1.2152669,-0.5666902 -1.2152669,-1.2649336 z M 9.3071494,7.7661184 13.479566,5.8931735 13.17899,5.109758 8.0918825,6.9228294 H 7.2817046 L 2.1945976,5.109758 1.8940216,5.8931735 6.0664378,7.7661184 v 3.3731566 l -1.6616749,5.59438 0.7575163,0.299367 2.3511363,-5.472103 h 0.3475663 l 2.3511362,5.472103 0.757517,-0.299367 -1.6616754,-5.59438 z'; break; case 'mute': @@ -8453,7 +8455,6 @@ if (thisObj.useTtml && (trackSrc.endsWith('.xml') || trackText.startsWith(' handleEventListeners()) + $(window).on('keydown',function(e) { + if (AblePlayer.nextIndex === 1) { + AblePlayer.lastCreated.onPlayerKeyPress(e); + } + }); + + // Construct an AblePlayer object + // Parameters are: + // media - jQuery selector or element identifying the media. + window.AblePlayer = function(media) { + + + var thisObj = this; + + // Keep track of the last player created for use with global events. + AblePlayer.lastCreated = this; + this.media = media; + if ($(media).length === 0) { + this.provideFallback(); + return; + } + + /////////////////////////////// + // + // Default variables assignment + // + /////////////////////////////// + + // The following variables CAN be overridden with HTML attributes + + // autoplay (Boolean; if present always resolves to true, regardless of value) + if ($(media).attr('autoplay') !== undefined) { + this.autoplay = true; // this value remains constant + this.okToPlay = true; // this value can change dynamically + } + else { + this.autoplay = false; + this.okToPlay = false; + } + + // loop (Boolean; if present always resolves to true, regardless of value) + if ($(media).attr('loop') !== undefined) { + this.loop = true; + } + else { + this.loop = false; + } + + // playsinline (Boolean; if present always resolves to true, regardless of value) + if ($(media).attr('playsinline') !== undefined) { + this.playsInline = '1'; // this value gets passed to YT.Player contructor in youtube.js + } + else { + this.playsInline = '0'; + } + + // poster (Boolean, indicating whether media element has a poster attribute) + if ($(media).attr('poster')) { + this.hasPoster = true; + } + else { + this.hasPoster = false; + } + + // start-time + if ($(media).data('start-time') !== undefined && $.isNumeric($(media).data('start-time'))) { + this.startTime = $(media).data('start-time'); + } + else { + this.startTime = 0; + } + + // debug + if ($(media).data('debug') !== undefined && $(media).data('debug') !== false) { + this.debug = true; + } + else { + this.debug = false; + } + + // Path to root directory of Able Player code + if ($(media).data('root-path') !== undefined) { + // add a trailing slash if there is none + this.rootPath = $(media).data('root-path').replace(/\/?$/, '/'); + } + else { + this.rootPath = this.getRootPath(); + } + + // Volume + // Range is 0 to 10. Best not to crank it to avoid overpowering screen readers + this.defaultVolume = 7; + if ($(media).data('volume') !== undefined && $(media).data('volume') !== "") { + var volume = $(media).data('volume'); + if (volume >= 0 && volume <= 10) { + this.defaultVolume = volume; + } + } + this.volume = this.defaultVolume; + + // Optional Buttons + // Buttons are added to the player controller if relevant media is present + // However, in some applications it might be undesirable to show buttons + // (e.g., if chapters or transcripts are provided in an external container) + + if ($(media).data('use-chapters-button') !== undefined && $(media).data('use-chapters-button') === false) { + this.useChaptersButton = false; + } + else { + this.useChaptersButton = true; + } + + if ($(media).data('use-descriptions-button') !== undefined && $(media).data('use-descriptions-button') === false) { + this.useDescriptionsButton = false; + } + else { + this.useDescriptionsButton = true; + } + + // Silence audio description + // set to "false" if the sole purposes of the WebVTT descriptions file + // is to display description text visibly and to integrate it into the transcript + if ($(media).data('descriptions-audible') !== undefined && $(media).data('descriptions-audible') === false) { + this.exposeTextDescriptions = false; + } + else if ($(media).data('description-audible') !== undefined && $(media).data('description-audible') === false) { + // support both singular and plural spelling of attribute + this.exposeTextDescriptions = false; + } + else { + this.exposeTextDescriptions = true; + } + + // Headings + // By default, an off-screen heading is automatically added to the top of the media player + // It is intelligently assigned a heading level based on context, via misc.js > getNextHeadingLevel() + // Authors can override this behavior by manually assigning a heading level using data-heading-level + // Accepted values are 1-6, or 0 which indicates "no heading" + // (i.e., author has already hard-coded a heading before the media player; Able Player doesn't need to do this) + if ($(media).data('heading-level') !== undefined && $(media).data('heading-level') !== "") { + var headingLevel = $(media).data('heading-level'); + if (/^[0-6]*$/.test(headingLevel)) { // must be a valid HTML heading level 1-6; or 0 + this.playerHeadingLevel = headingLevel; + } + } + + // Transcripts + // There are three types of interactive transcripts. + // In descending of order of precedence (in case there are conflicting tags), they are: + // 1. "manual" - A manually coded external transcript (requires data-transcript-src) + // 2. "external" - Automatically generated, written to an external div (requires data-transcript-div) + // 3. "popup" - Automatically generated, written to a draggable, resizable popup window that can be toggled on/off with a button + // If data-include-transcript="false", there is no "popup" transcript + + if ($(media).data('transcript-div') !== undefined && $(media).data('transcript-div') !== "") { + this.transcriptDivLocation = $(media).data('transcript-div'); + } + else { + this.transcriptDivLocation = null; + } + if ($(media).data('include-transcript') !== undefined && $(media).data('include-transcript') === false) { + this.hideTranscriptButton = true; + } + else { + this.hideTranscriptButton = null; + } + + this.transcriptType = null; + if ($(media).data('transcript-src') !== undefined) { + this.transcriptSrc = $(media).data('transcript-src'); + if (this.transcriptSrcHasRequiredParts()) { + this.transcriptType = 'manual'; + } + } + else if ($(media).find('track[kind="captions"], track[kind="subtitles"]').length > 0) { + // required tracks are present. COULD automatically generate a transcript + if (this.transcriptDivLocation) { + this.transcriptType = 'external'; + } + else { + this.transcriptType = 'popup'; + } + } + + // In "Lyrics Mode", line breaks in WebVTT caption files are supported in the transcript + // If false (default), line breaks are are removed from transcripts in order to provide a more seamless reading experience + // If true, line breaks are preserved, so content can be presented karaoke-style, or as lines in a poem + if ($(media).data('lyrics-mode') !== undefined && $(media).data('lyrics-mode') !== false) { + this.lyricsMode = true; + } + else { + this.lyricsMode = false; + } + + // Transcript Title + if ($(media).data('transcript-title') !== undefined && $(media).data('transcript-title') !== "") { + this.transcriptTitle = $(media).data('transcript-title'); + } + else { + // do nothing. The default title will be defined later (see transcript.js) + } + + // Captions + // data-captions-position can be used to set the default captions position + // this is only the default, and can be overridden by user preferences + // valid values of data-captions-position are 'below' and 'overlay' + if ($(media).data('captions-position') === 'overlay') { + this.defaultCaptionsPosition = 'overlay'; + } + else { // the default, even if not specified + this.defaultCaptionsPosition = 'below'; + } + + // Chapters + if ($(media).data('chapters-div') !== undefined && $(media).data('chapters-div') !== "") { + this.chaptersDivLocation = $(media).data('chapters-div'); + } + + if ($(media).data('chapters-title') !== undefined) { + // NOTE: empty string is valid; results in no title being displayed + this.chaptersTitle = $(media).data('chapters-title'); + } + + if ($(media).data('chapters-default') !== undefined && $(media).data('chapters-default') !== "") { + this.defaultChapter = $(media).data('chapters-default'); + } + else { + this.defaultChapter = null; + } + + // Slower/Faster buttons + // valid values of data-speed-icons are 'animals' (default) and 'arrows' + // 'animals' uses turtle and rabbit; 'arrows' uses up/down arrows + if ($(media).data('speed-icons') === 'arrows') { + this.speedIcons = 'arrows'; + } + else { + this.speedIcons = 'animals'; + } + + // Seekbar + // valid values of data-seekbar-scope are 'chapter' and 'video'; will also accept 'chapters' + if ($(media).data('seekbar-scope') === 'chapter' || $(media).data('seekbar-scope') === 'chapters') { + this.seekbarScope = 'chapter'; + } + else { + this.seekbarScope = 'video'; + } + + // YouTube + 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('youtube-nocookie') !== undefined && $(media).data('youtube-nocookie')) { + this.youTubeNoCookie = true; + } + else { + this.youTubeNoCookie = false; + } + + // Vimeo + if ($(media).data('vimeo-id') !== undefined && $(media).data('vimeo-id') !== "") { + this.vimeoId = $(media).data('vimeo-id'); + } + if ($(media).data('vimeo-desc-id') !== undefined && $(media).data('vimeo-desc-id') !== "") { + this.vimeoDescId = $(media).data('vimeo-desc-id'); + } + + // Skin + // valid values of data-skin are: + // 'legacy' (default), two rows of controls; seekbar positioned in available space within top row + // '2020', all buttons in one row beneath a full-width seekbar + if ($(media).data('skin') == '2020') { + this.skin = '2020'; + } + else { + this.skin = 'legacy'; + } + + // Icon type + // By default, AblePlayer 3.0.33 and higher uses SVG icons for the player controls + // Fallback for browsers that don't support SVG is scalable icomoon fonts + // Ultimate fallback is images, if the user has a custom style sheet that overrides font-family + // Use data-icon-type to force controls to use either 'svg', 'font', or 'images' + this.iconType = 'font'; + this.forceIconType = false; + if ($(media).data('icon-type') !== undefined && $(media).data('icon-type') !== "") { + var iconType = $(media).data('icon-type'); + if (iconType === 'font' || iconType == 'image' || iconType == 'svg') { + this.iconType = iconType; + this.forceIconType = true; + } + } + + if ($(media).data('allow-fullscreen') !== undefined && $(media).data('allow-fullscreen') === false) { + this.allowFullScreen = false; + } + else { + this.allowFullScreen = true; + } + + // Seek interval + // Number of seconds to seek forward or back with Rewind & Forward buttons + // Unless specified with data-seek-interval, the default value is re-calculated in initialize.js > setSeekInterval(); + // Calculation attempts to intelligently assign a reasonable interval based on media length + this.defaultSeekInterval = 10; + this.useFixedSeekInterval = false; // will change to true if media has valid data-seek-interval attribute + 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 calculuation + } + } + + // Now Playing + // Shows "Now Playing:" plus the title of the current track above player + // Only used if there is a playlist + if ($(media).data('show-now-playing') !== undefined && $(media).data('show-now-playing') === false) { + this.showNowPlaying = false; + } + else { + this.showNowPlaying = true; + } + + // TTML support (experimental); enabled for testing with data-use-ttml (Boolean) + if ($(media).data('use-ttml') !== undefined) { + this.useTtml = true; + // The following may result in a console error. + this.convert = require('xml-js'); + } + else { + this.useTtml = false; + } + + // Fallback + // The only supported fallback content as of version 4.0 is: + // 1. Content nested within the