forked from 0x2620/pandora
use new Ox.VideoElement, add inital player to edits and view as video results view
This commit is contained in:
parent
15be34955e
commit
9cd9611306
16 changed files with 218 additions and 80 deletions
|
@ -78,7 +78,7 @@ class MetaClip:
|
|||
for a in annotations]
|
||||
for key in keys:
|
||||
if key not in self.clip_keys and key not in j:
|
||||
value = self.item.get(key)
|
||||
value = self.item.get(key) or self.item.json.get(key)
|
||||
if not value and hasattr(self.item.sort, key):
|
||||
value = getattr(self.item.sort, key)
|
||||
j[key] = value
|
||||
|
|
|
@ -678,7 +678,7 @@
|
|||
//{"id": "maps", "title": "with Maps"},
|
||||
//{"id": "calendars", "title": "with Calendars"},
|
||||
{"id": "clip", "title": "as Clips"},
|
||||
//{"id": "video", "title": "as Video"},
|
||||
{"id": "video", "title": "as Video"},
|
||||
{"id": "map", "title": "on Map"},
|
||||
{"id": "calendar", "title": "on Calendar"}
|
||||
],
|
||||
|
|
|
@ -691,6 +691,7 @@
|
|||
{"id": "timelines", "title": "with Timelines"},
|
||||
{"id": "clips", "title": "with Clips"},
|
||||
{"id": "clip", "title": "as Clips"},
|
||||
{"id": "video", "title": "as Videos"},
|
||||
{"id": "map", "title": "on Map"},
|
||||
{"id": "calendar", "title": "on Calendar"}
|
||||
],
|
||||
|
|
|
@ -575,6 +575,7 @@
|
|||
{"id": "timelines", "title": "with Timelines"},
|
||||
{"id": "clips", "title": "with Clips"},
|
||||
{"id": "clip", "title": "as Clips"},
|
||||
{"id": "video", "title": "as Video"},
|
||||
{"id": "map", "title": "on Map"},
|
||||
{"id": "calendar", "title": "on Calendar"}
|
||||
],
|
||||
|
|
|
@ -494,6 +494,7 @@
|
|||
{"id": "timelines", "title": "with Timelines"},
|
||||
{"id": "clips", "title": "with Clips"},
|
||||
{"id": "clip", "title": "as Clips"},
|
||||
{"id": "video", "title": "as Video"},
|
||||
{"id": "map", "title": "on Map"},
|
||||
{"id": "calendar", "title": "on Calendar"}
|
||||
],
|
||||
|
|
|
@ -297,10 +297,14 @@ class Clip(models.Model):
|
|||
data['annotation'] = self.annotation.public_id
|
||||
data['in'] = self.annotation.start
|
||||
data['out'] = self.annotation.end
|
||||
data['parts'] = self.annotation.item.json['parts']
|
||||
data['durations'] = self.annotation.item.json['durations']
|
||||
else:
|
||||
data['item'] = self.item.itemId
|
||||
data['in'] = self.start
|
||||
data['out'] = self.end
|
||||
data['parts'] = self.item.json['parts']
|
||||
data['durations'] = self.item.json['durations']
|
||||
data['duration'] = data['out'] - data['in']
|
||||
return data
|
||||
|
||||
|
|
|
@ -31,6 +31,8 @@ pandora.ui.browser = function() {
|
|||
pandora.$ui.map.resizeMap();
|
||||
} else if (pandora.user.ui.listView == 'calendar') {
|
||||
pandora.$ui.calendar.resizeCalendar();
|
||||
} else if (pandora.user.ui.listView == 'video') {
|
||||
pandora.$ui.list.size();
|
||||
}
|
||||
},
|
||||
resizeend: function(data) {
|
||||
|
@ -59,6 +61,8 @@ pandora.ui.browser = function() {
|
|||
pandora.$ui.map.resizeMap();
|
||||
} else if (pandora.user.ui.listView == 'calendar') {
|
||||
pandora.$ui.calendar.resizeCalendar();
|
||||
} else if (pandora.user.ui.listView == 'video') {
|
||||
pandora.$ui.list.size();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -175,25 +175,23 @@ pandora.ui.clipList = function(videoRatio) {
|
|||
}
|
||||
pandora.api.get({id: item, keys: ['durations', 'rightslevel']}, function(result) {
|
||||
var points = [that.value(id, 'in'), that.value(id, 'out')],
|
||||
partsAndPoints = pandora.getVideoPartsAndPoints(
|
||||
result.data.durations, points
|
||||
),
|
||||
$player = Ox.VideoPlayer({
|
||||
censored: pandora.site.capabilities.canPlayClips[pandora.user.level] < result.data.rightslevel
|
||||
? [{'in': partsAndPoints.points[0], out: partsAndPoints.points[1]}]
|
||||
? [{'in': 0, out: points[1] - points[0]}]
|
||||
: [],
|
||||
censoredIcon: pandora.site.cantPlay.icon,
|
||||
censoredTooltip: pandora.site.cantPlay.text,
|
||||
height: height,
|
||||
'in': partsAndPoints.points[0],
|
||||
out: partsAndPoints.points[1],
|
||||
paused: true,
|
||||
playInToOut: true,
|
||||
poster: '/' + item + '/' + height + 'p' + points[0] + '.jpg',
|
||||
rewind: true,
|
||||
video: partsAndPoints.parts.map(function(i) {
|
||||
return pandora.getVideoURL(item, Ox.min(pandora.site.video.resolutions), i + 1);
|
||||
}),
|
||||
video: pandora.getClipVideos({
|
||||
item: item,
|
||||
parts: result.data.durations.length,
|
||||
durations: result.data.durations,
|
||||
'in': points[0],
|
||||
out: points[1]
|
||||
}, Ox.min(pandora.site.video.resolutions)),
|
||||
width: width
|
||||
})
|
||||
.addClass('OxTarget')
|
||||
|
|
|
@ -1,61 +0,0 @@
|
|||
// vim: et:ts=4:sw=4:sts=4:ft=javascript
|
||||
'use strict';
|
||||
pandora.ui.clipPlayer = function() {
|
||||
// FIXME: is clipPlayer the best name for this?
|
||||
var that = Ox.VideoPlayer({
|
||||
controlsBottom: ['play', 'previous', 'next', 'volume'],
|
||||
controlsTop: ['fullscreen', 'scale'],
|
||||
enableMouse: true,
|
||||
height: 384,
|
||||
paused: true,
|
||||
position: 0,
|
||||
video: function(range, callback) {
|
||||
var callback = arguments[arguments.length - 1],
|
||||
range = arguments.length == 2 ? arguments[0] : null,
|
||||
itemsQuery = pandora.user.ui.find,
|
||||
query = {conditions:[]};
|
||||
//fixme: can this be in pandora.Query? dont just check for subtitles
|
||||
itemsQuery.conditions.forEach(function(q) {
|
||||
if (q.key == 'subtitles') {
|
||||
query.conditions.push({key: 'subtitles', value: q.value, operator: q.operator});
|
||||
}
|
||||
});
|
||||
pandora.api.findClips(Ox.extend({
|
||||
query: query,
|
||||
itemsQuery: itemsQuery
|
||||
}, range ? {
|
||||
keys: ['id', 'in', 'out', 'subtitles'],
|
||||
range: range,
|
||||
sort: pandora.user.ui.listSort
|
||||
} : {}), function(result) {
|
||||
//Ox.Log('', 'API findClips range', range, 'result', result.data);
|
||||
if (!range) {
|
||||
callback(result.data.items);
|
||||
} else {
|
||||
var counter = 0,
|
||||
length = range[1] - range[0],
|
||||
data = [];
|
||||
result.data.items.forEach(function(item, i) {
|
||||
var id = item.id.split('/')[0];
|
||||
pandora.api.get({id: id, keys: ['durations']}, function(result) {
|
||||
//Ox.Log('', 'API get item', id, 'result', result.data);
|
||||
var points = [item['in'], item.out],
|
||||
partsAndPoints = pandora.getVideoPartsAndPoints(result.data.durations, points);
|
||||
data[i] = {
|
||||
parts: partsAndPoints.parts.map(function(i) {
|
||||
return pandora.getVideoURL(item, Ox.min(pandora.site.video.resolutions), i + 1);
|
||||
}),
|
||||
points: partsAndPoints.points
|
||||
};
|
||||
if (++counter == length) {
|
||||
callback(data);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
width: 512
|
||||
});
|
||||
return that;
|
||||
};
|
|
@ -22,6 +22,25 @@ pandora.ui.editPanel = function() {
|
|||
|
||||
$editMenu,
|
||||
|
||||
$viewSelect = Ox.Select({
|
||||
items: [
|
||||
{'id': 'list', 'title': Ox._('View as List')},
|
||||
{'id': 'player', 'title': Ox._('View as Player')},
|
||||
],
|
||||
value: 'list',
|
||||
width: 128
|
||||
})
|
||||
.css({
|
||||
float: 'left',
|
||||
margin: '4px 0 0 4px'
|
||||
})
|
||||
.bindEvent({
|
||||
change: function(data) {
|
||||
$panel.replaceElement(0, pandora.$ui.edit = pandora.ui[
|
||||
data.value == 'player' ? 'editPlayer' : 'editList'
|
||||
](edit));
|
||||
},
|
||||
}).appendTo($toolbar),
|
||||
|
||||
$statusbar = Ox.Bar({size: 16}),
|
||||
|
||||
|
@ -145,7 +164,7 @@ pandora.ui.editList = function(edit) {
|
|||
edit: pandora.user.ui.edit
|
||||
}, function(result) {
|
||||
Ox.Request.clearCache();
|
||||
pandora.$ui.rightPanel.reload()
|
||||
pandora.$ui.rightPanel.reload();
|
||||
});
|
||||
}
|
||||
},
|
||||
|
@ -198,3 +217,35 @@ pandora.ui.editList = function(edit) {
|
|||
return that;
|
||||
|
||||
};
|
||||
pandora.ui.editPlayer = function(edit) {
|
||||
var that = Ox.Element()
|
||||
.css({
|
||||
'overflow-y': 'auto'
|
||||
});
|
||||
|
||||
|
||||
self.$player = Ox.VideoPlayer({
|
||||
controlsBottom: ['play', 'previous', 'next', 'volume', 'position'],
|
||||
controlsTop: ['fullscreen', 'scale'],
|
||||
enableMouse: true,
|
||||
height: getHeight(),
|
||||
paused: true,
|
||||
position: 0,
|
||||
video: Ox.flatten(edit.clips.map(function(clip) {
|
||||
return pandora.getClipVideos(clip);
|
||||
})),
|
||||
width: getWidth()
|
||||
}).appendTo(that);
|
||||
|
||||
function getHeight() {
|
||||
// 24 menu + 24 toolbar + 16 statusbar + 32 title + 32 margins
|
||||
// + 1px to ge trid of scrollbar
|
||||
return window.innerHeight - 128 -1;
|
||||
}
|
||||
|
||||
function getWidth() {
|
||||
return window.innerWidth
|
||||
- pandora.user.ui.showSidebar * pandora.user.ui.sidebarSize - 1;
|
||||
}
|
||||
return that;
|
||||
};
|
||||
|
|
|
@ -27,7 +27,7 @@ pandora.ui.embedPlayer = function() {
|
|||
$title, $player, $controls, $timeline, $annotations;
|
||||
|
||||
pandora.api.get({id: ui.item, keys: [
|
||||
'duration', 'layers', 'parts', 'posterFrame',
|
||||
'duration', 'durations', 'layers', 'parts', 'posterFrame',
|
||||
'rightslevel', 'size', 'title', 'videoRatio'
|
||||
]}, function(result) {
|
||||
|
||||
|
|
|
@ -13,11 +13,11 @@ pandora.ui.item = function() {
|
|||
pandora.api.get({
|
||||
id: pandora.user.ui.item,
|
||||
keys: isVideoView ? [
|
||||
'cuts', 'director', 'duration', 'editable', 'layers',
|
||||
'cuts', 'director', 'duration', 'durations', 'editable', 'layers',
|
||||
'modified', 'parts', 'posterFrame', 'rendered', 'rightslevel',
|
||||
'size', 'title', 'videoRatio', 'year'
|
||||
] : pandora.user.ui.itemView == 'documents' ? [
|
||||
'director', 'documents', 'duration', 'editable',
|
||||
'director', 'documents', 'duration', 'durations', 'editable',
|
||||
'rightslevel', 'size', 'title', 'videoRatio', 'year'
|
||||
] : []
|
||||
}, pandora.user.ui.itemView == 'info' && pandora.site.capabilities.canEditMetadata[pandora.user.level] ? 0 : -1, function(result) {
|
||||
|
|
|
@ -377,7 +377,7 @@ pandora.ui.list = function() {
|
|||
} else if (view == 'clip') {
|
||||
that = pandora.$ui.clipList = pandora.ui.clipList();
|
||||
} else if (view == 'video') {
|
||||
that = pandora.ui.clipPlayer();
|
||||
that = pandora.ui.videoView();
|
||||
} else if (['map', 'calendar'].indexOf(view) > -1) {
|
||||
that = pandora.ui.navigationView(view);
|
||||
}
|
||||
|
|
|
@ -38,6 +38,8 @@ pandora.ui.rightPanel = function() {
|
|||
pandora.$ui.map.resizeMap();
|
||||
} else if (pandora.user.ui.listView == 'calendar') {
|
||||
pandora.$ui.calendar.resizeCalendar();
|
||||
} else if (pandora.user.ui.listView == 'video') {
|
||||
pandora.$ui.list.resize();
|
||||
}
|
||||
} else {
|
||||
pandora.$ui.browser.scrollToSelection();
|
||||
|
@ -53,6 +55,8 @@ pandora.ui.rightPanel = function() {
|
|||
pandora.$ui.map.resizeMap();
|
||||
} else if (pandora.user.ui.listView == 'calendar') {
|
||||
pandora.$ui.calendar.resizeCalendar();
|
||||
} else if (pandora.user.ui.listView == 'video') {
|
||||
pandora.$ui.list.size();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -584,6 +584,45 @@ pandora.getClipsQuery = function() {
|
|||
return clipsQuery;
|
||||
};
|
||||
|
||||
pandora.getClipVideos = function(clip, resolution) {
|
||||
var currentTime = 0,
|
||||
start = clip['in'] || 0,
|
||||
end = clip.out;
|
||||
resolution = resolution || pandora.user.ui.videoResolution;
|
||||
|
||||
return Ox.flatten(Ox.range(clip.parts).map(function(i) {
|
||||
var item = {
|
||||
src: pandora.getVideoURL(clip.item, resolution, i + 1)
|
||||
};
|
||||
if(currentTime + clip.durations[i] < start || currentTime > end) {
|
||||
item = null;
|
||||
} else {
|
||||
if(currentTime <= start && currentTime + clip.durations[i] > start) {
|
||||
item['in'] = start - currentTime;
|
||||
}
|
||||
if (currentTime + clip.durations[i] >= end) {
|
||||
item.out = end - currentTime;
|
||||
}
|
||||
if (item['in'] && item.out) {
|
||||
item.duration = item.out - item['in']
|
||||
} else if (item.out) {
|
||||
item.duration = item.out;
|
||||
} else if (!Ox.isUndefined(item['in'])) {
|
||||
item.duration = clip.durations[i] - item['in'];
|
||||
item.out = clip.durations[i];
|
||||
} else {
|
||||
item.duration = clip.durations[i];
|
||||
item['in'] = 0;
|
||||
item.out = item.duration;
|
||||
}
|
||||
}
|
||||
currentTime += clip.durations[i];
|
||||
return item;
|
||||
}).filter(function(c) {
|
||||
return !!c;
|
||||
}));
|
||||
};
|
||||
|
||||
(function() {
|
||||
var itemTitles = {};
|
||||
pandora.getDocumentTitle = function(itemTitle) {
|
||||
|
@ -1065,7 +1104,7 @@ pandora.getStatusText = function(data) {
|
|||
var ui = pandora.user.ui,
|
||||
canSeeMedia = pandora.site.capabilities.canSeeMedia[pandora.user.level],
|
||||
canSeeSize = pandora.site.capabilities.canSeeSize[pandora.user.level],
|
||||
itemName = ui.listView == 'clip'
|
||||
itemName = ['clip', 'video'].indexOf(ui.listView) > -1
|
||||
? (data.items == 1 ? Ox._('Clip') : Ox._('Clips'))
|
||||
: (pandora.site.itemName[data.items == 1 ? 'singular' : 'plural']),
|
||||
parts = [];
|
||||
|
@ -1139,7 +1178,10 @@ pandora.getVideoOptions = function(data) {
|
|||
options.video = {};
|
||||
pandora.site.video.resolutions.forEach(function(resolution) {
|
||||
options.video[resolution] = Ox.range(data.parts).map(function(i) {
|
||||
return pandora.getVideoURL(data.item || pandora.user.ui.item, resolution, i + 1);
|
||||
return {
|
||||
duration: data.durations[i],
|
||||
src: pandora.getVideoURL(data.item || pandora.user.ui.item, resolution, i + 1)
|
||||
};
|
||||
});
|
||||
});
|
||||
options.annotations = [];
|
||||
|
|
93
static/js/pandora/videoView.js
Normal file
93
static/js/pandora/videoView.js
Normal file
|
@ -0,0 +1,93 @@
|
|||
// vim: et:ts=4:sw=4:sts=4:ft=javascript
|
||||
'use strict';
|
||||
|
||||
pandora.ui.videoView = function() {
|
||||
var ui = pandora.user.ui,
|
||||
itemsQuery,
|
||||
query,
|
||||
that = Ox.Element().css({
|
||||
width: '100%',
|
||||
hegiht: '100%',
|
||||
}),
|
||||
range = [0, 500],
|
||||
clips = [],
|
||||
player;
|
||||
|
||||
if (!ui.item) {
|
||||
itemsQuery = ui.find;
|
||||
query = {conditions: [], operator: '&'};
|
||||
// if the item query contains a layer condition,
|
||||
// then this condition is added to the clip query
|
||||
itemsQuery.conditions.forEach(function(condition) {
|
||||
if (
|
||||
condition.key == 'annotations'
|
||||
|| Ox.getIndexById(pandora.site.layers, condition.key) > -1
|
||||
) {
|
||||
query.conditions.push(condition);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
itemsQuery = {
|
||||
conditions:[{key: 'id', value: ui.item, operator: '=='}],
|
||||
operator: '&'
|
||||
};
|
||||
query = {
|
||||
conditions: ui.itemFind === '' ? [] : [{
|
||||
key: 'annotations',
|
||||
value: ui.itemFind,
|
||||
operator: '='
|
||||
}],
|
||||
operator: '&'
|
||||
};
|
||||
}
|
||||
loadPlayer();
|
||||
function loadPlayer() {
|
||||
pandora.api.findClips({
|
||||
query: query,
|
||||
itemsQuery: itemsQuery,
|
||||
keys: ['id', 'in', 'out', 'durations', 'parts'],
|
||||
range: range,
|
||||
sort: pandora.user.ui.listSort
|
||||
}, function(result) {
|
||||
pandora.$ui.statusbar.set('total', {
|
||||
items: result.data.items.length
|
||||
});
|
||||
player && player.remove();
|
||||
player = Ox.VideoPlayer({
|
||||
controlsBottom: ['play', 'previous', 'next', 'volume'],
|
||||
controlsTop: ['fullscreen', 'scale'],
|
||||
enableMouse: true,
|
||||
height: getHeight(),
|
||||
paused: true,
|
||||
position: 0,
|
||||
video: Ox.flatten(result.data.items.map(function(clip) {
|
||||
clip.item = clip.id.split('/')[0];
|
||||
var r = pandora.getClipVideos(clip);
|
||||
console.log(clip, r);
|
||||
return r;
|
||||
})),
|
||||
width: getWidth()
|
||||
}).appendTo(that);
|
||||
});
|
||||
}
|
||||
|
||||
function getHeight() {
|
||||
return that.height();
|
||||
}
|
||||
|
||||
function getWidth() {
|
||||
return that.width();
|
||||
}
|
||||
|
||||
that.reloadList = function() {
|
||||
loadPlayer();
|
||||
};
|
||||
that.size = function() {
|
||||
player && player.options({
|
||||
height: getHeight(),
|
||||
width: getWidth(),
|
||||
})
|
||||
}
|
||||
|
||||
return that;
|
||||
};
|
Loading…
Reference in a new issue