c3d2-web/content/static/script/play-resources.js

237 lines
6.3 KiB
JavaScript

function arrayMap(array, iter) {
if (array.map)
return array.map(iter);
else {
var result = [], i;
for(i = 0; i < array.length; i++)
result.push(iter(array[i]));
return result;
}
}
function arraySome(array, iter) {
if (array.some)
return array.some(iter);
else {
var i;
for(i = 0; i < array.length; i++)
if (iter(array[i]))
return true;
return false;
}
}
function arrayForEach(array, iter) {
if (array.forEach)
array.forEach(iter);
else {
var i;
for(i = 0; i < array.length; i++)
iter(array[i]);
}
}
function parseTime(time) {
var parts = time.split(":"), part;
var r = 0;
while((part = parts.shift())) {
r = r * 60 + parseInt(part, 10);
}
return r;
}
function addPlayer(container, res, chapters) {
var types = arrayMap(res, function(res) {
return res.type;
});
/* Can we have <audio> or <video> please?
*
* Video must be prefered over audio because <audio> can play
* videos too.
*/
var html5player;
if (arraySome(types, canPlayVideo)) {
html5player = $('<video controls="controls" autoplay="autoplay"></video>');
} else if (arraySome(types, canPlayAudio)) {
html5player = $('<audio controls="controls" autoplay="autoplay"></audio>');
}
/* ...install sources */
if (html5player) {
arrayForEach(res, function(r) {
var src = $('<source/>');
src.attr('src', r.href);
src.attr('type', r.type);
html5player.append(src);
});
}
/* Anything else than HTML5? */
var fallback;
arrayForEach(res, function(r) {
if (fallback) /* Got one already */
return;
if (r.type === 'audio/mpeg') {
var movie = '/script/dewplayer-mini.swf?showtime=1&amp;autostart=1&amp;mp3=' + r.href;
fallback = $('<object type="application/x-shockwave-flash" width="150" height="20">' +
'<param name="wmode" value="transparent"/>' +
'<param name="allowScriptAccess" value="always"/>' +
'<param name="movie"/>' +
'</object>');
fallback.attr('data', movie);
fallback.find('param[name="movie"]').attr('value', movie);
} else if (r.type === 'video/x-flv') {
/* Create unique id for multiple containers on one page */
var containerId = 'flowplayer' + Math.round(Math.random() * 9999);
fallback = $('<div>Moment bitte</div>');
fallback.attr('id', containerId);
/* Defer loading because fallback needs to be appended first, and we want that .js on demand anyway */
window.setTimeout(function() {
loadFlowplayer(function() {
fallback.text('');
flowplayer(containerId, { src: '/script/flowplayer-3.2.5.swf' },
{ clip: r.href });
});
}, 1);
}
});
/* Add stuff to page */
if (html5player) {
if (fallback)
html5player.append(fallback);
container.append(html5player);
if (chapters[0]) {
var dl = $('<dl class="chapters"></dl>');
var prevStart;
chapters.find('chapter').each(function() {
var title = this.getAttribute('title');
var start = this.getAttribute('start');
var href = this.getAttribute('href');
if (start && start != prevStart) {
var dt = $('<dt><a href="#"></a></dt>');
var dt_a = dt.find('a');
dt_a.text(start);
dt_a.click(function(ev) {
ev.preventDefault();
html5player[0].currentTime = parseTime(start);
});
dl.append(dt);
}
prevStart = start;
var dd = $('<dd></dd>');
if (href) {
var dd_a = $('<a></a>');
dd_a.attr('href', href);
dd_a.text(title);
dd.append(dd_a);
} else {
dd.text(title);
}
dl.append(dd);
});
container.append(dl);
}
} else if (fallback) {
container.append(fallback);
} else {
container.append('<p>Upps, das musst du wohl erstmal herunterladen</p>');
}
}
$(document).ready(function() {
try {
/* Iterate over all resources in HTML output */
$('.resource').each(function() {
var els = [this];
var resource = { href: $(this).find('a').attr('href'),
type: $(this).find('a').attr('type') };
var poster = $(this).data('poster');
var preview = $(this).data('preview');
/* Get all associated alternatives */
var alternativeEls = $(this).nextUntil('.resource');
els = els.concat(alternativeEls.toArray());
var alternatives = alternativeEls.find('a').
map(function() {
return { href: $(this).attr('href'),
type: $(this).attr('type') };
}).
toArray();
var res = [resource].concat(alternatives);
if (poster)
res.poster = poster;
if (preview)
res.preview = preview;
/* Check playability */
if (arraySome(arrayMap(res, function(r) {
return r.type;
}), canPlay)) {
var liEl = $('<li></li>');
$(this).before(liEl);
console.log('h4', $(this).parents('h4'));
var mediaElName = $(this).find('.video-resource').length > 0 ? 'video' : 'audio';
var mediaEl = $("<" + mediaElName + " controls></" + mediaElName + ">");
res.forEach(function(r) {
var sourceEl = $("<source>");
sourceEl.attr('src', r.href);
sourceEl.attr('type', r.type);
mediaEl.append(sourceEl);
});
liEl.append(mediaEl);
var player = mediaEl.podlovewebplayer({
features: ["current", "progress", "duration", "tracks", "fullscreen", "volume"],
show: {
}
// , res, $(this).find('chapters'));
});
console.log("player", player);
// TODO: FIXME for .video-resource
console.log("els", els);
$(els).remove();
}
});
} catch (x) {
if (console && console.error)
console.error(x);
}
});
function canPlay(type) {
return canPlayAudio(type) ||
canPlayVideo(type) ||
canFallback(type);
}
/**
* From http://diveintohtml5.org/everything.html
*/
function canPlayAudio(type) {
var a = document.createElement('audio');
return !!(a.canPlayType &&
a.canPlayType(type).replace(/no/, ''));
}
/**
* Partially from http://diveintohtml5.org/everything.html
*
* But we don't want audio/* as <video>
*/
function canPlayVideo(type) {
var v = document.createElement('video');
return !!(v.canPlayType &&
v.canPlayType(type).replace(/no/, '') &&
!(/^audio\//.test(type)));
}
function canFallback(type) {
return type === 'audio/mpeg' ||
type === 'video/x-flv';
}