pandora/static/js/embed/pandora.js

300 lines
15 KiB
JavaScript
Raw Normal View History

2012-02-15 06:26:41 +00:00
// vim: et:ts=4:sw=4:sts=4:ft=javascript
'use strict';
2011-10-22 11:24:26 +00:00
Ox.load('UI', {
debug: false,
hideScreen: false,
loadImages: true,
showScreen: true,
theme: 'oxdark'
2011-10-22 11:24:26 +00:00
}, function() {
2013-02-12 07:40:30 +00:00
var videoKeys = ['duration', 'layers', 'parts', 'posterFrame', 'rightslevel', 'size', 'title', 'videoRatio'];
2011-10-22 11:24:26 +00:00
window.pandora = new Ox.App({url: '/api/'}).bindEvent({
load: function(data) {
Ox.extend(pandora, {
site: data.site,
user: data.user.level == 'guest' ? Ox.clone(data.site.user) : data.user,
2012-06-26 15:59:03 +00:00
$ui: {},
ui: {
player: function(options) {
var that = Ox.Element();
pandora.user.ui.item = options.item;
pandora.api.get({id: options.item, keys: videoKeys}, function(result) {
var data = getVideoOptions(result.data);
2013-02-12 07:28:26 +00:00
that.append(pandora.$player = Ox.VideoPlayer(Ox.extend({
2012-06-26 15:59:03 +00:00
censored: data.censored,
censoredIcon: pandora.site.cantPlay.icon,
censoredTooltip: pandora.site.cantPlay.text,
2013-02-12 11:48:49 +00:00
controlsBottom: ['play', 'volume', 'scale'].concat(
Ox.Fullscreen.available ? ['fullscreen'] : []
).concat(
2013-02-12 11:48:49 +00:00
['timeline', 'position', 'settings']
),
2013-02-12 11:54:14 +00:00
controlsTooltips: {
close: 'Close',
open: 'Watch on ' + pandora.site.site.name
},
2013-02-12 11:48:49 +00:00
controlsTop: (options.showCloseButton ? ['close'] : []).concat(
2013-02-15 06:02:08 +00:00
['title', 'open']
2013-02-11 12:43:42 +00:00
),
2012-06-26 15:59:03 +00:00
duration: data.duration,
enableFind: false,
2012-12-20 18:29:07 +00:00
enableFullscreen: Ox.Fullscreen.available,
2012-06-26 15:59:03 +00:00
enableKeyboard: true,
enableMouse: true,
enablePosition: true,
2013-02-12 08:27:42 +00:00
enableSubtitles: true,
2012-06-26 15:59:03 +00:00
enableTimeline: true,
enableVolume: true,
externalControls: false,
height: window.innerHeight,
2013-02-15 05:22:33 +00:00
invertHighlight: options.invertHighlight,
2012-06-26 15:59:03 +00:00
paused: options.paused,
2013-02-15 05:22:33 +00:00
playInToOut: options.playInToOut,
position: options.position || 0,
poster: '/' + options.item + '/' + '96p' + (
options.position !== void 0 ? options.position
: options['in'] !== void 0 ? options['in']
: data.posterFrame
) +'.jpg',
2012-06-26 15:59:03 +00:00
resolution: pandora.user.ui.videoResolution,
showMarkers: false,
showMilliseconds: 0,
subtitles: data.subtitles,
2013-02-15 05:22:33 +00:00
timeline: options.playInToOut ? function(size, i) {
return '/' + options.item
+ '/timelineantialias'
+ size + 'p' + i + '.jpg'
} : '/' + options.item + '/' + 'timeline16p.png',
2012-06-26 15:59:03 +00:00
title: result.data.title,
video: data.video,
width: window.innerWidth
2013-02-12 07:28:26 +00:00
}, options['in'] ? {
2013-02-12 07:32:42 +00:00
'in': options['in'],
2013-02-12 07:28:26 +00:00
} : {}, options.out ? {
out: options.out
} : {}))
2013-02-12 08:23:50 +00:00
.bindEvent(Ox.extend({
2013-02-11 12:43:42 +00:00
open: function() {
pandora.$player.options({paused: true});
2013-02-12 08:16:09 +00:00
var url = document.location.protocol + '//'
+ document.location.hostname + '/'
+ options.item + '/'
2013-02-11 13:04:04 +00:00
+ Ox.formatDuration(pandora.$player.options('position'));
window.open(url, '_blank');
2013-02-11 12:43:42 +00:00
},
2012-06-26 15:59:03 +00:00
resolution: function(data) {
pandora.api.setUI({'videoResolution': data.resolution});
},
2012-12-20 18:29:07 +00:00
fullscreen: function(data) {
Ox.Fullscreen.toggle();
}
2013-02-15 05:22:33 +00:00
}, ((options['in'] || options.out) && !options.playInToOut) ? {
2013-02-12 08:23:50 +00:00
playing: checkRange,
position: checkRange
} : {}))
.bindEvent(function(data, event) {
2013-02-12 12:05:05 +00:00
if (window.parent) {
2013-02-12 12:12:15 +00:00
window.parent.postMessage(JSON.stringify({
event: event,
id: options.id
}), '*');
2013-02-12 12:05:05 +00:00
}
2013-02-12 11:45:59 +00:00
})
2012-06-26 15:59:03 +00:00
);
Ox.UI.hideLoadingScreen();
});
return that;
},
timeline: function(options) {
var that = Ox.Element();
pandora.user.ui.item = options.item;
pandora.api.get({id: options.item, keys: videoKeys}, function(result) {
Ox.UI.hideLoadingScreen();
var data = getVideoOptions(result.data),
ui = pandora.user.ui;
that.append(pandora.player = Ox.VideoTimelinePlayer({
censored: data.censored,
censoredIcon: pandora.site.cantPlay.icon,
censoredTooltip: pandora.site.cantPlay.text,
cuts: data.cuts || [],
duration: data.duration,
followPlayer: ui.followPlayer,
getFrameURL: function(position) {
return '/' + ui.item + '/' + ui.videoResolution + 'p' + position + '.jpg';
},
getLargeTimelineURL: function(type, i) {
return '/' + ui.item + '/timeline' + type + '64p' + i + '.jpg';
},
height: that.height(),
muted: ui.videoMuted,
'in': options['in'],
out: options.out,
paused: options.paused,
position: options['in'],
resolution: Ox.min(pandora.site.video.resolutions),
2012-06-26 15:59:03 +00:00
smallTimelineURL: '/' + ui.item + '/timeline16p.jpg',
subtitles: data.subtitles,
timeline: ui.videoTimeline,
timelines: pandora.site.timelines,
video: data.video,
videoRatio: data.videoRatio,
volume: ui.videoVolume,
width: that.width()
})
.bindEvent({
playing: checkRange,
position: checkRange,
resolution: function(data) {
pandora.api.setUI({'videoResolution': data.resolution});
},
})
);
});
return that;
}
2012-02-15 06:26:41 +00:00
}
2011-10-22 11:24:26 +00:00
});
2013-02-12 08:23:50 +00:00
function checkRange(data) {
if (
data.position < options['in'] - 0.04
|| data.position > options.out
) {
if (!pandora.$player.options('paused')) {
pandora.$player.togglePaused();
2013-02-13 07:32:14 +00:00
if (data.position > options.out) {
data.position = options['in'] - 0.05;
}
2013-02-12 08:23:50 +00:00
}
pandora.$player.options({
position: data.position < options['in'] - 0.04
? options['in'] : options.out
});
2013-02-12 08:23:50 +00:00
}
}
2011-10-22 11:24:26 +00:00
Ox.extend(pandora.user, {
videoFormat: Ox.getVideoFormat(pandora.site.video.formats)
2011-10-22 11:24:26 +00:00
});
2012-02-15 06:26:41 +00:00
var options = parseQuery();
2012-06-25 14:49:39 +00:00
if (['video', 'player'].indexOf(options.view) > -1) {
2012-06-26 15:59:03 +00:00
pandora.$ui.player = pandora.ui.player(options)
.css({top: 0, bottom: 0, left: 0, right: 0, position: 'absolute'})
.appendTo(document.body);
} else if (options.view == 'timeline') {
pandora.$ui.timeline = pandora.ui.timeline(options)
.css({top: 0, bottom: 0, left: 0, right: 0, position: 'absolute'})
2012-02-15 06:26:41 +00:00
.appendTo(document.body);
}
2011-10-22 11:24:26 +00:00
}
});
2013-02-12 07:24:02 +00:00
function getVideoOptions(data) {
var canPlayClips = data.editable || pandora.site.capabilities.canPlayClips[pandora.user.level] >= data.rightslevel,
canPlayVideo = data.editable || pandora.site.capabilities.canPlayVideo[pandora.user.level] >= data.rightslevel,
2013-02-12 08:01:58 +00:00
options = {},
subtitlesLayer = pandora.site.layers.filter(function(layer) {
return layer.isSubtitles;
})[0];
options.censored = canPlayVideo ? []
: canPlayClips ? (
options.subtitles.length
2012-05-24 08:22:56 +00:00
? options.subtitles.map(function(subtitle, i) {
return {
'in': i == 0 ? 0 : options.subtitles[i - 1].out,
out: subtitle['in']
};
}).concat(
[{'in': Ox.last(options.subtitles).out, out: data.duration}]
2012-05-24 08:22:56 +00:00
).filter(function(censored) {
// don't include gaps shorter than one second
return censored.out - censored['in'] >= 1;
})
: Ox.range(0, data.duration - 5, 60).map(function(position) {
return {
'in': position + 5,
out: Math.min(position + 60, data.duration)
};
})
)
: [{'in': 0, out: data.duration}];
2013-02-12 07:40:30 +00:00
options.duration = data.duration;
options.layers = [];
pandora.site.layers.forEach(function(layer, i) {
options.layers[i] = Ox.extend({}, layer, {
items: data.layers[layer.id].map(function(annotation) {
annotation.duration = Math.abs(annotation.out - annotation['in']);
annotation.editable = annotation.editable
|| annotation.user == pandora.user.username
|| pandora.site.capabilities['canEditAnnotations'][pandora.user.level];
return annotation;
})
});
});
2013-02-12 07:40:30 +00:00
options.posterFrame = data.posterFrame;
2013-02-12 08:01:58 +00:00
options.subtitles = subtitlesLayer ? data.layers[subtitlesLayer.id].map(function(subtitle) {
return {
id: subtitle.id,
'in': subtitle['in'],
out: subtitle.out,
text: subtitle.value.replace(/\n/g, ' ').replace(/<br\/?>/g, '\n')
};
}) : [];
2013-02-12 07:40:30 +00:00
options.video = {};
pandora.site.video.resolutions.forEach(function(resolution) {
options.video[resolution] = Ox.range(data.parts).map(function(i) {
return getVideoURL(data.item || pandora.user.ui.item, resolution, i + 1);
2013-02-12 07:40:30 +00:00
});
});
2012-06-26 15:59:03 +00:00
options.videoRatio = data.videoRatio;
return options;
}
2012-02-17 09:19:15 +00:00
function getVideoURL(id, resolution, part) {
2013-02-12 07:40:30 +00:00
var prefix = pandora.site.site.videoprefix
.replace('{id}', id)
.replace('{part}', part)
.replace('{resolution}', resolution)
.replace('{uid}', Ox.uid());
return prefix + '/' + id + '/' + resolution + 'p' + part + '.' + pandora.user.videoFormat;
}
2012-02-17 09:19:15 +00:00
function parseQuery() {
var vars = window.location.search.length
2012-05-24 09:56:52 +00:00
? window.location.search.slice(1).split('&')
2012-02-17 09:19:15 +00:00
: [],
query = {
2012-05-24 09:56:52 +00:00
item: window.location.pathname.slice(1).split('/')[0]
2012-02-17 09:19:15 +00:00
},
defaults = {
2013-02-15 05:22:33 +00:00
invertHighlight: true,
paused: true,
playInToOut: true,
2012-02-17 09:19:15 +00:00
view: 'video',
},
options;
2012-02-17 09:19:15 +00:00
vars.forEach(function(v) {
2013-02-12 08:17:05 +00:00
var kv = v.split('='), k = kv[0], v = kv[1];
2013-08-14 18:54:06 +00:00
query[k] = Ox.decodeURIComponent(v);
2013-02-12 08:54:53 +00:00
if (query[k] == 'true') {
query[k] = true;
} else if (query[k] == 'false') {
query[k] = false;
} else if (query[k].match(/^[\d\.]+$/)) {
2013-02-12 08:14:28 +00:00
query[k] = parseFloat(query[k]);
}
if (['in', 'out'].indexOf(k) > -1 && v.indexOf(':') > -1) {
query[k] = Ox.parseDuration(query[k]);
}
2012-02-17 09:19:15 +00:00
});
options = Ox.extend({}, defaults, query);
if (!options.position) {
options.position = options['in'] || 0;
}
if (!options['in'] && !options.out) {
options.playInToOut = false;
}
return options;
2012-02-17 09:19:15 +00:00
}
2013-02-12 07:24:02 +00:00
2011-10-22 11:24:26 +00:00
});