forked from 0x2620/pandora
add canPlayClips flag to annotation layers and use those layers to limit playback to clips
This commit is contained in:
parent
83013bbe5e
commit
41b50ccdb8
5 changed files with 63 additions and 23 deletions
|
@ -733,6 +733,8 @@
|
||||||
Optional keys are:
|
Optional keys are:
|
||||||
"autocomplete": Available if the layer is used as a filter
|
"autocomplete": Available if the layer is used as a filter
|
||||||
"canAddAnnotations": Permissions per user level
|
"canAddAnnotations": Permissions per user level
|
||||||
|
"canPlayClips": If true, clips from this layer will play for users
|
||||||
|
with canPlayClips access
|
||||||
"entity": ID of the referenced entity (if type is "entity")
|
"entity": ID of the referenced entity (if type is "entity")
|
||||||
"hasEvents": If true, the calendar will be populated with matches from
|
"hasEvents": If true, the calendar will be populated with matches from
|
||||||
this layer
|
this layer
|
||||||
|
@ -768,6 +770,7 @@
|
||||||
"id": "subtitles",
|
"id": "subtitles",
|
||||||
"title": "Subtitles",
|
"title": "Subtitles",
|
||||||
"canAddAnnotations": {"staff": true, "admin": true},
|
"canAddAnnotations": {"staff": true, "admin": true},
|
||||||
|
"canPlayClips": true,
|
||||||
"hasEvents": true,
|
"hasEvents": true,
|
||||||
"hasPlaces": true,
|
"hasPlaces": true,
|
||||||
"isSubtitles": true,
|
"isSubtitles": true,
|
||||||
|
|
|
@ -752,6 +752,8 @@
|
||||||
Optional keys are:
|
Optional keys are:
|
||||||
"autocomplete": Available if the layer is used as a filter
|
"autocomplete": Available if the layer is used as a filter
|
||||||
"canAddAnnotations": Permissions per user level
|
"canAddAnnotations": Permissions per user level
|
||||||
|
"canPlayClips": If true, clips from this layer will play for users
|
||||||
|
with canPlayClips access
|
||||||
"entity": ID of the referenced entity (if type is "entity")
|
"entity": ID of the referenced entity (if type is "entity")
|
||||||
"hasEvents": If true, the calendar will be populated with matches from
|
"hasEvents": If true, the calendar will be populated with matches from
|
||||||
this layer
|
this layer
|
||||||
|
@ -778,6 +780,7 @@
|
||||||
"id": "notes",
|
"id": "notes",
|
||||||
"title": "Notes",
|
"title": "Notes",
|
||||||
"canAddAnnotations": {"member": true, "researcher": true, "staff": true, "admin": true},
|
"canAddAnnotations": {"member": true, "researcher": true, "staff": true, "admin": true},
|
||||||
|
"canPlayClips": true,
|
||||||
"hasEvents": true,
|
"hasEvents": true,
|
||||||
"hasPlaces": true,
|
"hasPlaces": true,
|
||||||
"item": "Note",
|
"item": "Note",
|
||||||
|
@ -789,6 +792,7 @@
|
||||||
"id": "subtitles",
|
"id": "subtitles",
|
||||||
"title": "Subtitles",
|
"title": "Subtitles",
|
||||||
"canAddAnnotations": {"researcher": true, "staff": true, "admin": true},
|
"canAddAnnotations": {"researcher": true, "staff": true, "admin": true},
|
||||||
|
"canPlayClips": true,
|
||||||
"hasEvents": true,
|
"hasEvents": true,
|
||||||
"hasPlaces": true,
|
"hasPlaces": true,
|
||||||
"isSubtitles": true,
|
"isSubtitles": true,
|
||||||
|
|
|
@ -634,6 +634,8 @@
|
||||||
Optional keys are:
|
Optional keys are:
|
||||||
"autocomplete": Available if the layer is used as a filter
|
"autocomplete": Available if the layer is used as a filter
|
||||||
"canAddAnnotations": Permissions per user level
|
"canAddAnnotations": Permissions per user level
|
||||||
|
"canPlayClips": If true, clips from this layer will play for users
|
||||||
|
with canPlayClips access
|
||||||
"entity": ID of the referenced entity (if type is "entity")
|
"entity": ID of the referenced entity (if type is "entity")
|
||||||
"hasEvents": If true, the calendar will be populated with matches from
|
"hasEvents": If true, the calendar will be populated with matches from
|
||||||
this layer
|
this layer
|
||||||
|
@ -683,6 +685,7 @@
|
||||||
"id": "transcripts",
|
"id": "transcripts",
|
||||||
"title": "Transcripts",
|
"title": "Transcripts",
|
||||||
"canAddAnnotations": {"member": true, "staff": true, "admin": true},
|
"canAddAnnotations": {"member": true, "staff": true, "admin": true},
|
||||||
|
"canPlayClips": true,
|
||||||
"isSubtitles": true,
|
"isSubtitles": true,
|
||||||
"item": "Transcript",
|
"item": "Transcript",
|
||||||
"showInfo": true,
|
"showInfo": true,
|
||||||
|
|
|
@ -573,6 +573,8 @@ examples (config.SITENAME.jsonc) that are part of this pan.do/ra distribution.
|
||||||
Optional keys are:
|
Optional keys are:
|
||||||
"autocomplete": Available if the layer is used as a filter
|
"autocomplete": Available if the layer is used as a filter
|
||||||
"canAddAnnotations": Permissions per user level
|
"canAddAnnotations": Permissions per user level
|
||||||
|
"canPlayClips": If true, clips from this layer will play for users
|
||||||
|
with canPlayClips access
|
||||||
"entity": ID of the referenced entity (if type is "entity")
|
"entity": ID of the referenced entity (if type is "entity")
|
||||||
"hasEvents": If true, the calendar will be populated with matches from
|
"hasEvents": If true, the calendar will be populated with matches from
|
||||||
this layer
|
this layer
|
||||||
|
@ -616,6 +618,7 @@ examples (config.SITENAME.jsonc) that are part of this pan.do/ra distribution.
|
||||||
"id": "subtitles",
|
"id": "subtitles",
|
||||||
"title": "Subtitles",
|
"title": "Subtitles",
|
||||||
"canAddAnnotations": {"staff": true, "admin": true},
|
"canAddAnnotations": {"staff": true, "admin": true},
|
||||||
|
"canPlayClips": true,
|
||||||
"hasEvents": true,
|
"hasEvents": true,
|
||||||
"hasPlaces": true,
|
"hasPlaces": true,
|
||||||
"isSubtitles": true,
|
"isSubtitles": true,
|
||||||
|
|
|
@ -1948,6 +1948,54 @@ pandora.getVideoURL = function(id, resolution, part, track) {
|
||||||
+ pandora.getVideoURLName(id, resolution, part, track);
|
+ pandora.getVideoURLName(id, resolution, part, track);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pandora.getCensoredClips = function(data) {
|
||||||
|
var annotations = [],
|
||||||
|
clips = [],
|
||||||
|
last;
|
||||||
|
pandora.site.layers.filter(function(layer) {
|
||||||
|
return layer.canPlayClips;
|
||||||
|
}).forEach(function(layer) {
|
||||||
|
data.layers[layer.id] && data.layers[layer.id].forEach(function(annotation, i) {
|
||||||
|
annotations.push(annotation)
|
||||||
|
});
|
||||||
|
});
|
||||||
|
if (annotations.length) {
|
||||||
|
Ox.sort(annotations, function(clip) {
|
||||||
|
return clip['in'];
|
||||||
|
}).forEach(function(clip) {
|
||||||
|
if (last && last['out'] >= clip['in']) {
|
||||||
|
last['out'] = Math.max(last['out'], clip['out']);
|
||||||
|
} else {
|
||||||
|
last = {
|
||||||
|
'in': clip['in'],
|
||||||
|
out: clip.out
|
||||||
|
};
|
||||||
|
clips.push(last);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return clips.length
|
||||||
|
? clips.map(function(clip, i) {
|
||||||
|
return {
|
||||||
|
'in': i == 0 ? 0
|
||||||
|
: clips[i - 1].out,
|
||||||
|
out: clip['in']
|
||||||
|
};
|
||||||
|
}).concat([{
|
||||||
|
'in': Ox.last(clips).out,
|
||||||
|
out: data.duration
|
||||||
|
}]).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)
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
pandora.getVideoOptions = function(data) {
|
pandora.getVideoOptions = function(data) {
|
||||||
var canPlayClips = data.editable
|
var canPlayClips = data.editable
|
||||||
|| pandora.site.capabilities.canPlayClips[pandora.user.level]
|
|| pandora.site.capabilities.canPlayClips[pandora.user.level]
|
||||||
|
@ -1958,29 +2006,8 @@ pandora.getVideoOptions = function(data) {
|
||||||
options = {};
|
options = {};
|
||||||
options.subtitlesLayer = pandora.getSubtitlesLayer();
|
options.subtitlesLayer = pandora.getSubtitlesLayer();
|
||||||
options.censored = canPlayVideo ? []
|
options.censored = canPlayVideo ? []
|
||||||
: canPlayClips ? (
|
: canPlayClips ? pandora.getCensoredClips(data)
|
||||||
options.subtitlesLayer && data.layers[options.subtitlesLayer].length
|
: [{'in': 0, out: data.duration}];
|
||||||
? data.layers[options.subtitlesLayer].map(function(subtitle, i) {
|
|
||||||
return {
|
|
||||||
'in': i == 0 ? 0
|
|
||||||
: data.layers[options.subtitlesLayer][i - 1].out,
|
|
||||||
out: subtitle['in']
|
|
||||||
};
|
|
||||||
}).concat([{
|
|
||||||
'in': Ox.last(data.layers[options.subtitlesLayer]).out,
|
|
||||||
out: data.duration
|
|
||||||
}]).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}];
|
|
||||||
options.video = [];
|
options.video = [];
|
||||||
pandora.site.video.resolutions.forEach(function(resolution) {
|
pandora.site.video.resolutions.forEach(function(resolution) {
|
||||||
if (data.audioTracks) {
|
if (data.audioTracks) {
|
||||||
|
|
Loading…
Reference in a new issue