From f82e75e8919cfd98b30c1f05a02598636f634cf6 Mon Sep 17 00:00:00 2001 From: Thulinma Date: Thu, 24 Sep 2015 11:10:02 +0200 Subject: [PATCH] new embed framework - WIP --- lsp/newembed.js | 381 +++++++++++++++++++++++++++++++++++++++++ lsp/test_newembed.html | 49 ++++++ 2 files changed, 430 insertions(+) create mode 100644 lsp/newembed.js create mode 100644 lsp/test_newembed.html diff --git a/lsp/newembed.js b/lsp/newembed.js new file mode 100644 index 00000000..f3c79d2e --- /dev/null +++ b/lsp/newembed.js @@ -0,0 +1,381 @@ +if (typeof mistplayers == 'undefined') { + //no need to define this if it's already there + + var mistplayers = {}; + + //create prototype with empty functions the player should have, so that any that have not been defined return false + function MistPlayer() { + + //return true if this player is to be used for this mimetype + this.formimetype = function (fullmimetype){ return false; }; + + this.name = 'Generic player'; + + //mimetype: e.g. 'video/mp4'; that is withouth the html5, flash, or whatever first part. + this.supported = function(mimetype){ return false; }; + + /* + shape of build options: + { + container: html DOM element, + width: (int) video width, + height: (int) video height, + name: (string) the stream name, + src: (string) the video source string, + mimetype: (string) the mimetype, + islive: (boolean) whether or not this is a live video, + autoplay: (boolean) whether or not to enable autoplay + } + */ + this.build = function(options){ return false; }; + + //creates the player element, including custom functions + this.element = function(tag){ + var ele = document.createElement(tag); + ele.mistplay = function(){ return false; }; + ele.mistpause = function(){ return false; }; + + //(double) value: 0 for muted, 1 for max + ele.mistsetvolume = function(value){ return false; }; + //return the current position, in seconds + ele.mistposition = function(){ return false; }; + + return ele; + }; + } + + /////////////////////////////////////////////////// + //ADD AVAILABLE PLAYERS TO THE MISTPLAYERS OBJECT// + /////////////////////////////////////////////////// + + ////HTML5//////////////////////////////////////////// + var html5 = new MistPlayer(); + mistplayers.html5 = html5; + html5.name = 'HTML5 video element'; + html5.formimetype = function(fullmimetype){ + var t = fullmimetype.split('/'); + return ((t[0] == 'html5') && (t[1] == 'video')); + }; + html5.supported = function(mimetype) { + var support = false; + try { + var v = document.createElement('video'); + if ((v) && (v.canPlayType(mimetype) != "")) { + support = v.canPlayType(mimetype); + } + } catch(e){} + return support; + } + html5.build = function(options){ + var ele = this.element('video'); + + ele.setAttribute('width',options.width); + ele.setAttribute('height',options.height); + ele.setAttribute('src',encodeURI(options.src)); + ele.setAttribute('controls','controls'); + + if (options.autoplay) { + ele.setAttribute('autoplay','controls'); + } + + ele.mistplay = function(){ + this.play(); + }; + ele.mistpause = function(){ + this.pause(); + }; + ele.mistsetvolume = function(value){ + this.volume = value; + }; + ele.mistposition = function(){ + return this.currentTime; + } + + options.container.appendChild(ele); + return ele; + } + + ////FLASH//////////////////////////////////////////// + var flash = new MistPlayer(); + mistplayers.flash = flash; + flash.name = 'Flash object'; + flash.formimetype = function(fullmimetype){ + var t = fullmimetype.split('/'); + return (t[0] == 'flash'); + }; + flash.supported = function(mimetype) { + + var version = 0; + try { + // check in the mimeTypes + version = navigator.mimeTypes['application/x-shockwave-flash'].enabledPlugin.description.replace(/([^0-9\.])/g, '').split('.')[0]; + } catch(e){} + try { + // for our special friend IE + version = new ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable("$version").replace(/([^0-9\,])/g, '').split(',')[0]; + } catch(e){} + version = parseInt(version); + + return version >= parseInt(mimetype); + } + flash.build = function(options){ + var ele = this.element('object'); + ele.setAttribute('id',options.name); + ele.setAttribute('width',options.width); + ele.setAttribute('height',options.height); + + //set flashvars + var flashvars = { + src: encodeURIComponent(options.src), + controlBarMode: 'floating', + initialBufferTime: 5, + expandedBufferTime: 5, + minContinuousPlaybackTime: 3 + }; + //set param elements + var params = { + movie: 'http://fpdownload.adobe.com/strobe/FlashMediaPlayback.swf', + flashvars: [], + allowFullScreen: 'true', + allowscriptaccess: 'always', + wmode: 'direct' + }; + if (options.autoplay) { + params.autoPlay = 'true'; + flashvars.autoPlay = 'true'; + } + if (options.islive) { + flashvars.streamType = 'live'; + } + if (parseInt(options.mimetype) >= 10) { + params.movie = 'http://fpdownload.adobe.com/strobe/FlashMediaPlayback_101.swf'; + } + for (var i in flashvars) { + params.flashvars.push(i+'='+flashvars[i]); + } + params.flashvars = params.flashvars.join('&'); + for (var i in params) { + var param = document.createElement('param'); + ele.appendChild(param); + param.setAttribute('name',i); + param.setAttribute('value',params[i]); + } + + var embed = document.createElement('embed'); + embed.setAttribute('name',options.name); + embed.setAttribute('src',params.movie); + embed.setAttribute('type','application/x-shockwave-flash'); + embed.setAttribute('allowscriptaccess','always'); + embed.setAttribute('allowfullscreen','true'); + embed.setAttribute('width',options.width); + embed.setAttribute('height',options.height); + embed.setAttribute('flashvars',params.flashvars); + ele.appendChild(embed); + + options.container.appendChild(ele); + return ele; + } + + ////SILVERLIGHT////////////////////////////////////// + var silverlight = new MistPlayer(); + mistplayers.silverlight = silverlight; + silverlight.name = 'Silverlight'; + silverlight.formimetype = function(fullmimetype){ + return (fullmimetype == 'silverlight'); + }; + silverlight.supported = function(mimetype) { + var plugin; + + try { + // check in the mimeTypes + plugin = navigator.plugins["Silverlight Plug-In"]; + return !!plugin; + } catch(e){} + try { + // for our special friend IE + plugin = new ActiveXObject('AgControl.AgControl'); + return true; + } catch(e){} + + return false; + } + silverlight.build = function(options){ + var ele = this.element('object'); + + ele.setAttribute('data','data:application/x-silverlight,'); //yes that comma needs to be there + ele.setAttribute('type','application/x-silverlight'); + ele.setAttribute('width',options.width); + ele.setAttribute('height',options.height); + + var params = { + source: encodeURI(options.src), + onerror: 'onSilverlightError', + autoUpgrade: 'true', + background: 'black', + enableHtmlAccess: 'true', + minRuntimeVersion: '3.0.40624.0', + initparams: [] + }; + var initparams = { + autoload: 'false', + enablecaptions: 'true', + joinLive: 'true', + muted: 'false', + playlist: document.createElement('playList') + }; + if (options.autoplay) { + initparams.autoplay = 'true'; + } + var playitems = document.createElement('playListItems'); + initparams.playlist.appendChild(playitems); + var playitem = document.createElement('playListItem'); + playitems.appendChild(playitem); + playitems.setAttribute('mediaSource',encodeURI(options.src)); + playitems.setAttribute('adaptiveStreaming','true'); + initparams.playlist = initparams.playlist.outerHTML; + + for (var i in initparams) { + params.initparams.push(i+'='+initparams[i]); + } + params.initparams = params.initparams.join(','); + for (var i in params) { + var param = document.createElement('param'); + ele.appendChild(param); + param.setAttribute('name',i); + param.setAttribute('value',params[i]); + } + + ele.innerHTML += 'Get Microsoft Silverlight'; + + options.container.appendChild(ele); + return ele; + } + +} //end of player definitions + +function mistembed(streamname) { + + function findPlayer(fullmimetype) { + for (var i in mistplayers) { + if (mistplayers[i].formimetype(fullmimetype)) { + return mistplayers[i]; + } + } + return false; + } + + var video = mistvideo[streamname]; + container = document.createElement('div'), + scripts = document.getElementsByTagName('script'), + me = scripts[scripts.length - 1]; + + if (me.parentNode.hasAttribute('data-forcetype')) { + var forceType = me.parentNode.getAttribute('data-forcetype'); + } + if (me.parentNode.hasAttribute('data-forcesupportcheck')) { + var forceSupportCheck = true; + } + if (me.parentNode.hasAttribute('data-autoplay')) { + var autoplay = true; + } + + // create the container + me.parentNode.insertBefore(container, me); + // set the class to 'mistvideo' + container.setAttribute('class', 'mistvideo'); + // remove script tag + me.parentNode.removeChild(me); + + if(video.error) { + // there was an error; display it + container.innerHTML = 'Error: '+video.error+''; + } + else if ((typeof video.source == 'undefined') || (video.source.length < 1)) { + // no stream sources + container.innerHTML = 'Error: no protocols found'; + } + else { + // no error, and sources found. Check the video types and output the best + // available video player. + + var foundPlayer = false; + + for (var i in video.source) { + if ((forceType) && (video.source[i].type.indexOf(forceType) < 0)) { + video.source[i].rejected = 'This source type is not the one being forced.'; + continue; + } + + var player = findPlayer(video.source[i].type); + var shortmime = video.source[i].type.split('/'); + shortmime.shift(); + shortmime = shortmime.join('/'); + video.source[i].browser_support = false; + + if (player) { + var support = player.supported(shortmime); + if ((support) || (forceType)) { + //either the player is supported by the browser, or this source type is being enforced + + video.source[i].browser_support = Boolean(support); + if (foundPlayer === false) { + foundPlayer = { + protocol: video.source[i], + player: player, + shortmime: shortmime + }; + } + if (!forceSupportCheck) { + break; + } + } + else { + video.source[i].rejected = 'The player for this source type ('+player.name+') is not supported by your browser.'; + } + } + else { + video.source[i].rejected = 'No compatible player found for this source type.'; + } + } + } + + if (foundPlayer) { + // we support this kind of video, so build it. + + //calculations for the size + videowidth = video.width || 250; + videoheight = video.height || 250; + var ratio; + var containerwidth = parseInt(container.scrollWidth); + var containerheight = parseInt(container.scrollHeight); + if(videowidth > containerwidth && containerwidth > 0) { + ratio = videowidth / containerwidth; + videowidth /= ratio; + videoheight /= ratio; + } + if(videoheight > containerheight && containerheight > 0) { + ratio = videoheight / containerheight; + videowidth /= ratio; + videoheight /= ratio; + } + + video.embedded = foundPlayer.player.build({ + container: container, + width: videowidth, + height: videoheight, + src: foundPlayer.protocol.url, + name: streamname, + mimetype: foundPlayer.shortmime, + islive: (video.type == 'live'), + autoplay: autoplay + }); + + return foundPlayer.protocol.type; + } + else { + // of all the source types given, none was supported (eg. no flash and HTML5 video). Display error + container.innerHTML = 'No support for any player found'; + } + + return false; +} diff --git a/lsp/test_newembed.html b/lsp/test_newembed.html new file mode 100644 index 00000000..1a9779f6 --- /dev/null +++ b/lsp/test_newembed.html @@ -0,0 +1,49 @@ + + + Test the stream embedding + + + + + + + +
+
+ +
+
+
+ + \ No newline at end of file