/*!
* OSMF Edge Media Player
* Unified Flash & HTML5 Javascript
*
* written by Emanuele "flashedge" Manco
* http://activeden.net/user/flashedge
*
* Version 1.6.3
*/
function edgePlayer(target, w, h) {
//console.log("Initializing Edge Player...");
this.$ = jQuery;
this.flash = {};
this.html5 = {};
if (target != "html5" && target != "flash" && edgePlayer.flash != undefined) { // target flash if there is no target, falls back to html5
target = "flash";
}
if (target == "html5" && Modernizr.video && Modernizr.audio) {
//console.log("HTML5 Video & Audio are supported.");
if (edgePlayer.html5.type == "video" || edgePlayer.html5.type == "media") {
initHTML5(edgePlayer.html5.id, edgePlayer.html5.type, w+"px", h+"px", edgePlayer.html5.volume, edgePlayer.html5.autoHide, edgePlayer.html5.m4v, edgePlayer.html5.ogv, edgePlayer.html5.webm, edgePlayer.html5.poster);
} else if (edgePlayer.html5.type == "audio") {
initHTML5(edgePlayer.html5.id, edgePlayer.html5.type, w+"px", h+"px", edgePlayer.html5.volume, edgePlayer.html5.autoHide, null, null, null, null, edgePlayer.html5.mp3, edgePlayer.html5.oga);
}
} else if (target == "flash" || Modernizr.video != true || Modernizr.audio != true) {
// check if we really have flash available first
//console.log("No HTML5 for this browser.");
initFlash(edgePlayer.flash.id, edgePlayer.flash.poster, edgePlayer.flash.media, edgePlayer.flash.type, w, h, edgePlayer.flash.setup, edgePlayer.flash.playlist, edgePlayer.flash.player);
}
function initFlash(flashID, posterPath, mediaPath, mediaType, mediaWidth, mediaHeight, setupPath, playlistPath, playerPath) {
var flashvars = edgePlayer.flash/*{}*/;
var params = {
menu: "true",
allowfullscreen: "true",
allowscriptaccess: "always",
wmode: "direct"
};
var attributes = {
id: flashID,
name: flashID
};
//playlistPath ? flashvars = { setup: setupPath, playlist: playlistPath, player: playerPath } : flashvars = { poster: posterPath, media: mediaPath, type: mediaType, setup: setupPath, player: playerPath };
if (edgePlayer.flash.volume != null) {
//console.log("volume is "+edgePlayer.flash.volume);
flashvars["volume"] = edgePlayer.flash.volume;
}
swfobject.embedSWF("swf/shell.swf", flashID, mediaWidth, mediaHeight, "10.2.0","swf/expressInstall.swf", flashvars, params, attributes, checkFlash);
}
function checkFlash(e) {
if (e.success) {
//console.log("Flash loaded successfully");
} else {
//console.log("Flash failed loading");
edgePlayer("html5", w, h);
}
}
// handles the html5 version of the player
function initHTML5(jpID, mediaType, mediaWidth, mediaHeight, mediaVolume, autoHide, m4vPath, ogvPath, webmvPath, posterPath, mp3Path, oggPath) {
jpID = "#"+jpID;
var deviceAgent = navigator.userAgent.toLowerCase();
var iOS = deviceAgent.match(/(iphone|ipod|ipad)/);
// playlist vars
var playlist;
var playlistEnabled = false;
// check if we have playlist
if (edgePlayer.html5.playlist != undefined || edgePlayer.html5.playlist != null) {
playlist = edgePlayer.html5.playlist;
playlistEnabled = true;
//console.log("detected playlist!");
var agent = deviceAgent.match(/(iphone|ipod)/);
if (agent) {
//console.log("You're on iPhone!");
$("div.jp-video .jp-controls-holder, .jp-toolbar, .jplaylist").css("display","block");
}
}
//console.log("playlist? "+playlistEnabled);
$(jpID).css({ opacity: 0, width: mediaWidth, height: mediaHeight });
$(".jp-video-play").css({ opacity: 0 }); //buggy on iOS
$(".jp-video-play, .jp-sizer").css({ width: mediaWidth, height: mediaHeight, opacity:0});
$(".jp-audio, .jp-video, jp-gui").css({ width: mediaWidth, height: mediaHeight });
var clicked = false; // boolean statement for user tracking
var playing = false; // boolean statement to get player status
if (edgePlayer.html5.compactMode) {
$(".jp-gui, .jp-playlist, .jp-nav, .playlistNav.previous, .playlistNav.next").addClass("compact");
}
// main media switch, for single or multiple types
switch (mediaType) {
case "video": initVideo();
break;
case "audio": initAudio();
break;
case "media": initPlaylist();
break;
case "playlist": initPlaylist();
break;
default: initVideo();
}
function initVideo() {
if (playlistEnabled == false) { // check if there is a playlist
$(jpID).jPlayer({
ready: function () {$(this).jPlayer("setMedia", { m4v: m4vPath, ogv: ogvPath, webmv: webmvPath, poster: posterPath }); },
swfPath: "js",
supplied: "webmv, ogv, m4v",
size: { width: mediaWidth, height: mediaHeight, cssClass: "jp-sizer"},
loop: false,
volume: mediaVolume,
// shows native controls on iDevices if uncommented
/*nativeVideoControls: {
ipad: /ipad/,
iphone: /iphone/,
ipod: /ipod/
},*/
autohide: { restored: false, full: false, fadeOut: 600, fadeIn:200, hold: 1000}, // disable builtin autohide, which is buggy
size: {width: mediaWidth, height: mediaHeight, cssClass: ""}
});
}
}
function initAudio() {
if (playlistEnabled == false) { // check if there is a playlist
$(jpID).jPlayer({
ready: function () {
$(this).jPlayer("setMedia", {
mp3: mp3Path,
oga: oggPath
});
},
swfPath: "js",
supplied: "mp3, oga",
wmode: "window",
volume: mediaVolume
});
}
}
// playlist
function initPlaylist() {
if (playlistEnabled) {
//console.log("Playlist initialized");
var myPlaylist = new jPlayerPlaylist({
jPlayer: jpID,
cssSelectorAncestor: "#jp_container_1"
}, playlist,
{
playlistOptions: {
autoPlay: false,
loopOnPrevious: false,
shuffleOnLoop: true,
enableRemoveControls: false,
displayTime: 0,
addTime: 'fast',
removeTime: 'fast',
shuffleTime: 'slow'
},
swfPath: "js",
supplied: "webmv, ogv, m4v, oga, mp3"
});
$(jpID).jPlayer({
volume: mediaVolume,
size: {width: mediaWidth, height: mediaHeight, cssClass: ""}
});
$(jpID).css({width: mediaWidth, height: mediaHeight});
trackClick();
initFade();
initAutoHide();
initPlayToggle();
$('.jp-interface').css({ opacity: 0 }); // Hides at startup the controlbar
$(".jp-toolbar").wrap("
").css({marginTop: "-35px"}); // wraps toolbar inside a new header for masking
//$("#jpToolbar").slideUp(0);
// structurize the playlist and arrange graphics
setTimeout( function populatePlaylist() {
var p = edgePlayer.html5.playlist;
$(".jp-toolbar p").empty().append(p[0]["title"]);
//$(jpID).append("");
for (var i = 0; i < p.length; i++) {
// hack the structure and inject the thumbnail for each one
$(".jp-playlist ul li").each(function(index) {
//var j = 0;
if (index == i) {
//var obj = p[i]["poster"];
var img = new Image();
if (p[i]["thumb"]) {
img.src = p[i]["thumb"];
} else {
img.src = p[i]["poster"];
}
var thumb = $(img);
var x = 0;
$(this).find(".jp-playlist-item").wrapInner("").prepend(thumb);
$(this).find("img").wrap("");
// fix artist structure
$(this).find(".jp-artist").remove();
var artist = p[i]["artist"];
$(this).find(".jp-playlist-item").append("by "+artist+"");
//$(this).find(".jp-playlist-item").wrapInner("")
}
});
}
$(".jp-playlist").wrap("");
$(".jp-playlist").before("");
$(".jp-playlist").css("display","block");
if (edgePlayer.html5.compactMode) $(".playlistNav").css({marginTop:"-16px"});
var h = $(".jp-playlist").height(); // step height
var y = 0; // current position
var max = Math.floor((p.length/3)-1)*240; // maximum height
// previous click behaviour
$(".playlistNav .previous")
.css({opacity:0.2})
.click( function() {
if (y != 0) {
$(".jp-playlist ul").animate({
top: '+='+h
}, 1, 'easeOutQuad',
function(){
if (y < 0) {
$(".playlistNav .previous, #playlistNav .next").stop().animate({ opacity: 0.8}, 500);
} else {
$(".playlistNav .previous").stop().animate({ opacity: 0.2}, 500);
$(".playlistNav .next").stop().animate({ opacity: 0.8}, 500);
}
}
);
y += h;
}
});
// next click behaviour
$(".playlistNav .next")
.css({opacity:0.8})
.click( function() {
if (-y < max) {
$(".jp-playlist ul").animate({
top: '-='+h
}, 1, 'easeOutQuad',
function() {
if (-y < max) {
$(".playlistNav .previous").stop().animate({ opacity: 0.8}, 500);
$(".playlistNav .next").stop().animate({ opacity: 0.8}, 500);
} else {
$(".playlistNav .previous").stop().animate({ opacity: 0.8}, 500);
$(".playlistNav .next").stop().animate({ opacity: 0.2}, 500);
}
});
y -= h;
}
});
// next & previous mouse hovers
$(".playlistNav .previous, .playlistNav .next").hover (
function() {
var o = ($(this).css("opacity"));
if (o > 0.7) $(this).animate({opacity:1});},
function() {
var o = ($(this).css("opacity"));
if (o > 0.7) $(this).animate({ opacity:0.8});
});
if (p.length <= 3) $(".playlistNav").remove(); // remove navigation if there are only 3 entries
initToolbar();
}, 500);// delay whole function half second, until playlist is ready
function initToolbar() {
var n = 0;
// find current title and slap it in the toolbar
$(jpID).bind($.jPlayer.event.play, function() {
$(".jp-playlist ul li").each(function(index) {
if ( $(this).attr("class") == "jp-playlist-current" ) {
n = index;
}
});
//console.log("Playing number: "+n);
$(".jp-toolbar p").empty().append(edgePlayer.html5.playlist[n]["title"]);
});
// hack for rewinding to the first item
$(jpID).bind($.jPlayer.event.ended, function(event) {
//console.log("ended! "+n +edgePlayer.html5.playlist.length );
if (n == edgePlayer.html5.playlist.length-1)
{myPlaylist.play(0);}
});
}
//hide playlist
$(".jplaylist").css("display", "none");
$(".jp-toolbar .playlistBtn").click(function() {
$(".jplaylist").toggle(0);
});
var pageURL = window.location.href;
$(".jp-toolbar .tweetBtn").click(function() {
window.open("http://twitter.com/?status="+pageURL);
//console.log(pageURL);
});
$(".jp-toolbar .likeBtn").click(function() {
window.open("http://www.facebook.com/sharer.php?u="+pageURL);
});
}
}
if (mediaType == "video" && playlistEnabled == false) { // functions to enable when one single video is being played
//console.log("rewind?");
$(jpID).jPlayer({ fullScreen: false}); // reset fullscreen if enabled
clicked = false; // reset user interaction
trackClick();
// shows again the poster when video has ended
$(jpID).bind($.jPlayer.event.ended + ".jp-repeat", function(event) {
//console.log("ended");
// initial animation setup
$(jpID).css({ opacity: 0 });
$(".jp-video-play").css({ opacity: 0 });
// add replay icon class
$("div.jp-video-play a.jp-video-play-icon").removeClass("jp-video-play-icon").addClass("jp-video-replay-icon");
$(this).jPlayer("setMedia", {m4v: m4vPath, ogv: ogvPath, webmv: webmvPath, poster: posterPath});
$(this).jPlayer({ fullScreen: false}); // reset fullscreen if enabled
clicked = false; // reset user interaction
$('.jp-interface').css({ opacity: 0 }); // hides the controlbar
showPlayer();
});
initFade();
initAutoHide();
initPlayToggle();
$('.jp-interface').css({ opacity: 0 }); // Hides at startup the controlbar
}
function initFade() { // fades in once the player is ready
//$(jpID).bind($.jPlayer.event.canplay, function(event) { // event does not fire in safari, argh!
$(jpID).find("#jp_poster_0").bind("load", function() { // using a simple image load event
//console.log("player ready");
showPlayer();
});
}
function showPlayer() { // shows the player
//console.log("show");
$('a.jp-video-play-icon').css('display', 'block');
$(jpID).stop().animate({ "opacity": 1 }, 300);
clicked == false ? $(".jp-video-play").css("display","block").delay(200).animate({ "opacity": 1 }, 500) : $(".jp-video-play").css("display","none");
}
function trackClick() { // tracks the user interaction
$(".jp-video-play, .jp-playlist").click( function() {
if (clicked == false) { // happens only once
//console.log("click");
clicked = true;
$('.jp-interface').stop().animate({ opacity: 1 }, 100);
if (edgePlayer.html5.compactMode) $('.jp-controls-holder').css({marginTop: "36px"}).stop().animate({ marginTop: "0px" }, 'slow');
$(".jp-toolbar").stop().animate({ marginTop: "0px" }, 'slow');
//$("#jpToolbar").slideDown('slow');
}
});
}
function initAutoHide() {
// Hides the controlbar when user is idle or away and shows it again when active
setIdleTimeout(6000); // 6 seconds
setAwayTimeout(10000); // 10 seconds
document.onIdle = function() {
if (autoHide) {
//$('.jp-interface').stop().animate({ "opacity": 0 }, 250);
edgePlayer.html5.compactMode ? $(this).find('.jp-controls-holder').stop().animate({ marginTop: "36px" }, 'fast') : $(this).find('.jp-interface').stop().animate({ opacity: 0 }, 250);
$(".jp-toolbar").stop().animate({ marginTop: "-35px" }, 'fast');
//$("#jpToolbar").slideUp('fast');
if ($(".jplaylist").is(":visible")) $(".jplaylist").toggle('fast');
}
}
document.onAway = function() {
if (autoHide) {
//$('.jp-interface').stop().animate({ "opacity": 0 }, 250);
edgePlayer.html5.compactMode ? $(this).find('.jp-controls-holder').stop().animate({ marginTop: "36px" }, 'fast') : $(this).find('.jp-interface').stop().animate({ opacity: 0 }, 250);
$(".jp-toolbar").stop().animate({ marginTop: "-35px" }, 'fast');
//$("#jpToolbar").slideUp('fast');
if ($(".jplaylist").is(":visible")) $(".jplaylist").toggle('fast');
}
}
document.onBack = function(isIdle, isAway) {
if (isIdle && clicked) {
//$('.jp-interface').stop().animate({ "opacity": 1 }, 250);
edgePlayer.html5.compactMode ? $(this).find('.jp-controls-holder').stop().animate({ marginTop: "0px" }, 'slow') : $(this).find('.jp-interface').stop().animate({ opacity: 1 }, 250);
$(".jp-toolbar").stop().animate({ marginTop: "0px" }, 'slow');
//$("#jpToolbar").slideDown('slow');
}
if (isAway && clicked) {
//$('.jp-interface').stop().animate({ "opacity": 1 }, 250);
edgePlayer.html5.compactMode ? $(this).find('.jp-controls-holder').stop().animate({ marginTop: "0px" }, 'slow') : $(this).find('.jp-interface').stop().animate({ opacity: 1 }, 250);
$(".jp-toolbar").stop().animate({ marginTop: "0px" }, 'slow');
//$("#jpToolbar").slideDown('slow');
}
}
// Hides the controlbar on rollout and shows on roll over.
$('.jp-type-playlist, .jp-type-single').addClass('jp-area'); // declared area
$('.jp-area').hover( function () {
if (clicked && autoHide) {
edgePlayer.html5.compactMode ? $('.jp-controls-holder').stop().animate({ marginTop: "0px" }, 'slow') : $('.jp-interface').stop().animate({ opacity: 1 }, 200);
$(".jp-toolbar").stop().animate({ marginTop: "0px" }, 'slow');
//$("#jpToolbar").slideDown('slow');
}
}, function () {
if (clicked && autoHide) {
edgePlayer.html5.compactMode ? $('.jp-controls-holder').stop().animate({ marginTop: "36px" }, 'fast') : $('.jp-interface').stop().animate({ opacity: 0 }, 200);
$(".jp-toolbar").stop().animate({ marginTop: "-35px" }, 'fast');
//$("#jpToolbar").slideUp('fast');
if ($(".jplaylist").is(":visible")) $(".jplaylist").toggle('fast');
}
});
}
function initPlayToggle() {
// tracks playing state
$(jpID).bind($.jPlayer.event.play, function() { playing = true; });
$(jpID).bind($.jPlayer.event.pause, function() { playing = false; });
$('.jquery_jplayer, #jp_video_0, #jp_audio_0, #jp_poster_0').click (function () {
playing ? $(jpID).jPlayer("pause") : $(jpID).jPlayer("play"); // toggle play-pause
} );
}
}
}
// additional custom function for arranging jPlayer
function arrangePlayer(target, w, h){
$('a.jp-video-play-icon').css('display', 'block');
var targetID = $(target).parent().parent().attr('id');
//console.log(targetID);
var playing = true;
var clicked = false;
$(target).parent().find('.jp-video-play').css('display', 'block');
// tracks user interaction
$(target).parent().find('.jp-video-play').click(function() {
$(target).parent().find('.jp-interface').stop().animate({ opacity: 1 }, 200);
if (clicked == false) $(target).find('video').css({ width: w, height: h });
clicked = true;
});
// pause event
$(target).bind($.jPlayer.event.pause, function() {
$(target).parent().find('.jp-video-play').css('display','block');
$(target).parent().find('.jp-video-play').stop().animate({opacity: 1 }, 200);
playing = false;
var current = $(target).parent().parent().parent().attr('id');
$('#callback').text("Paused: "+current);
});
// play event
$(target).bind($.jPlayer.event.play, function() {
$(target).parent().find('.jp-video-play').stop().animate({
opacity: 0
}, 200, function() {
// Animation complete.
$(target).parent().find('.jp-video-play').css('display','none');
});
playing = true;
var current = $(target).parent().parent().parent().attr('id');
var next = $("#"+current).next().attr('id');
$('#callback').text("Currently playing: "+current);
if (next == undefined) next = $("#"+current).parent().find(':first-child').attr('id');
nextVideo = $("#"+next).find(".jp-jplayer").attr('id');
//console.log("current is: "+current+ " next is "+next +" / "+nextVideo);
});
// adds play/pause toggle
$(target).click( function() {
$(this).bind($.jPlayer.event.play, function() {
playing = true;
});
$(this).bind($.jPlayer.event.pause, function() { playing = false;});
playing ? $(this).jPlayer("pause") : $(this).jPlayer("play");
});
$(target).parent().hover( function() {
if (clicked && $(this).find(".jp-video-play").is(":visible") == false) $(this).find('.jp-interface').stop().animate({ opacity: 1 }, 200);}, function() { if (clicked) $(this).find('.jp-interface').stop().animate({ opacity: 0 }, 200);
});
// fix the silly built-in classes
function resize() {
$(target).parent().parent().removeClass('jp-video-270p'); // get rid of the built-in class
$(target).parent().parent().addClass('jp-sizer');
$('.jp-sizer').css({ width: w, height: h});
$(target).css({ width: w, height: h });
$(target).find('img, video').css({ width: w, height: h });
$(target).parent().css({ width: w, height: h });
$(target).parent().find('.jp-video-play, .jp-audio, .jp-video, jp-gui').css({ width: w, height: h });
if (w < 400 || h < 250) {
$(target).parent().find('.jp-interface').css('display', 'none');
}
}
resize();
// fixes the sizing when closing fullscreen
$(target).bind($.jPlayer.event.resize, function() {
var f = $(this).parent().parent().hasClass('jp-video-full');
if (f) {
$(target).parent().find('.jp-interface').css('display', 'block');
} else {
resize();
}
});
$(this).bind($.jPlayer.event.play, function() {
resize();
clicked = true;
$(this).parent().find('.jp-interface').stop().animate({ opacity: 1 }, 200);
});
}
var nextVideo;
function launchNext(event) { // Override the default jPlayer repeat event handler
//console.log("launching next video: "+nextVideo);
if(event.jPlayer.options.loop) {
$(this).unbind(".jPlayerRepeat").unbind(".jPlayerNext");
$(this).bind($.jPlayer.event.ended + ".jPlayer.jPlayerRepeat", function() {
$(this).jPlayer("play");
});
} else {
$(this).unbind(".jPlayerRepeat").unbind(".jPlayerNext");
$(this).bind($.jPlayer.event.ended + ".jPlayer.jPlayerNext", function() {
$("#"+nextVideo).jPlayer("play", 0);
});
}
}
function edgeReady() {
$("#videos > object").each( function(index) {
var i = $(this).attr('id');
var flashObj = document.getElementById(i);
//flashObj.id(i);
getFlashMovie(i).id(i);
//console.log(i);
});
//console.log("ready");
if ($('#callback').text() == 'Waiting for Callback Input') {
$('#callback').text('Flash Callback is Ready!');
}
}
function edgeLaunch(id, path, type) {
if (getFlashMovie(id) != undefined) getFlashMovie(id).load(path, type);
}
function edgeStatus(s, id){
//console.log("Current status is: "+s+ " for " +id);
// s can be 'playing', 'paused' and 'stopped'
switch(s) {
case "playing":
$("#videos > object").each( function(index) {
var i = $(this).attr('id');
if (i == id || id == undefined) {
//console.log("Keep this playing");
$('#callback').text('Currently playing video: '+id);
$(this).addClass("playing");
} else {
$(this).removeClass("playing");
/*var flashObj = document.getElementById(i);
flashObj.pause();*/
getFlashMovie(i).pause();
}
});
edgeReady();
break;
case "stopped":
var n = $("#videos > .playing").next().attr('id');
$('#callback').text('Attempting to play next video id: '+n);
if (n == undefined) n = $("#videos > .playing").parent().find(':first-child').attr('id');
//console.log('attempt to play next video '+n);
getFlashMovie(n).go();
break;
case "paused":
$('#callback').text('Paused video: '+id);
break;
}
}
// gets the flash movie object
function getFlashMovie(movieName) {
var isIE = navigator.appName.indexOf("Microsoft") != -1;
return (isIE) ? window[movieName] : document[movieName];
}