1// HTML5 responsive player 2function createPlyr(options){ 3 4 // This is the easiest way to have default options. 5 // call with settings.varname 6 var settings = $.extend({ 7 // These are the defaults. 8 srctype: 'video/mp4', 9 caption: '', 10 captionName: '.vid-cap-1', 11 playerName: '#plyr-1', 12 autoplay: true, 13 is_ext: false, 14 track: '' 15 // video 16 // logo 17 // player 18 }, options ); 19 20 var sourceData = { 21 type: 'video', 22 sources: [{ 23 src: settings.video, // the video filepath OR youtube URL or ID OR vimeo URL or ID 24 type: settings.srctype // 'video/mp4' or 'youtube' or 'vimeo' 25 }], 26 poster: settings.logo, 27 autoplay: settings.autoplay 28 }; 29 30 if (settings.track) { 31 sourceData.tracks = [{ 32 kind: 'captions', 33 label: 'English captions', 34 srclang: 'en', 35 src: settings.track, 36 default: true 37 }]; 38 } 39 40 settings.player.source(sourceData); 41 42 $(settings.captionName).html(settings.caption); 43 44 // Plyr's built-in Firefox VTT parser fails on REGION/NOTE/STYLE blocks and 45 // non-standard formatting that the browser's native parser handles fine. 46 // Override it with our own timeupdate-driven renderer. 47 if (settings.track && navigator.userAgent.indexOf('Firefox') !== -1) { 48 _plyrLoadFirefoxCaptions(settings); 49 } 50} 51 52// Parse a VTT string into [{start, end, text}] â handles REGION/NOTE/STYLE blocks. 53function _plyrParseVTT(text) { 54 var captions = []; 55 var blocks = text.replace(/\r\n/g, '\n').replace(/\r/g, '\n').split('\n\n'); 56 57 for (var i = 0; i < blocks.length; i++) { 58 var block = blocks[i].trim(); 59 if (!block || /^WEBVTT/.test(block) || /^NOTE/.test(block) || 60 /^REGION/.test(block) || /^STYLE/.test(block)) { 61 continue; 62 } 63 64 var lines = block.split('\n'); 65 var arrowIdx = -1; 66 for (var j = 0; j < lines.length; j++) { 67 if (lines[j].indexOf('-->') !== -1) { arrowIdx = j; break; } 68 } 69 if (arrowIdx === -1) continue; 70 71 var parts = lines[arrowIdx].split('-->'); 72 var start = _plyrVttToSec(parts[0].trim()); 73 var end = _plyrVttToSec(parts[1].trim().split(/\s/)[0]); 74 var cueText = lines.slice(arrowIdx + 1).join('\n').trim(); 75 76 if (!isNaN(start) && !isNaN(end) && cueText) { 77 captions.push({ start: start, end: end, text: cueText }); 78 } 79 } 80 return captions; 81} 82 83function _plyrVttToSec(t) { 84 var p = t.split(':'); 85 if (p.length === 3) { 86 return parseFloat(p[0]) * 3600 + parseFloat(p[1]) * 60 + parseFloat(p[2]); 87 } 88 if (p.length === 2) { 89 return parseFloat(p[0]) * 60 + parseFloat(p[1]); 90 } 91 return NaN; 92} 93 94function _plyrLoadFirefoxCaptions(settings) { 95 $.ajax({ 96 url: settings.track, 97 success: function(data) { 98 var captions = _plyrParseVTT(data); 99 var videoEl = document.querySelector(settings.playerName + ' video'); 100 var captionEl = document.querySelector(settings.playerName + ' .plyr__captions'); 101 102 if (!videoEl || !captionEl || !captions.length) return; 103 104 // Remove any previous handler stored on this element 105 if (videoEl._plyrFirefoxHandler) { 106 videoEl.removeEventListener('timeupdate', videoEl._plyrFirefoxHandler); 107 } 108 109 videoEl._plyrFirefoxHandler = function() { 110 var t = videoEl.currentTime; 111 var text = ''; 112 for (var i = 0; i < captions.length; i++) { 113 if (t >= captions[i].start && t <= captions[i].end) { 114 text = captions[i].text; 115 break; 116 } 117 } 118 var span = captionEl.querySelector('span'); 119 if (!span) { 120 span = document.createElement('span'); 121 captionEl.appendChild(span); 122 } 123 span.innerHTML = text; 124 }; 125 126 videoEl.addEventListener('timeupdate', videoEl._plyrFirefoxHandler); 127 } 128 }); 129} 130 131 132function replaceIframe(options) { 133 134 var settings = $.extend({ 135 // These are the defaults. 136 logo: '/images/vidplaceholder.jpg', 137 caption: '', 138 captionName: '.vid-cap-1', 139 playerName: '#extplyr-1', 140 autoplay: true, 141 // video 142 }, options ); 143 144 // set new iframce src 145 $(settings.playerName + ' iframe').attr('src', settings.video); 146 // set new caption
147 $(settings.captionName).html(settings.caption); 148 149} // end replace iframe
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.