2011-04-23 16:45:50 +00:00
|
|
|
// vim: et:ts=4:sw=4:sts=4:ft=js
|
2011-04-22 22:03:10 +00:00
|
|
|
Ox.VideoEditorPlayer = function(options, self) {
|
|
|
|
|
|
|
|
var self = self || {},
|
|
|
|
that = new Ox.Element('div', self)
|
|
|
|
.defaults({
|
|
|
|
duration: 0,
|
|
|
|
find: '',
|
|
|
|
height: 0,
|
|
|
|
points: [0, 0],
|
|
|
|
position: 0,
|
|
|
|
posterFrame: 0,
|
|
|
|
size: 'small',
|
|
|
|
subtitles: [],
|
|
|
|
type: 'play',
|
|
|
|
url: '',
|
|
|
|
width: 0
|
|
|
|
})
|
|
|
|
.options(options || {})
|
|
|
|
.addClass('OxVideoPlayer')
|
|
|
|
.css({
|
|
|
|
height: (self.options.height + 16) + 'px',
|
|
|
|
width: self.options.width + 'px'
|
|
|
|
});
|
|
|
|
|
|
|
|
self.controlsHeight = 16;
|
|
|
|
|
|
|
|
if (self.options.type == 'play') {
|
|
|
|
self.$video = new Ox.VideoElement({
|
|
|
|
height: self.options.height,
|
|
|
|
paused: true,
|
|
|
|
points: self.options.points,
|
|
|
|
position: self.options.position,
|
|
|
|
url: self.options.url,
|
|
|
|
width: self.options.width
|
|
|
|
})
|
|
|
|
.bindEvent({
|
|
|
|
paused: paused,
|
|
|
|
playing: playing
|
|
|
|
})
|
|
|
|
.appendTo(that);
|
|
|
|
self.video = self.$video.$element[0];
|
|
|
|
} else {
|
|
|
|
self.$video = $('<img>')
|
|
|
|
.css({
|
|
|
|
height: self.options.height + 'px',
|
|
|
|
width: self.options.width + 'px'
|
|
|
|
})
|
|
|
|
.appendTo(that.$element)
|
|
|
|
}
|
|
|
|
|
|
|
|
self.$subtitle = $('<div>')
|
|
|
|
.addClass('OxSubtitle')
|
|
|
|
.appendTo(that.$element);
|
|
|
|
|
|
|
|
setSubtitleSize();
|
|
|
|
|
|
|
|
self.$markerFrame = $('<div>')
|
|
|
|
.addClass('OxMarkerFrame')
|
|
|
|
.append(
|
|
|
|
$('<div>')
|
|
|
|
.addClass('OxFrame')
|
|
|
|
.css({
|
|
|
|
width: Math.floor((self.options.width - self.options.height) / 2) + 'px',
|
|
|
|
height: self.options.height + 'px'
|
|
|
|
})
|
|
|
|
)
|
|
|
|
.append(
|
|
|
|
$('<div>')
|
|
|
|
.addClass('OxPoster')
|
|
|
|
.css({
|
|
|
|
width: (self.options.height - 2) + 'px',
|
|
|
|
height: (self.options.height - 2) + 'px'
|
|
|
|
})
|
|
|
|
)
|
|
|
|
.append(
|
|
|
|
$('<div>')
|
|
|
|
.addClass('OxFrame')
|
|
|
|
.css({
|
|
|
|
width: Math.ceil((self.options.width - self.options.height) / 2) + 'px',
|
|
|
|
height: self.options.height + 'px'
|
|
|
|
})
|
|
|
|
)
|
|
|
|
.hide()
|
|
|
|
.appendTo(that.$element);
|
|
|
|
|
|
|
|
self.$markerPoint = {};
|
|
|
|
['in', 'out'].forEach(function(point, i) {
|
|
|
|
self.$markerPoint[point] = {};
|
|
|
|
['top', 'bottom'].forEach(function(edge) {
|
|
|
|
var titleCase = Ox.toTitleCase(point) + Ox.toTitleCase(edge);
|
|
|
|
self.$markerPoint[point][edge] = $('<img>')
|
|
|
|
.addClass('OxMarkerPoint OxMarker' + titleCase)
|
|
|
|
.attr({
|
|
|
|
src: Ox.UI.PATH + 'png/ox.ui/videoMarker' + titleCase + '.png'
|
|
|
|
})
|
|
|
|
.hide()
|
|
|
|
.appendTo(that.$element);
|
|
|
|
if (self.options.points[i] == self.options.position) {
|
|
|
|
self.$markerPoint[point][edge].show();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
self.$controls = new Ox.Bar({
|
|
|
|
size: self.controlsHeight
|
|
|
|
})
|
|
|
|
.css({
|
|
|
|
marginTop: '-2px'
|
|
|
|
})
|
|
|
|
.appendTo(that);
|
|
|
|
|
|
|
|
if (self.options.type == 'play') {
|
|
|
|
// fixme: $buttonPlay etc. ?
|
|
|
|
self.$playButton = new Ox.Button({
|
|
|
|
id: self.options.id + 'Play',
|
|
|
|
title: [
|
|
|
|
{id: 'play', title: 'play'},
|
|
|
|
{id: 'pause', title: 'pause'}
|
|
|
|
],
|
|
|
|
tooltip: ['Play', 'Pause'],
|
|
|
|
type: 'image'
|
|
|
|
})
|
|
|
|
.bindEvent('click', togglePlay)
|
|
|
|
.appendTo(self.$controls);
|
|
|
|
self.$playInToOutButton = new Ox.Button({
|
|
|
|
id: self.options.id + 'PlayInToOut',
|
|
|
|
title: 'PlayInToOut',
|
|
|
|
tooltip: 'Play In to Out',
|
|
|
|
type: 'image'
|
|
|
|
})
|
|
|
|
.bindEvent('click', function() {
|
|
|
|
that.playInToOut();
|
|
|
|
})
|
|
|
|
.appendTo(self.$controls);
|
|
|
|
self.$muteButton = new Ox.Button({
|
|
|
|
id: self.options.id + 'Mute',
|
|
|
|
title: [
|
|
|
|
{id: 'mute', title: 'mute'},
|
|
|
|
{id: 'unmute', title: 'unmute'}
|
|
|
|
],
|
|
|
|
tooltip: ['Mute', 'Unmute'],
|
|
|
|
type: 'image'
|
|
|
|
})
|
|
|
|
.bindEvent('click', toggleMute)
|
|
|
|
.appendTo(self.$controls);
|
|
|
|
self.$sizeButton = new Ox.Button({
|
|
|
|
id: self.options.id + 'Size',
|
|
|
|
title: self.options.size == 'small' ? [
|
|
|
|
{id: 'large', title: 'grow'},
|
|
|
|
{id: 'small', title: 'shrink'}
|
|
|
|
] : [
|
|
|
|
{id: 'small', title: 'shrink'},
|
|
|
|
{id: 'large', title: 'grow'}
|
|
|
|
],
|
|
|
|
tooltip: ['Larger', 'Smaller'],
|
|
|
|
type: 'image'
|
|
|
|
})
|
|
|
|
.bindEvent('click', toggleSize)
|
|
|
|
.appendTo(self.$controls);
|
|
|
|
} else {
|
|
|
|
self.$goToPointButton = new Ox.Button({
|
|
|
|
id: self.options.id + 'GoTo' + Ox.toTitleCase(self.options.type),
|
|
|
|
title: 'GoTo' + Ox.toTitleCase(self.options.type),
|
|
|
|
tooltip: 'Go to ' + Ox.toTitleCase(self.options.type) + ' Point',
|
|
|
|
type: 'image'
|
|
|
|
})
|
|
|
|
.bindEvent('click', goToPoint)
|
|
|
|
.appendTo(self.$controls);
|
|
|
|
self.$setPointButton = new Ox.Button({
|
|
|
|
id: self.options.id + 'Set' + Ox.toTitleCase(self.options.type),
|
|
|
|
title: 'Set' + Ox.toTitleCase(self.options.type),
|
|
|
|
tooltip: 'Set ' + Ox.toTitleCase(self.options.type) + ' Point',
|
|
|
|
type: 'image'
|
|
|
|
})
|
|
|
|
.bindEvent('click', setPoint)
|
|
|
|
.appendTo(self.$controls);
|
|
|
|
}
|
|
|
|
|
|
|
|
self.$positionInput = new Ox.TimeInput({
|
|
|
|
milliseconds: true,
|
|
|
|
seconds: true,
|
|
|
|
value: Ox.formatDuration(self.options.position, 3)
|
|
|
|
})
|
|
|
|
.css({
|
|
|
|
float: 'right',
|
|
|
|
})
|
|
|
|
.appendTo(self.$controls)
|
|
|
|
|
|
|
|
// fixme: strange positioning hack
|
|
|
|
self.$positionInput.css({
|
|
|
|
width: '98px'
|
|
|
|
});
|
|
|
|
$.browser.mozilla && self.$positionInput.css({
|
|
|
|
marginTop: '-19px'
|
|
|
|
});
|
|
|
|
// fixme: children doesnt work w/o $element
|
|
|
|
self.$positionInput.$element.children('.OxLabel').each(function(i, element) {
|
|
|
|
$(this).css({
|
|
|
|
width: '22px',
|
|
|
|
marginLeft: (i == 0 ? 8 : 0) + 'px',
|
|
|
|
background: 'rgb(32, 32, 32)'
|
|
|
|
});
|
|
|
|
});
|
|
|
|
self.$positionInput.$element.children('div.OxInput').each(function(i) {
|
|
|
|
var marginLeft = [-82, -58, -34, -10];
|
|
|
|
$(this).css({
|
|
|
|
marginLeft: marginLeft[i] + 'px'
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
if (self.options.type == 'play') {
|
|
|
|
self.$loadingIcon = new Ox.LoadingIcon()
|
|
|
|
.appendTo(that)
|
|
|
|
.start();
|
|
|
|
self.loadingInterval = setInterval(function() {
|
|
|
|
if (self.video.readyState) {
|
|
|
|
clearInterval(self.loadingInterval);
|
|
|
|
self.$loadingIcon.stop();
|
|
|
|
setPosition();
|
|
|
|
}
|
|
|
|
}, 50);
|
|
|
|
} else {
|
|
|
|
setPosition();
|
|
|
|
}
|
|
|
|
|
|
|
|
function getSubtitle() {
|
|
|
|
var subtitle = '';
|
|
|
|
Ox.forEach(self.options.subtitles, function(v) {
|
|
|
|
if (v['in'] <= self.options.position && v['out'] > self.options.position) {
|
|
|
|
subtitle = v.value;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
return subtitle;
|
|
|
|
}
|
|
|
|
|
|
|
|
function goToPoint() {
|
|
|
|
that.triggerEvent('change', {
|
|
|
|
position: self.options.points[self.options.type == 'in' ? 0 : 1]
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function paused(event, data) {
|
|
|
|
self.$playButton.toggleTitle();
|
|
|
|
}
|
|
|
|
|
|
|
|
function playing(event, data) {
|
|
|
|
self.options.position = data.position;
|
|
|
|
setMarkers();
|
|
|
|
setSubtitle();
|
|
|
|
self.$positionInput.options({
|
|
|
|
value: Ox.formatDuration(self.options.position, 3)
|
|
|
|
});
|
|
|
|
that.triggerEvent('playing', {
|
|
|
|
position: self.options.position
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function setHeight() {
|
|
|
|
that.css({
|
|
|
|
height: (self.options.height + 16) + 'px'
|
|
|
|
});
|
|
|
|
self.options.type == 'play' ? self.$video.options({
|
|
|
|
height: self.options.height
|
|
|
|
}) : self.$video.css({
|
|
|
|
height: self.options.height + 'px'
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function setMarkers() {
|
|
|
|
self.options.position == self.options.posterFrame ?
|
|
|
|
self.$markerFrame.show() : self.$markerFrame.hide();
|
|
|
|
Ox.forEach(self.$markerPoint, function(markers, point) {
|
|
|
|
Ox.forEach(markers, function(marker) {
|
|
|
|
self.options.position == self.options.points[point == 'in' ? 0 : 1] ?
|
|
|
|
marker.show() : marker.hide();
|
|
|
|
});
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
function setPoint() {
|
|
|
|
var data = {};
|
|
|
|
self.options.points[self.options.type == 'in' ? 0 : 1] = self.options.position;
|
|
|
|
setMarkers();
|
|
|
|
data[self.options.type] = self.options.position;
|
|
|
|
that.triggerEvent('set', data);
|
|
|
|
}
|
|
|
|
|
|
|
|
function setPosition() {
|
|
|
|
var position = Ox.limit(
|
|
|
|
self.options.position - (self.options.type == 'out' ? 0.01 : 0),
|
|
|
|
0, self.options.duration - 0.01
|
|
|
|
),
|
|
|
|
url;
|
|
|
|
if (self.options.type == 'play') {
|
|
|
|
self.$video.position(self.options.position);
|
|
|
|
} else {
|
|
|
|
self.$loadingIcon && self.$loadingIcon.stop();
|
|
|
|
url = self.options.url(position);
|
|
|
|
if (self.$video.attr('src') != url) {
|
|
|
|
self.$loadingIcon = new Ox.LoadingIcon()
|
|
|
|
.appendTo(that)
|
|
|
|
.start();
|
|
|
|
self.$video.attr({
|
|
|
|
src: url
|
|
|
|
})
|
|
|
|
.load(self.$loadingIcon.stop);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
setMarkers();
|
|
|
|
setSubtitle();
|
|
|
|
self.$positionInput.options({
|
|
|
|
value: Ox.formatDuration(self.options.position, 3)
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function setSubtitle() {
|
|
|
|
var subtitle = getSubtitle();
|
|
|
|
if (subtitle != self.subtitle) {
|
|
|
|
self.subtitle = subtitle;
|
|
|
|
self.$subtitle.html(Ox.highlight(self.subtitle, self.options.find).replace(/\n/g, '<br/>'));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function setSubtitleSize() {
|
|
|
|
self.$subtitle.css({
|
|
|
|
bottom: parseInt(self.controlsHeight + self.options.height / 16) + 'px',
|
|
|
|
width: self.options.width + 'px',
|
|
|
|
fontSize: parseInt(self.options.height / 20) + 'px',
|
|
|
|
WebkitTextStroke: (self.options.height / 1000) + 'px rgb(0, 0, 0)'
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function setWidth() {
|
|
|
|
that.css({
|
|
|
|
width: self.options.width + 'px'
|
|
|
|
});
|
|
|
|
self.options.type == 'play' ? self.$video.options({
|
|
|
|
width: self.options.width
|
|
|
|
}) : self.$video.css({
|
|
|
|
width: self.options.width + 'px'
|
|
|
|
});
|
|
|
|
setSubtitleSize();
|
|
|
|
}
|
|
|
|
|
|
|
|
function toggleMute() {
|
|
|
|
self.$video.toggleMute();
|
|
|
|
}
|
|
|
|
|
|
|
|
function togglePlay() {
|
|
|
|
self.video.paused ? that.play() : that.pause();
|
|
|
|
}
|
|
|
|
|
|
|
|
function toggleSize(event, data) {
|
|
|
|
self.options.size = data.id
|
|
|
|
that.triggerEvent('togglesize', {
|
|
|
|
size: self.options.size
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
self.onChange = function(key, value) {
|
|
|
|
if (key == 'height') {
|
|
|
|
setHeight();
|
|
|
|
} else if (key == 'points') {
|
|
|
|
setMarkers();
|
|
|
|
} else if (key == 'position') {
|
|
|
|
setPosition();
|
|
|
|
} else if (key == 'posterFrame') {
|
|
|
|
setMarkers();
|
|
|
|
} else if (key == 'width') {
|
|
|
|
setWidth();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
that.mute = function() {
|
|
|
|
self.$video.mute();
|
|
|
|
return that;
|
|
|
|
};
|
|
|
|
|
|
|
|
that.pause = function() {
|
|
|
|
self.$video.pause();
|
|
|
|
return that;
|
|
|
|
};
|
|
|
|
|
|
|
|
that.play = function() {
|
|
|
|
self.$video.play();
|
|
|
|
return that;
|
|
|
|
};
|
|
|
|
|
|
|
|
that.playInToOut = function() {
|
|
|
|
self.$video.paused() && self.$playButton.toggleTitle();
|
|
|
|
self.$video.playInToOut();
|
|
|
|
return that;
|
|
|
|
};
|
|
|
|
|
|
|
|
that.toggleMute = function() {
|
|
|
|
self.$muteButton.trigger('click');
|
|
|
|
return that;
|
|
|
|
}
|
|
|
|
|
|
|
|
that.togglePlay = function() {
|
|
|
|
self.$playButton.trigger('click');
|
|
|
|
return that;
|
|
|
|
}
|
|
|
|
|
|
|
|
that.unmute = function() {
|
|
|
|
self.$video.unmute();
|
|
|
|
return that;
|
|
|
|
};
|
|
|
|
|
|
|
|
return that;
|
|
|
|
|
|
|
|
};
|