/*
* flowplayer.js 3.2.12. The Flowplayer API
*
* Copyright 2009-2011 Flowplayer Oy
*
* This file is part of Flowplayer.
*
* Flowplayer is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Flowplayer is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Flowplayer. If not, see 1){var u=arguments[1],r=(arguments.length==3)?arguments[2]:{};if(typeof u=="string"){u={src:u}}u=j({bgcolor:"#000000",version:[10,1],expressInstall:"http://releases.flowplayer.org/swf/expressinstall.swf",cachebusting:false},u);if(typeof p=="string"){if(p.indexOf(".")!=-1){var t=[];n(o(p),function(){t.push(new b(this,l(u),l(r)))});return new d(t)}else{var s=c(p);return new b(s!==null?s:l(p),l(u),l(r))}}else{if(p){return new b(p,l(u),l(r))}}}return null};j(window.$f,{fireEvent:function(){var q=[].slice.call(arguments);var r=$f(q[0]);return r?r._fireEvent(q.slice(1)):null},addPlugin:function(p,q){b.prototype[p]=q;return $f},each:n,extend:j});if(typeof jQuery=="function"){jQuery.fn.flowplayer=function(r,q){if(!arguments.length||typeof arguments[0]=="number"){var p=[];this.each(function(){var s=$f(this);if(s){p.push(s)}});return arguments.length?p[arguments[0]]:new d(p)}return this.each(function(){$f(this,l(r),q?l(q):{})})}}}();!function(){var h=document.all,j="http://get.adobe.com/flashplayer",c=typeof jQuery=="function",e=/(\d+)[^\d]+(\d+)[^\d]*(\d*)/,b={width:"100%",height:"100%",id:"_"+(""+Math.random()).slice(9),allowfullscreen:true,allowscriptaccess:"always",quality:"high",version:[3,0],onFail:null,expressInstall:null,w3c:false,cachebusting:false};if(window.attachEvent){window.attachEvent("onbeforeunload",function(){__flash_unloadHandler=function(){};__flash_savedUnloadHandler=function(){}})}function i(m,l){if(l){for(var f in l){if(l.hasOwnProperty(f)){m[f]=l[f]}}}return m}function a(f,n){var m=[];for(var l in f){if(f.hasOwnProperty(l)){m[l]=n(f[l])}}return m}window.flashembed=function(f,m,l){if(typeof f=="string"){f=document.getElementById(f.replace("#",""))}if(!f){return}if(typeof m=="string"){m={src:m}}return new d(f,i(i({},b),m),l)};var g=i(window.flashembed,{conf:b,getVersion:function(){var m,f;try{f=navigator.plugins["Shockwave Flash"].description.slice(16)}catch(o){try{m=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");f=m&&m.GetVariable("$version")}catch(n){try{m=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");f=m&&m.GetVariable("$version")}catch(l){}}}f=e.exec(f);return f?[1*f[1],1*f[(f[1]*1>9?2:3)]*1]:[0,0]},asString:function(l){if(l===null||l===undefined){return null}var f=typeof l;if(f=="object"&&l.push){f="array"}switch(f){case"string":l=l.replace(new RegExp('(["\\\\])',"g"),"\\$1");l=l.replace(/^\s?(\d+\.?\d*)%/,"$1pct");return'"'+l+'"';case"array":return"["+a(l,function(o){return g.asString(o)}).join(",")+"]";case"function":return'"function()"';case"object":var m=[];for(var n in l){if(l.hasOwnProperty(n)){m.push('"'+n+'":'+g.asString(l[n]))}}return"{"+m.join(",")+"}"}return String(l).replace(/\s/g," ").replace(/\'/g,'"')},getHTML:function(o,l){o=i({},o);var n='";return n},isSupported:function(f){return k[0]>f[0]||k[0]==f[0]&&k[1]>=f[1]}});var k=g.getVersion();function d(f,n,m){if(g.isSupported(n.version)){f.innerHTML=g.getHTML(n,m)}else{if(n.expressInstall&&g.isSupported([6,65])){f.innerHTML=g.getHTML(i(n,{src:n.expressInstall}),{MMredirectURL:encodeURIComponent(location.href),MMplayerType:"PlugIn",MMdoctitle:document.title})}else{if(!f.innerHTML.replace(/\s/g,"")){f.innerHTML="Flash version "+n.version+" or greater is required
"+(k[0]>0?"Your version is "+k:"You have no flash plugin installed")+"
"+(f.tagName=="A"?"
Click here to download latest version
":"Download latest version from here
");if(f.tagName=="A"||f.tagName=="DIV"){f.onclick=function(){location.href=j}}}if(n.onFail){var l=n.onFail.call(this);if(typeof l=="string"){f.innerHTML=l}}}}if(h){window[n.id]=document.getElementById(n.id)}i(this,{getRoot:function(){return f},getOptions:function(){return n},getConf:function(){return m},getApi:function(){return f.firstChild}})}if(c){jQuery.tools=jQuery.tools||{version:"3.2.12"};jQuery.tools.flashembed={conf:b};jQuery.fn.flashembed=function(l,f){return this.each(function(){$(this).data("flashembed",flashembed(this,l,f))})}}}();; /** @namespace H5P */ H5P.VideoYouTube = (function ($) { /** * YouTube video player for H5P. * * @class * @param {Array} sources Video files to use * @param {Object} options Settings for the player * @param {Object} l10n Localization strings */ function YouTube(sources, options, l10n) { var self = this; var player; var playbackRate = 1; var id = 'h5p-youtube-' + numInstances; numInstances++; var $wrapper = $(''); var $placeholder = $('', { id: id, text: l10n.loading }).appendTo($wrapper); // Optional placeholder // var $placeholder = $('').appendTo($wrapper); /** * Use the YouTube API to create a new player * * @private */ var create = function () { if (!$placeholder.is(':visible') || player !== undefined) { return; } if (window.YT === undefined) { // Load API first loadAPI(create); return; } if (YT.Player === undefined) { return; } var width = $wrapper.width(); if (width < 200) { width = 200; } var loadCaptionsModule = true; var videoId = getId(sources[0].path); player = new YT.Player(id, { width: width, height: width * (9/16), videoId: videoId, playerVars: { origin: ORIGIN, autoplay: options.autoplay ? 1 : 0, controls: options.controls ? 1 : 0, disablekb: options.controls ? 0 : 1, fs: 0, playlist: options.loop ? videoId : undefined, rel: 0, showinfo: 0, iv_load_policy: 3, wmode: "opaque", start: options.startAt, playsinline: 1 }, events: { onReady: function () { self.trigger('ready'); self.trigger('loaded'); }, onApiChange: function () { if (loadCaptionsModule) { loadCaptionsModule = false; // Always load captions player.loadModule('captions'); } var trackList; try { // Grab tracklist from player trackList = player.getOption('captions', 'tracklist'); } catch (err) {} if (trackList && trackList.length) { // Format track list into valid track options var trackOptions = []; for (var i = 0; i < trackList.length; i++) { trackOptions.push(new H5P.Video.LabelValue(trackList[i].displayName, trackList[i].languageCode)); } // Captions are ready for loading self.trigger('captions', trackOptions); } }, onStateChange: function (state) { if (state.data > -1 && state.data < 4) { // Fix for keeping playback rate in IE11 if (H5P.Video.IE11_PLAYBACK_RATE_FIX && state.data === H5P.Video.PLAYING && playbackRate !== 1) { // YT doesn't know that IE11 changed the rate so it must be reset before it's set to the correct value player.setPlaybackRate(1); player.setPlaybackRate(playbackRate); } // End IE11 fix self.trigger('stateChange', state.data); } }, onPlaybackQualityChange: function (quality) { self.trigger('qualityChange', quality.data); }, onPlaybackRateChange: function (playbackRate) { self.trigger('playbackRateChange', playbackRate.data); }, onError: function (error) { var message; switch (error.data) { case 2: message = l10n.invalidYtId; break; case 100: message = l10n.unknownYtId; break; case 101: case 150: message = l10n.restrictedYt; break; default: message = l10n.unknownError + ' ' + error.data; break; } self.trigger('error', message); } } }); }; /** * Indicates if the video must be clicked for it to start playing. * For instance YouTube videos on iPad must be pressed to start playing. * * @public */ self.pressToPlay = navigator.userAgent.match(/iPad/i) ? true : false; /** * Appends the video player to the DOM. * * @public * @param {jQuery} $container */ self.appendTo = function ($container) { $container.addClass('h5p-youtube').append($wrapper); create(); }; /** * Get list of available qualities. Not available until after play. * * @public * @returns {Array} */ self.getQualities = function () { if (!player || !player.getAvailableQualityLevels) { return; } var qualities = player.getAvailableQualityLevels(); if (!qualities.length) { return; // No qualities } // Add labels for (var i = 0; i < qualities.length; i++) { var quality = qualities[i]; var label = (LABELS[quality] !== undefined ? LABELS[quality] : 'Unknown'); // TODO: l10n qualities[i] = { name: quality, label: LABELS[quality] }; } return qualities; }; /** * Get current playback quality. Not available until after play. * * @public * @returns {String} */ self.getQuality = function () { if (!player || !player.getPlaybackQuality) { return; } var quality = player.getPlaybackQuality(); return quality === 'unknown' ? undefined : quality; }; /** * Set current playback quality. Not available until after play. * Listen to event "qualityChange" to check if successful. * * @public * @params {String} [quality] */ self.setQuality = function (quality) { if (!player || !player.setPlaybackQuality) { return; } player.setPlaybackQuality(quality); }; /** * Start the video. * * @public */ self.play = function () { if (!player || !player.playVideo) { self.on('ready', self.play); return; } player.playVideo(); }; /** * Pause the video. * * @public */ self.pause = function () { self.off('ready', self.play); if (!player || !player.pauseVideo) { return; } player.pauseVideo(); }; /** * Seek video to given time. * * @public * @param {Number} time */ self.seek = function (time) { if (!player || !player.seekTo) { return; } player.seekTo(time, true); }; /** * Get elapsed time since video beginning. * * @public * @returns {Number} */ self.getCurrentTime = function () { if (!player || !player.getCurrentTime) { return; } return player.getCurrentTime(); }; /** * Get total video duration time. * * @public * @returns {Number} */ self.getDuration = function () { if (!player || !player.getDuration) { return; } return player.getDuration(); }; /** * Get percentage of video that is buffered. * * @public * @returns {Number} Between 0 and 100 */ self.getBuffered = function () { if (!player || !player.getVideoLoadedFraction) { return; } return player.getVideoLoadedFraction() * 100; }; /** * Turn off video sound. * * @public */ self.mute = function () { if (!player || !player.mute) { return; } player.mute(); }; /** * Turn on video sound. * * @public */ self.unMute = function () { if (!player || !player.unMute) { return; } player.unMute(); }; /** * Check if video sound is turned on or off. * * @public * @returns {Boolean} */ self.isMuted = function () { if (!player || !player.isMuted) { return; } return player.isMuted(); }; /** * Return the video sound level. * * @public * @returns {Number} Between 0 and 100. */ self.getVolume = function () { if (!player || !player.getVolume) { return; } return player.getVolume(); }; /** * Set video sound level. * * @public * @param {Number} level Between 0 and 100. */ self.setVolume = function (level) { if (!player || !player.setVolume) { return; } player.setVolume(level); }; /** * Get list of available playback rates. * * @public * @returns {Array} available playback rates */ self.getPlaybackRates = function () { if (!player || !player.getAvailablePlaybackRates) { return; } var playbackRates = player.getAvailablePlaybackRates(); if (!playbackRates.length) { return; // No rates, but the array should contain at least 1 } return playbackRates; }; /** * Get current playback rate. * * @public * @returns {Number} such as 0.25, 0.5, 1, 1.25, 1.5 and 2 */ self.getPlaybackRate = function () { if (!player || !player.getPlaybackRate) { return; } return player.getPlaybackRate(); }; /** * Set current playback rate. * Listen to event "playbackRateChange" to check if successful. * * @public * @params {Number} suggested rate that may be rounded to supported values */ self.setPlaybackRate = function (newPlaybackRate) { if (!player || !player.setPlaybackRate) { return; } playbackRate = Number(newPlaybackRate); player.setPlaybackRate(playbackRate); }; /** * Set current captions track. * * @param {H5P.Video.LabelValue} Captions track to show during playback */ self.setCaptionsTrack = function (track) { player.setOption('captions', 'track', track ? {languageCode: track.value} : {}); }; /** * Figure out which captions track is currently used. * * @return {H5P.Video.LabelValue} Captions track */ self.getCaptionsTrack = function () { var track = player.getOption('captions', 'track'); return (track.languageCode ? new H5P.Video.LabelValue(track.displayName, track.languageCode) : null); }; // Respond to resize events by setting the YT player size. self.on('resize', function () { if (!$wrapper.is(':visible')) { return; } if (!player) { // Player isn't created yet. Try again. create(); return; } // Use as much space as possible $wrapper.css({ width: '100%', height: '100%' }); var width = $wrapper[0].clientWidth; var height = options.fit ? $wrapper[0].clientHeight : (width * (9/16)); // Set size $wrapper.css({ width: width + 'px', height: height + 'px' }); player.setSize(width, height); }); } /** * Check to see if we can play any of the given sources. * * @public * @static * @param {Array} sources * @returns {Boolean} */ YouTube.canPlay = function (sources) { return getId(sources[0].path); }; /** * Find id of YouTube video from given URL. * * @private * @param {String} url * @returns {String} YouTube video identifier */ var getId = function (url) { // Has some false positives, but should cover all regular URLs that people can find var matches = url.match(/(?:(?:youtube.com\/(?:attribution_link\?(?:\S+))?(?:v\/|embed\/|watch\/|(?:user\/(?:\S+)\/)?watch(?:\S+)v\=))|(?:youtu.be\/|y2u.be\/))([A-Za-z0-9_-]{11})/i); if (matches && matches[1]) { return matches[1]; } }; /** * Load the IFrame Player API asynchronously. */ var loadAPI = function (loaded) { if (window.onYouTubeIframeAPIReady !== undefined) { // Someone else is loading, hook in var original = window.onYouTubeIframeAPIReady; window.onYouTubeIframeAPIReady = function (id) { loaded(id); original(id); }; } else { // Load the API our self var tag = document.createElement('script'); tag.src = "https://www.youtube.com/iframe_api"; var firstScriptTag = document.getElementsByTagName('script')[0]; firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); window.onYouTubeIframeAPIReady = loaded; } }; /** @constant {Object} */ var LABELS = { highres: '2160p', // Old API support hd2160: '2160p', // (New API) hd1440: '1440p', hd1080: '1080p', hd720: '720p', large: '480p', medium: '360p', small: '240p', tiny: '144p', auto: 'Auto' }; /** @private */ var numInstances = 0; // Extract the current origin (used for security) var ORIGIN = window.location.href.match(/http[s]?:\/\/[^\/]+/); ORIGIN = !ORIGIN || ORIGIN[0] === undefined ? undefined : ORIGIN[0]; // ORIGIN = undefined is needed to support fetching file from device local storage return YouTube; })(H5P.jQuery); // Register video handler H5P.videoHandlers = H5P.videoHandlers || []; H5P.videoHandlers.push(H5P.VideoYouTube); ; /** @namespace H5P */ H5P.VideoPanopto = (function ($) { /** * Panopto video player for H5P. * * @class * @param {Array} sources Video files to use * @param {Object} options Settings for the player * @param {Object} l10n Localization strings */ function Panopto(sources, options, l10n) { var self = this; var player; var playbackRate = 1; var id = 'h5p-panopto-' + numInstances; numInstances++; var $wrapper = $(''); var $placeholder = $('', { id: id, html: ''+a+"%
"+e[n].score+"/"+e[n].maxScore+"
'+i.cp.l10n.slide+' | '+i.cp.l10n.score+"/"+i.cp.l10n.total.toLowerCase()+" |
---|
'+i.cp.l10n.totalScore+'