video widgets: add support for multiple audio and subtitles tracks (first pass)
This commit is contained in:
parent
7d7620601c
commit
00e6367ca9
5 changed files with 248 additions and 236 deletions
|
@ -78,6 +78,8 @@ Ox.AnnotationFolder = function(options, self) {
|
|||
crossesPoint() && updateAnnotations();
|
||||
self.position = self.options.position;
|
||||
}
|
||||
} else if (key == 'languages') {
|
||||
updateAnnotations();
|
||||
} else if (key == 'range') {
|
||||
updateAnnotations();
|
||||
self.$annotations.options({placeholder: getPlaceholder()});
|
||||
|
@ -416,7 +418,9 @@ Ox.AnnotationFolder = function(options, self) {
|
|||
)
|
||||
) && (
|
||||
self.options.languages == 'all'
|
||||
|| self.options.languages.indexOf(item.language) > -1
|
||||
|| self.options.languages.some(function(language) {
|
||||
return item.languages.indexOf(language) > -1;
|
||||
})
|
||||
) && (
|
||||
self.options.users == 'all'
|
||||
|| self.options.users.indexOf(item.user) > -1
|
||||
|
|
|
@ -41,6 +41,7 @@ Ox.VideoAnnotationPanel <f> VideoAnnotationPanel Object
|
|||
@*/
|
||||
|
||||
Ox.VideoAnnotationPanel = function(options, self) {
|
||||
|
||||
self = self || {};
|
||||
var that = Ox.Element({}, self)
|
||||
.defaults({
|
||||
|
@ -88,6 +89,7 @@ Ox.VideoAnnotationPanel = function(options, self) {
|
|||
subtitles: [],
|
||||
subtitlesDefaultTrack: 'en',
|
||||
subtitlesLayer: null,
|
||||
subtitlesTrack: 'en',
|
||||
timeline: '',
|
||||
timelines: [],
|
||||
videoRatio: 16/9,
|
||||
|
@ -281,7 +283,24 @@ Ox.VideoAnnotationPanel = function(options, self) {
|
|||
}
|
||||
});
|
||||
|
||||
self.options.subtitles = self.options.subtitles || getSubtitles();
|
||||
self.options.subtitles = options.subtitles !== void 0
|
||||
? self.options.subtitles : parseSubtitles();
|
||||
self.subtitlesTracks = Ox.sort(Ox.unique(Ox.flatten(
|
||||
self.options.subtitles.map(function(subtitle) {
|
||||
return subtitle.tracks;
|
||||
})
|
||||
))).map(function(track) {
|
||||
return {
|
||||
id: track,
|
||||
title: Ox._(track),
|
||||
checked: self.options.enableSubtitles
|
||||
&& track == self.options.subtitlesTrack
|
||||
};
|
||||
}).concat([{
|
||||
id: '',
|
||||
title: Ox._('None'),
|
||||
checked: !self.options.enableSubtitles
|
||||
}]);
|
||||
|
||||
if (Ox.isObject(self.options.video[0])) {
|
||||
self.resolutions = Ox.sort(Ox.unique(
|
||||
|
@ -302,7 +321,7 @@ Ox.VideoAnnotationPanel = function(options, self) {
|
|||
)).map(function(track) {
|
||||
return {
|
||||
id: track,
|
||||
title: Ox._(Ox.getLanguageNameByCode(video.track)),
|
||||
title: Ox._(track),
|
||||
checked: self.options.audioTrack == track
|
||||
};
|
||||
});
|
||||
|
@ -377,6 +396,7 @@ Ox.VideoAnnotationPanel = function(options, self) {
|
|||
sizeIsLarge: self.options.videoSize == 'large',
|
||||
subtitles: Ox.clone(self.options.subtitles, true),
|
||||
subtitlesDefaultTrack: self.options.subtitlesDefaultTrack,
|
||||
subtitlesTrack: self.options.subtitlesTrack,
|
||||
type: type,
|
||||
video: type == 'play' ? self.options.video : self.options.getFrameURL,
|
||||
volume: self.options.volume,
|
||||
|
@ -591,8 +611,9 @@ Ox.VideoAnnotationPanel = function(options, self) {
|
|||
]}
|
||||
] : [],
|
||||
self.options.subtitles.length ? [
|
||||
// TODO...
|
||||
{id: 'subtitles', title: Ox._('Show Subtitles'), checked: self.options.enableSubtitles}
|
||||
{id: 'subtitlesTracks', title: Ox._('Subtitles'), items: [
|
||||
{group: 'subtitlesTrack', min: 1, max: 1, items: self.subtitlesTracks}
|
||||
]}
|
||||
] : [],
|
||||
[
|
||||
{id: 'timelines', title: Ox._('Timeline'), items: [
|
||||
|
@ -665,7 +686,8 @@ Ox.VideoAnnotationPanel = function(options, self) {
|
|||
}
|
||||
},
|
||||
change: function(data) {
|
||||
var id = data.id;
|
||||
var enableSubtitles,
|
||||
id = data.id;
|
||||
if (id == 'size') {
|
||||
toggleSize();
|
||||
} else if (id == 'loop') {
|
||||
|
@ -674,10 +696,16 @@ Ox.VideoAnnotationPanel = function(options, self) {
|
|||
self.options.resolution = parseInt(data.checked[0].id, 10);
|
||||
self.$player[0].options({resolution: self.options.resolution});
|
||||
} else if (id == 'audioTrack') {
|
||||
// ...
|
||||
} else if (id == 'subtitles') {
|
||||
// TODO...
|
||||
toggleSubtitles();
|
||||
self.options.audioTrack = data.checked[0].id;
|
||||
self.$player[0].options({audioTrack: self.options.audioTrack});
|
||||
} else if (id == 'subtitlesTrack') {
|
||||
enableSubtitles = !!data.checked[0].id;
|
||||
if (enableSubtitles != self.options.enableSubtitles) {
|
||||
self.options.enableSubtitles = enableSubtitles;
|
||||
that.triggerEvent('subtitles', {subtitles: enableSubtitles});
|
||||
}
|
||||
self.options.subtitlesTrack = data.checked[0].id;
|
||||
setSubtitlesTrack();
|
||||
} else if (id == 'timeline') {
|
||||
self.options.timeline = data.checked[0].id;
|
||||
updateTimelines();
|
||||
|
@ -1151,23 +1179,11 @@ Ox.VideoAnnotationPanel = function(options, self) {
|
|||
}
|
||||
|
||||
function getSubtitles() {
|
||||
return self.options.subtitlesLayer ? self.options.layers.filter(function(layer) {
|
||||
return layer.id == self.options.subtitlesLayer;
|
||||
})[0].items.map(function(subtitle) {
|
||||
return {
|
||||
id: subtitle.id,
|
||||
'in': subtitle['in'],
|
||||
out: subtitle.out,
|
||||
text: subtitle.value.replace(/\n/g, ' ').replace(/<br\/?>/g, '\n'),
|
||||
tracks: (
|
||||
subtitle.languages
|
||||
? subtitle.languages
|
||||
: [self.options.subtitleDefaultTrack]
|
||||
).map(function(language) {
|
||||
return Ox.getLanguageNameByCode(language);
|
||||
return self.options.enableSubtitles
|
||||
? self.options.subtitles.filter(function(v) {
|
||||
return Ox.contains(v.tracks, self.options.subtitlesTrack);
|
||||
})
|
||||
};
|
||||
}) : [];
|
||||
: [];
|
||||
}
|
||||
|
||||
function getWords() {
|
||||
|
@ -1203,6 +1219,20 @@ Ox.VideoAnnotationPanel = function(options, self) {
|
|||
setPosition(getNextPosition(type, direction));
|
||||
}
|
||||
|
||||
function parseSubtitles() {
|
||||
return self.options.subtitlesLayer ? self.options.layers.filter(function(layer) {
|
||||
return layer.id == self.options.subtitlesLayer;
|
||||
})[0].items.map(function(subtitle) {
|
||||
return {
|
||||
id: subtitle.id,
|
||||
'in': subtitle['in'],
|
||||
out: subtitle.out,
|
||||
text: subtitle.value.replace(/\n/g, ' ').replace(/<br\/?>/g, '\n'),
|
||||
tracks: subtitle.languages || [self.options.subtitlesDefaultTrack]
|
||||
};
|
||||
}) : [];
|
||||
}
|
||||
|
||||
function playInToOut() {
|
||||
self.$player[0].playInToOut();
|
||||
}
|
||||
|
@ -1364,6 +1394,35 @@ Ox.VideoAnnotationPanel = function(options, self) {
|
|||
});
|
||||
}
|
||||
|
||||
function setSubtitlesTrack() {
|
||||
var enableSubtitles = self.options.subtitlesTrack != '',
|
||||
subtitles,
|
||||
toggleSubtitles = enableSubtitles != self.options.enableSubtitles;
|
||||
self.options.enableSubtitles = enableSubtitles;
|
||||
subtitles = getSubtitles();
|
||||
if (toggleSubtitles) {
|
||||
self.$player.forEach(function($player) {
|
||||
$player.options({
|
||||
enableSubtitles: self.options.enableSubtitles
|
||||
});
|
||||
});
|
||||
that.triggerEvent('subtitles', {
|
||||
subtitles: self.options.enableSubtitles
|
||||
});
|
||||
} else {
|
||||
self.$player.forEach(function($player) {
|
||||
$player.options({
|
||||
subtitles: subtitles
|
||||
});
|
||||
});
|
||||
}
|
||||
self.$timeline.forEach(function($timeline) {
|
||||
$timeline.options({
|
||||
subtitles: subtitles
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function showKeyboardShortcuts() {
|
||||
var dialog = Ox.Dialog({
|
||||
buttons: [
|
||||
|
@ -1505,25 +1564,8 @@ Ox.VideoAnnotationPanel = function(options, self) {
|
|||
});
|
||||
}
|
||||
|
||||
function toggleSubtitles() {
|
||||
self.options.enableSubtitles = !self.options.enableSubtitles;
|
||||
self.$player.forEach(function($player) {
|
||||
$player.options({
|
||||
enableSubtitles: self.options.enableSubtitles
|
||||
});
|
||||
});
|
||||
self.$timeline.forEach(function($timeline) {
|
||||
$timeline.options({
|
||||
subtitles: self.options.enableSubtitles ? Ox.clone(self.options.subtitles, true) : []
|
||||
});
|
||||
});
|
||||
that.triggerEvent('subtitles', {
|
||||
subtitles: self.options.enableSubtitles
|
||||
});
|
||||
}
|
||||
|
||||
function updateSubtitles() {
|
||||
self.options.subtitles = getSubtitles();
|
||||
self.options.subtitles = parseSubtitles();
|
||||
self.$player.forEach(function($player) {
|
||||
$player.options({subtitles: Ox.clone(self.options.subtitles, true)});
|
||||
});
|
||||
|
|
|
@ -71,8 +71,8 @@ Ox.VideoPlayer <f> Generic Video Player
|
|||
out <n> Out point (sec)
|
||||
text <s> Text
|
||||
tracks <[s]> Track names, like "English" or "Director's Commentary"
|
||||
subtitlesDefaultTrack <s|'en'> Default subtitle language (ISO 639-1) or track name
|
||||
subtitlesTrack <s|'en'> Subtitle language (ISO 639-1) or track name
|
||||
subtitlesDefaultTrack <s|'English'> Track name
|
||||
subtitlesTrack <s|'English'> Track name
|
||||
timeline <s> Timeline image URL
|
||||
timelineType <s|''> Current timeline type id
|
||||
timelineTypes <[o]|[]> Array of timeline type objects (id and title)
|
||||
|
@ -166,8 +166,8 @@ Ox.VideoPlayer = function(options, self) {
|
|||
showProgress: false,
|
||||
sizeIsLarge: false,
|
||||
subtitles: [],
|
||||
subtitlesDefaultTrack: 'en',
|
||||
subtitlesTrack: 'en',
|
||||
subtitlesDefaultTrack: 'English',
|
||||
subtitlesTrack: 'English',
|
||||
timeline: '',
|
||||
timelineType: '',
|
||||
timelineTypes: [],
|
||||
|
@ -285,6 +285,8 @@ Ox.VideoPlayer = function(options, self) {
|
|||
self.videoHeight = self.options.height;
|
||||
self.results = [];
|
||||
|
||||
loadSubtitles();
|
||||
|
||||
/*
|
||||
----------------------------------------------------------------------------
|
||||
Keyboard
|
||||
|
@ -1237,8 +1239,6 @@ Ox.VideoPlayer = function(options, self) {
|
|||
|
||||
self.results = [];
|
||||
|
||||
loadSubtitles();
|
||||
|
||||
setSizes(false, function() {
|
||||
self.options.fullscreen && enterFullscreen();
|
||||
});
|
||||
|
@ -1535,11 +1535,6 @@ Ox.VideoPlayer = function(options, self) {
|
|||
return css;
|
||||
}
|
||||
|
||||
function getMenuSection(str) {
|
||||
var match = str.match(/<span class="(.+?)">/);
|
||||
return match ? match[1] : null;
|
||||
}
|
||||
|
||||
function getPosition(e) {
|
||||
// fixme: no offsetX in firefox???
|
||||
if ($.browser.mozilla) {
|
||||
|
@ -1617,23 +1612,25 @@ Ox.VideoPlayer = function(options, self) {
|
|||
|
||||
function getSubtitle() {
|
||||
var subtitle = '';
|
||||
self.options.enableSubtitles && Ox.forEach(self.options.subtitles, function(v) {
|
||||
if (self.options.enableSubtitles) {
|
||||
Ox.forEach(self.options.subtitles, function(v) {
|
||||
if (
|
||||
v['in'] <= self.options.position
|
||||
&& v.out >= self.options.position
|
||||
&& v.track == self.options.subtitlesTrack
|
||||
&& Ox.contains(v.tracks, self.options.subtitlesTrack)
|
||||
) {
|
||||
subtitle = v.text;
|
||||
return false; // break
|
||||
}
|
||||
});
|
||||
}
|
||||
return subtitle;
|
||||
}
|
||||
|
||||
function getSubtitles() {
|
||||
return self.options.enableSubtitles
|
||||
? self.options.subtitles.map(function(v) {
|
||||
return v.track == self.options.subtitlesTrack;
|
||||
? self.options.subtitles.filter(function(v) {
|
||||
return Ox.contains(v.tracks, self.options.subtitlesTrack);
|
||||
})
|
||||
: [];
|
||||
}
|
||||
|
@ -1714,8 +1711,13 @@ Ox.VideoPlayer = function(options, self) {
|
|||
|
||||
function getVideo() {
|
||||
return self.options.video.filter(function(video) {
|
||||
return video.audioTrack == self.options.audioTrack
|
||||
&& video.resolution == self.options.resolution;
|
||||
return (
|
||||
!self.options.audioTrack
|
||||
|| video.track == self.options.audioTrack
|
||||
) && (
|
||||
!self.options.resolution
|
||||
|| video.resolution == self.options.resolution
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1944,14 +1946,9 @@ Ox.VideoPlayer = function(options, self) {
|
|||
|
||||
function loadedsubtitles() {
|
||||
if (!self.subtitlesTracks || Ox.isEmpty(self.subtitlesTracks)) {
|
||||
self.subtitlesTracks = [{
|
||||
code: self.options.subtitlesDefaultTrack,
|
||||
name: Ox.getLanguageNameByCode(
|
||||
self.options.subtitlesDefaultTrack
|
||||
)
|
||||
}];
|
||||
self.subtitlesTracks = [self.options.subtitlesDefaultTrack];
|
||||
}
|
||||
self.subtitlesTracks.push({code: '', name: 'None'});
|
||||
self.subtitlesTracks.push('None');
|
||||
if (self.options.find) {
|
||||
submitFindInput(self.options.find);
|
||||
if (self.options.duration) {
|
||||
|
@ -1968,23 +1965,13 @@ Ox.VideoPlayer = function(options, self) {
|
|||
}
|
||||
|
||||
function loadSubtitles() {
|
||||
if (self.options.subtitles) {
|
||||
if (self.options.subtitles.length) {
|
||||
if (Ox.isArray(self.options.subtitles)) {
|
||||
self.subtitlesTracks = Ox.sortBy(
|
||||
Ox.unique(
|
||||
self.subtitlesTracks = Ox.sort(Ox.unique(Ox.flatten(
|
||||
self.options.subtitles.map(function(subtitle) {
|
||||
return subtitle.track;
|
||||
}).filter(function(track) {
|
||||
return !!track;
|
||||
return subtitle.tracks;
|
||||
})
|
||||
).map(function(track) {
|
||||
return {
|
||||
code: track,
|
||||
name: Ox.getLanguageNameByCode(track)
|
||||
};
|
||||
}),
|
||||
'name'
|
||||
);
|
||||
)));
|
||||
loadedsubtitles();
|
||||
} else {
|
||||
if (self.options.subtitles.indexOf('\n') > -1) {
|
||||
|
@ -2050,33 +2037,77 @@ Ox.VideoPlayer = function(options, self) {
|
|||
}
|
||||
|
||||
function renderSettings() {
|
||||
// fixme: use proper ids (as class of span)
|
||||
var $settings = $('<div>')
|
||||
return Ox.VideoPlayerMenu({
|
||||
items: [{disabled: true, title: Ox._('Resolution')}].concat(
|
||||
self.resolutions.map(function(resolution) {
|
||||
return {
|
||||
group: 'resolution',
|
||||
id: resolution,
|
||||
checked: resolution == self.options.resolution,
|
||||
title: resolution + 'p'
|
||||
};
|
||||
}),
|
||||
self.audioTracks.length > 1
|
||||
? [{}, {disabled: true, title: Ox._('Audio')}].concat(
|
||||
self.audioTracks.map(function(track) {
|
||||
return {
|
||||
group: 'audioTrack',
|
||||
id: track,
|
||||
checked: track == self.options.audioTrack,
|
||||
title: Ox._(track)
|
||||
};
|
||||
})
|
||||
)
|
||||
: [],
|
||||
self.options.subtitles.length
|
||||
? [{}, {disabled: true, title: Ox._('Subtitles')}].concat(
|
||||
self.subtitlesTracks.map(function(track) {
|
||||
return {
|
||||
group: 'subtitlesTrack',
|
||||
id: track,
|
||||
checked: self.options.enableSubtitles
|
||||
? track == self.options.subtitlesTrack
|
||||
: track == '',
|
||||
title: Ox._(track)
|
||||
};
|
||||
})
|
||||
)
|
||||
: [],
|
||||
self.options.timelineTypes.length
|
||||
? [{}, {disabled: true, title: Ox._('Timeline')}].concat(
|
||||
self.options.timelineTypes.map(function(type) {
|
||||
return {
|
||||
group: 'timeline',
|
||||
id: type.id,
|
||||
checked: type.id == self.options.timelineType,
|
||||
title: type.title
|
||||
};
|
||||
})
|
||||
)
|
||||
: [],
|
||||
self.options.enableDownload
|
||||
? [{}, {id: 'download', title: Ox._('Download')}]
|
||||
: []
|
||||
)
|
||||
})
|
||||
.addClass('OxControls OxSettings')
|
||||
.on({
|
||||
click: function(e) {
|
||||
var $target = $(e.target), resolution, title, track, type;
|
||||
self.$settings.hide();
|
||||
if (!$target.is('.OxLine') && !$target.is('.OxSpace')) {
|
||||
title = $(e.target).parent().children()[0].innerHTML;
|
||||
if (title == Ox._('Download')) {
|
||||
that.triggerEvent('download');
|
||||
} else if (getMenuSection(title) == 'resolution') {
|
||||
resolution = parseInt(Ox.stripTags(title), 10);
|
||||
.bindEvent({
|
||||
click: function(data) {
|
||||
var resolution, type;
|
||||
if (data.group == 'resolution') {
|
||||
resolution = parseInt(data.id, 10);
|
||||
if (resolution != self.options.resolution) {
|
||||
self.options.resolution = resolution;
|
||||
setResolution();
|
||||
}
|
||||
} else if (getMenuSection(title) == 'audioTrack') {
|
||||
track = Ox.stripTags(title);
|
||||
self.options.audioTrack = Ox.getLanguageCodeByName(track);
|
||||
} else if (data.group == 'audioTrack') {
|
||||
self.options.audioTrack = data.id;
|
||||
setAudioTrack();
|
||||
} else if (getMenuSection(title) == 'subtitlesTrack') {
|
||||
track = Ox.stripTags(title);
|
||||
self.options.subtitlesTrack = track == 'None'
|
||||
? '' : Ox.getLanguageCodeByName(track);
|
||||
} else if (data.group == 'subtitlesTrack') {
|
||||
self.options.subtitlesTrack = data.id == 'None'
|
||||
? '' : data.id;
|
||||
setSubtitlesTrack();
|
||||
} else {
|
||||
} else if (data.group == 'timeline') {
|
||||
type = self.options.timelineTypes[
|
||||
Ox.indexOf(self.options.timelineTypes, function(type) {
|
||||
return type.title == title;
|
||||
|
@ -2086,114 +2117,12 @@ Ox.VideoPlayer = function(options, self) {
|
|||
self.options.timelineType = type;
|
||||
setTimelineType();
|
||||
}
|
||||
} else if (data.id == 'download') {
|
||||
that.triggerEvent('download');
|
||||
}
|
||||
self.$settings.children('.OxItem').each(function() {
|
||||
var children = $(this).children(),
|
||||
title = children[0].innerHTML,
|
||||
checked = (
|
||||
title == Ox._('Subtitles')
|
||||
&& self.options.enableSubtitles
|
||||
) || (
|
||||
isResolution(title)
|
||||
&& parseInt(title, 10) == self.options.resolution
|
||||
) || (
|
||||
self.options.timelineTypes.length
|
||||
&& title == Ox.getObjectById(
|
||||
self.options.timelineTypes,
|
||||
self.options.timelineType
|
||||
).title
|
||||
);
|
||||
$(children[1]).attr({
|
||||
src: Ox.UI.getImageURL(
|
||||
'symbol' + (checked ? 'Check' : 'None')
|
||||
)
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}),
|
||||
items = [{
|
||||
disabled: true,
|
||||
title: Ox._('Resolution')
|
||||
}].concat(
|
||||
self.resolutions.map(function(resolution) {
|
||||
return {
|
||||
checked: resolution == self.options.resolution,
|
||||
title: '<span class="resolution">'
|
||||
+ resolution + 'p</span>'
|
||||
};
|
||||
}),
|
||||
self.audioTracks.length > 1
|
||||
? [{}, {disabled: true, title: Ox._('Audio')}].concat(
|
||||
self.audioTracks.map(function(track) {
|
||||
return {
|
||||
checked: track.code == self.options.audioTrack,
|
||||
title: '<span class="audioTrack">'
|
||||
+ Ox._(track.name) + '</span>'
|
||||
};
|
||||
})
|
||||
)
|
||||
: [],
|
||||
self.options.subtitles.length
|
||||
? [{}, {disabled: true, title: Ox._('Subtitles')}].concat(
|
||||
self.subtitlesTracks.map(function(track) {
|
||||
return {
|
||||
checked: track.code == self.options.enableSubtitles
|
||||
? self.options.subtitlesTrack : '',
|
||||
title: '<span class="subtitlesTrack">'
|
||||
+ Ox._(track.name) + '</span>'
|
||||
};
|
||||
})
|
||||
)
|
||||
: [],
|
||||
self.options.timelineTypes.length
|
||||
? [{}, {disabled: true, title: Ox._('Timeline')}].concat(
|
||||
self.options.timelineTypes.map(function(type) {
|
||||
return {
|
||||
checked: type.id == self.options.timelineType,
|
||||
title: '<span class="timeline">'
|
||||
+ type.title + '</span>'
|
||||
};
|
||||
})
|
||||
)
|
||||
: [],
|
||||
self.options.enableDownload
|
||||
? [{}, {title: Ox._('Download')}]
|
||||
: []
|
||||
),
|
||||
height = 0;
|
||||
items.forEach(function(item) {
|
||||
var $item;
|
||||
if (item.title) {
|
||||
$item = $('<div>')
|
||||
.addClass('OxItem' + (item.disabled ? ' OxDisabled' : ''))
|
||||
.appendTo($settings);
|
||||
if (!item.disabled) {
|
||||
$item.on({
|
||||
mouseenter: function() {
|
||||
$(this).addClass('OxSelected');
|
||||
},
|
||||
mouseleave: function() {
|
||||
$(this).removeClass('OxSelected');
|
||||
}
|
||||
});
|
||||
}
|
||||
$('<div>').html(item.title).appendTo($item);
|
||||
$('<img>').attr({
|
||||
src: Ox.UI.getImageURL(
|
||||
'symbol' + (item.checked ? 'Check' : 'None')
|
||||
)
|
||||
}).appendTo($item);
|
||||
height += 16;
|
||||
} else {
|
||||
$('<div>').addClass('OxSpace').appendTo($settings);
|
||||
$('<div>').addClass('OxLine').appendTo($settings);
|
||||
$('<div>').addClass('OxSpace').appendTo($settings);
|
||||
height += 1
|
||||
}
|
||||
});
|
||||
$settings.css({height: height + 'px'});
|
||||
return $settings;
|
||||
|
||||
}
|
||||
|
||||
function rewind() {
|
||||
|
@ -2223,7 +2152,7 @@ Ox.VideoPlayer = function(options, self) {
|
|||
}
|
||||
|
||||
function setAudioTrack() {
|
||||
// ...
|
||||
updateVideo();
|
||||
}
|
||||
|
||||
function setCensored() {
|
||||
|
@ -2298,17 +2227,7 @@ Ox.VideoPlayer = function(options, self) {
|
|||
}
|
||||
|
||||
function setResolution() {
|
||||
if (!self.options.paused) {
|
||||
self.playOnLoad = true;
|
||||
togglePaused('button');
|
||||
}
|
||||
self.loadedMetadata = false;
|
||||
showLoadingIcon();
|
||||
self.video = getVideo();
|
||||
self.$video.options({
|
||||
items: self.video
|
||||
});
|
||||
self.$playButton && self.$playButton.options({disabled: true});
|
||||
updateVideo();
|
||||
that.triggerEvent('resolution', {
|
||||
resolution: self.options.resolution
|
||||
});
|
||||
|
@ -2402,17 +2321,24 @@ Ox.VideoPlayer = function(options, self) {
|
|||
}
|
||||
|
||||
function setSubtitlesTrack() {
|
||||
var enableSubtitles = !!self.options.subtitlesTrack;
|
||||
var enableSubtitles = !!self.options.subtitlesTrack,
|
||||
toggleSubtitles = enableSubtitles != self.options.enableSubtitles;
|
||||
self.options.enableSubtitles = enableSubtitles;
|
||||
setSubtitle();
|
||||
self.$timeline && self.$timeline.options({
|
||||
subtitles: getSubtitles()
|
||||
});
|
||||
if (enableSubtitles != self.options.enableSubtitles) {
|
||||
if (toggleSubtitles) {
|
||||
self.options.enableSubtitles = enableSubtitles;
|
||||
that.triggerEvent('subtitles', {
|
||||
subtitles: self.options.enableSubtitles
|
||||
});
|
||||
}
|
||||
if (enableSubtitles) {
|
||||
that.triggerEvent('subtitlestrack', {
|
||||
track: self.options.subtitlesTrack
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function setTimelineType() {
|
||||
|
@ -2421,21 +2347,13 @@ Ox.VideoPlayer = function(options, self) {
|
|||
|
||||
function setVideo() {
|
||||
if (Ox.isObject(self.options.video[0])) {
|
||||
self.audioTracks = Ox.sortBy(Ox.unique(
|
||||
self.audioTracks = Ox.sort(Ox.unique(
|
||||
self.options.video.map(function(video) {
|
||||
return {
|
||||
code: video.track,
|
||||
name: Ox.getLanguageNameByCode(video.track)
|
||||
};
|
||||
return video.track;
|
||||
})
|
||||
), 'name');
|
||||
if (!Ox.contains(
|
||||
self.audioTracks.map(function(track) {
|
||||
return track.code;
|
||||
}),
|
||||
self.options.audioTrack
|
||||
)) {
|
||||
self.options.audioTrack = self.audioTracks[0].code;
|
||||
));
|
||||
if (!Ox.contains(self.audioTracks, self.options.audioTrack)) {
|
||||
self.options.audioTrack = self.audioTracks[0];
|
||||
}
|
||||
self.resolutions = Ox.sort(Ox.unique(
|
||||
self.options.video.map(function(video) {
|
||||
|
@ -2781,6 +2699,20 @@ Ox.VideoPlayer = function(options, self) {
|
|||
self.$volume.toggle();
|
||||
}
|
||||
|
||||
function updateVideo() {
|
||||
if (!self.options.paused) {
|
||||
self.playOnLoad = true;
|
||||
togglePaused('button');
|
||||
}
|
||||
self.loadedMetadata = false;
|
||||
showLoadingIcon();
|
||||
self.video = getVideo();
|
||||
self.$video.options({
|
||||
items: self.video
|
||||
});
|
||||
self.$playButton && self.$playButton.options({disabled: true});
|
||||
}
|
||||
|
||||
/*@
|
||||
changeVolume <f> change volume
|
||||
(num) -> <o> change volume
|
||||
|
|
|
@ -38,7 +38,7 @@ Ox.VideoPlayerMenu = function(options, self) {
|
|||
});
|
||||
|
||||
self.$items = [];
|
||||
self.height = 0;
|
||||
self.height = 2;
|
||||
|
||||
self.options.items.forEach(function(item) {
|
||||
var $item;
|
||||
|
|
|
@ -8,6 +8,7 @@ Ox.VideoPlayerPanel <f> VideoPlayerPanel Object
|
|||
annotationsrange <!> annotationsrange
|
||||
annotationssize <!> annotationssize
|
||||
annotationssort <!> annotationssort
|
||||
audioTrack <s|''> Two-letter ISO 639-1 language code or track name
|
||||
censored <!> censored
|
||||
downloadvideo <!> downloadvideo
|
||||
find <!> find
|
||||
|
@ -40,6 +41,7 @@ Ox.VideoPlayerPanel = function(options, self) {
|
|||
annotationsSize: 256,
|
||||
annotationsSort: 'position',
|
||||
annotationsTooltip: 'annotations',
|
||||
audioTrack: '',
|
||||
censored: [],
|
||||
censoredIcon: '',
|
||||
censoredTooltip: '',
|
||||
|
@ -74,7 +76,9 @@ Ox.VideoPlayerPanel = function(options, self) {
|
|||
showUsers: false,
|
||||
smallTimelineURL: '',
|
||||
subtitles: [],
|
||||
subtitlesDefaultTrack: 'en',
|
||||
subtitlesDefaultTrack: 'English',
|
||||
subtitlesLayer: null,
|
||||
subtitlesTrack: 'English',
|
||||
timeline: '',
|
||||
timelineTooltip: 'timeline',
|
||||
video: '',
|
||||
|
@ -194,6 +198,9 @@ Ox.VideoPlayerPanel = function(options, self) {
|
|||
key_space: togglePaused
|
||||
});
|
||||
|
||||
self.options.subtitles = options.subtitles !== void 0
|
||||
? self.options.subtitles : parseSubtitles();
|
||||
|
||||
self.fullscreen = false;
|
||||
self.results = [];
|
||||
|
||||
|
@ -201,6 +208,7 @@ Ox.VideoPlayerPanel = function(options, self) {
|
|||
|
||||
self.$video = Ox.VideoPlayer({
|
||||
annotations: getAnnotations(),
|
||||
audioTrack: self.options.audioTrack,
|
||||
censored: self.options.censored,
|
||||
censoredIcon: self.options.censoredIcon,
|
||||
censoredTooltip: self.options.censoredTooltip,
|
||||
|
@ -227,8 +235,9 @@ Ox.VideoPlayerPanel = function(options, self) {
|
|||
position: self.options.position,
|
||||
resolution: self.options.resolution,
|
||||
scaleToFill: self.options.scaleToFill,
|
||||
subtitles: self.options.subtitles,
|
||||
subtitles: Ox.clone(self.options.subtitles, true),
|
||||
subtitlesDefaultTrack: self.options.subtitlesDefaultTrack,
|
||||
subtitlesTrack: self.options.subtitlesTrack,
|
||||
timeline: self.options.smallTimelineURL,
|
||||
video: self.options.video,
|
||||
volume: self.options.volume,
|
||||
|
@ -276,11 +285,14 @@ Ox.VideoPlayerPanel = function(options, self) {
|
|||
},
|
||||
select: selectAnnotation,
|
||||
subtitles: function(data) {
|
||||
self.$timeline.options({
|
||||
subtitles: data.subtitles ? self.options.subtitles : []
|
||||
});
|
||||
self.options.enableSubtitles = data.subtitles;
|
||||
self.$timeline.options({subtitles: getSubtitles()});
|
||||
that.triggerEvent('subtitles', data);
|
||||
},
|
||||
subtitlestrack: function(data) {
|
||||
self.options.subtitlesTrack = data.track;
|
||||
self.$timeline.options({subtitles: getSubtitles()});
|
||||
},
|
||||
volume: function(data) {
|
||||
that.triggerEvent('volume', data);
|
||||
}
|
||||
|
@ -301,7 +313,7 @@ Ox.VideoPlayerPanel = function(options, self) {
|
|||
'in': self.options['in'],
|
||||
out: self.options.out,
|
||||
position: self.options.position,
|
||||
subtitles: self.options.enableSubtitles ? self.options.subtitles : [],
|
||||
subtitles: getSubtitles(),
|
||||
videoId: self.options.videoId, // fixme: not in defaults
|
||||
type: self.options.timeline,
|
||||
width: getTimelineWidth()
|
||||
|
@ -463,6 +475,14 @@ Ox.VideoPlayerPanel = function(options, self) {
|
|||
* self.options.annotationsSize - 1;
|
||||
}
|
||||
|
||||
function getSubtitles() {
|
||||
return self.options.enableSubtitles
|
||||
? self.options.subtitles.filter(function(v) {
|
||||
return Ox.contains(v.tracks, self.options.subtitlesTrack);
|
||||
})
|
||||
: [];
|
||||
}
|
||||
|
||||
function getTimelineWidth() {
|
||||
return self.options.width
|
||||
- (self.options.showAnnotations && !self.fullscreen)
|
||||
|
@ -485,6 +505,20 @@ Ox.VideoPlayerPanel = function(options, self) {
|
|||
setPosition(getNextPosition(type, direction));
|
||||
}
|
||||
|
||||
function parseSubtitles() {
|
||||
return self.options.subtitlesLayer ? self.options.layers.filter(function(layer) {
|
||||
return layer.id == self.options.subtitlesLayer;
|
||||
})[0].items.map(function(subtitle) {
|
||||
return {
|
||||
id: subtitle.id,
|
||||
'in': subtitle['in'],
|
||||
out: subtitle.out,
|
||||
text: subtitle.value.replace(/\n/g, ' ').replace(/<br\/?>/g, '\n'),
|
||||
tracks: subtitle.languages || [self.options.subtitlesDefaultTrack]
|
||||
};
|
||||
}) : [];
|
||||
}
|
||||
|
||||
function resizeAnnotations(data) {
|
||||
// called on annotations resize
|
||||
self.options.annotationsSize = data.size;
|
||||
|
|
Loading…
Reference in a new issue