diff --git a/static/js/timeline.js b/static/js/timeline.js deleted file mode 100644 index a4e0a1ca..00000000 --- a/static/js/timeline.js +++ /dev/null @@ -1,1303 +0,0 @@ -$(function() { - - /* - h1 is 0.5-12 times as large as h0 - w1 is 0.5-12*ratio as large as w0 - h1 = (h0 - 24) / 2 - w1 = h1 * ratio - w0 = pageWidth - 8 - w1 - */ - var $body = $("body"), - $document = $(document), - $window = $(window), - $editor, - $panel, - $player = [], - $players, - $timelines, - $timelineLarge, - $timelineSmall, - find = "cinema", - matches = [3, 22, 24, 55, 57, 61, 70, 105, 118, 122, 150, 152, 155], - pageWidth = $document.width() - 384 - 2, - posterFrame = 1515, - points = [2059, 2748], - videoId = document.location.hash.substring(1), - videoUrl = "/" + videoId + "/96p." + ($.support.video.webm ? "webm": "mp4"), - stripTimeline = false; - - $.getJSON("/" + videoId + "/data/video.json", function(video) { - var duration = video.duration, - videoRatio = video.aspectRatio, - videoHeight = 96, - videoWidth = parseInt(video.aspectRatio*videoHeight), - position = duration/2; - - videoWidth += videoWidth%2; - videoUrl = video.baseUrl + "/" + video.profiles[0] + "p." + ($.support.video.webm ? "webm": "mp4"); - - //resizeVideoPlayers(pageWidth); - - Ox.Editor = function(options, self) { - - var self = self || {}, - that = new Ox.Element("div", self) - .defaults({ - cuts: [], - duration: 0, - find: "", - largeTimeline: true, - matches: [], - points: [0, 0], - position: 0, - posterFrame: 0, - subtitles: [], - videoHeight: 0, - videoId: "", - videoWidth: 0, - videoSize: "large", - width: 0 - }) - .options(options || {}) - .addClass("OxEditor"); - - $.extend(self, { - $player: [], - $timeline: [], - controlsHeight: 16, - margin: 8, - videoRatio: self.options.videoWidth / self.options.videoHeight - }); - self.sizes = getSizes(); - - $.each(["play", "in", "out"], function(i, type) { - self.$player[i] = new Ox.VideoPlayer({ - duration: self.options.duration, - find: self.options.find, - height: self.sizes.player[i].height, - id: "player" + Ox.toTitleCase(type), - points: self.options.points, - position: type == "play" ? self.options.position : self.options.points[type == "in" ? 0 : 1], - posterFrame: self.options.posterFrame, - subtitles: self.options.subtitles, - type: type, - url: videoUrl, - width: self.sizes.player[i].width - }) - .css({ - left: self.sizes.player[i].left + "px", - top: self.sizes.player[i].top + "px" - }) - .appendTo(that); - if (type == "in" || type == "out") { - self.$player[i].bindEvent({ - change: function() { - goToPoint(type); - }, - set: function() { - setPoint(type); - } - }) - } - }); - self.$player[0].bindEvent("change", changePlayer); - - self.$timeline[0] = new Ox.LargeTimeline({ - cuts: self.options.cuts, - duration: self.options.duration, - find: self.options.find, - id: "timelineLarge", - matches: self.options.matches, - points: self.options.points, - position: self.options.position, - subtitles: self.options.subtitles, - videoId: self.options.videoId, - width: self.sizes.timeline[0].width - }) - .css({ - left: self.sizes.timeline[0].left + "px", - top: self.sizes.timeline[0].top + "px" - }) - .bindEvent("change", changeTimelineLarge) - .bindEvent("changeEnd", changeTimelineLarge) - .appendTo(that); - - self.$timeline[1] = new Ox.SmallTimeline({ - cuts: self.options.cuts, - duration: self.options.duration, - find: self.options.find, - id: "timelineSmall", - matches: self.options.matches, - points: self.options.points, - position: self.options.position, - subtitles: self.options.subtitles, - videoId: self.options.videoId, - width: self.sizes.timeline[1].width - }) - .css({ - left: self.sizes.timeline[1].left + "px", - top: self.sizes.timeline[1].top + "px" - }) - .bindEvent("change", changeTimelineSmall) - .appendTo(that); - - that.addEvent({ - key_alt_left: function() { - movePositionBy(-0.04); - }, - key_alt_right: function() { - movePositionBy(0.04); - }, - key_alt_shift_left: function() { - movePositionTo("cut", -1); - }, - key_alt_shift_right: function() { - movePositionTo("cut", 1); - }, - key_closebracket: function() { - goToPoint("out"); - }, - key_comma: function() { - movePositionTo("subtitle", -1); - }, - key_dot: function() { - movePositionTo("subtitle", 1); - }, - key_down: function() { - movePositionBy(self.options.width - 2 * self.margin); - }, - key_i: function() { - setPoint("in"); - }, - key_left: function() { - movePositionBy(-1); - }, - key_m: toggleMute, - key_o: function() { - setPoint("out"); - }, - key_openbracket: function() { - goToPoint("in"); - }, - key_p: playInToOut, - key_right: function() { - movePositionBy(1); - }, - key_shift_comma: function() { - movePositionTo("match", -1) - }, - key_shift_dot: function() { - movePositionTo("match", 1) - }, - key_shift_down: function() { - movePositionBy(self.options.duration); - }, - key_shift_left: function() { - movePositionBy(-60); - }, - key_shift_right: function() { - movePositionBy(60); - }, - key_shift_up: function() { - movePositionBy(-self.options.duration); - }, - key_space: togglePlay, - key_up: function() { - movePositionBy(-(self.options.width - 2 * self.margin)); - } - }); - - that.gainFocus(); - - function changePlayer(event, data) { - self.options.position = data.position; - self.$timeline[0].options({ - position: data.position - }); - self.$timeline[1].options({ - position: data.position - }); - } - - function changeTimelineLarge(event, data) { - self.options.position = data.position; - self.$player[0].options({ - position: data.position - }); - self.$timeline[1].options({ - position: data.position - }); - } - - function changeTimelineSmall(event, data) { - self.options.position = data.position; - self.$player[0].options({ - position: data.position - }); - self.$timeline[0].options({ - position: data.position - }); - } - - function getNextPosition(type, direction) { - var found = false, - position = 0, - positions; - if (type == "cut") { - positions = self.options.cuts; - } else if (type == "match") { - positions = $.map(self.options.matches, function(v, i) { - return self.options.subtitles[v]["in"]; - }); - } else if (type == "subtitle") { - positions = $.map(self.options.subtitles, function(v, i) { - return v["in"]; - }); - } - direction == -1 && positions.reverse(); - $.each(positions, function(i, v) { - if (direction == 1 ? v > self.options.position : v < self.options.position) { - position = v; - found = true; - return false; - } - }); - direction == -1 && positions.reverse(); - if (!found) { - position = positions[direction == 1 ? 0 : positions.length - 1]; - } - return position; - } - - function getSizes() { - var size = { - player: [], - timeline: [] - }; - size.player[0] = { - left: self.margin / 2, - top: self.margin / 2, - width: Math.round((self.options.width - 3 * self.margin + (self.controlsHeight + self.margin) / 2 * self.videoRatio) * 2/3), - } - size.player[0].height = Math.round(size.player[0].width / self.videoRatio); - size.player[1] = { - left: size.player[0].left + size.player[0].width + self.margin, - top: size.player[0].top, - width: self.options.width - 3 * self.margin - size.player[0].width - } - size.player[1].height = Math.ceil(size.player[1].width / self.videoRatio) - size.player[2] = { - left: size.player[1].left, - top: size.player[0].top + size.player[1].height + self.controlsHeight + self.margin, - width: size.player[1].width, - height: size.player[0].height - size.player[1].height - self.controlsHeight - self.margin - } - size.timeline[0] = { - left: self.margin / 2, - top: size.player[0].height + self.controlsHeight + 1.5 * self.margin, - width: self.options.width - 2 * self.margin, - height: 64 - } - size.timeline[1] = { - left: size.timeline[0].left, - top: size.timeline[0].top + size.timeline[0].height + self.margin, - width: size.timeline[0].width - } - return size; - } - - function goToPoint(point) { - self.options.position = self.options.points[point == "in" ? 0 : 1]; - setPosition(); - that.triggerEvent("change", { - position: self.options.position - }); - } - - function movePositionBy(sec) { - self.options.position = Ox.limit(self.options.position + sec, 0, self.options.duration); - setPosition(); - that.triggerEvent("change", { - position: self.options.position - }); - } - - function movePositionTo(type, direction) { - self.options.position = getNextPosition(type, direction); - setPosition(); - that.triggerEvent("change", { - position: self.options.position - }); - } - - function playInToOut() { - self.$player[0].playInToOut(); - } - - function resizeEditor(event, data) { - var width = data - 2 * margin + 100; - resizeVideoPlayers(width); - $timelineLarge.options({ - width: width - }); - $timelineSmall.options({ - width: width - }); - } - - function resizePlayers() { - $.each(self.$player, function(i, v) { - v.options({ - width: size[i].width, - height: size[i].height - }) - .css({ - left: size[i].left + "px", - top: size[i].top + "px", - }); - }); - } - - function setPoint(point) { - self.options.points[point == "in" ? 0 : 1] = self.options.position; - self.$player[point == "in" ? 1 : 2].options({ - position: self.options.position - }); - if (self.options.points[1] < self.options.points[0]) { - self.options.points[point == "in" ? 1 : 0] = self.options.position; - self.$player[point == "in" ? 2 : 1].options({ - position: self.options.position - }); - } - $.each(self.$player, function(i, v) { - v.options({ - points: self.options.points - }); - }); - $.each(self.$timeline, function(i, v) { - v.options({ - points: self.options.points - }); - }); - } - - function setPosition() { - self.$player[0].options({ - position: self.options.position - }); - $.each(self.$timeline, function(i, v) { - v.options({ - position: self.options.position - }); - }); - } - - function toggleMute() { - self.$player[0].toggleMute(); - } - - function togglePlay() { - self.$player[0].togglePlay(); - } - - self.onChange = function(key, value) { - if (key == "width") { - self.sizes = getSizes(); - $.each(self.$player, function(i, v) { - v.options({ - height: self.sizes.player[i].height, - width: self.sizes.player[i].width - }) - .css({ - left: self.sizes.player[i].left + "px", - top: self.sizes.player[i].top + "px" - }); - }); - $.each(self.$timeline, function(i, v) { - v.options({ - width: self.sizes.timeline[i].width - }) - .css({ - left: self.sizes.timeline[i].left + "px", - top: self.sizes.timeline[i].top + "px" - }); - }); - } - }; - - return that; - - }; - - Ox.LargeTimeline = function(options, self) { - - var self = self || {}, - that = new Ox.Element("div", self) - .defaults({ - cuts: [], - duration: 0, - find: "", - matches: [], - points: [0, 0], - position: 0, - subtitles: [], - videoId: "", - width: 0 - }) - .options(options || {}) - .addClass("OxTimelineLarge") - .mousedown(mousedown) - .mouseleave(mouseleave) - .mousemove(mousemove); - - $.extend(self, { - $cuts: [], - $markerPoint: [], - $subtitles: [], - $tiles: {}, - center: parseInt(self.options.width / 2), - element: that.$element[0], - fps: 25, - height: 64, - tileWidth: 1500 - }); - self.tiles = self.options.duration * self.fps / self.tileWidth; - - self.$timeline = $("
") - .css({ - left: self.center + "px" - }) - .appendTo(that.$element) - - $.each(self.options.subtitles, function(i, v) { - self.$subtitles[i] = $("
") - .addClass("OxSubtitle" + (self.options.matches.indexOf(i) > -1 ? " OxHighlight" : "")) - .css({ - left: (v["in"] * self.fps) + "px", - width: (((v["out"] - v["in"]) * self.fps) - 4) + "px" - }) - .html(highlight(v.text, self.options.find)) - .appendTo(self.$timeline) - }); - - $.each(self.options.cuts, function(i, v) { - self.$cuts[i] = $("") - .addClass("OxCut") - .attr({ - src: "/static/oxjs/build/png/ox.ui/videoMarkerCut.png" - }) - .css({ - left: (v * self.fps) + "px" - }) - .appendTo(self.$timeline) - }); - - self.$markerPosition = $("") - .addClass("OxMarkerPosition") - .attr({ - src: "/static/oxjs/build/png/ox.ui/videoMarkerPlay.png" - }) - .appendTo(that.$element); - setMarker(); - - $.each(["In", "Out"], function(i, v) { - self.$markerPoint[i] = $("") - .addClass("OxMarkerPoint" + v) - .attr({ - src: "/static/oxjs/build/png/ox.ui/videoMarker" + v + ".png" - }) - .appendTo(self.$timeline); - setMarkerPoint(i); - }); - - setWidth(); - setPosition(); - - function mousedown(e) { - var mousemove = false, - x = e.clientX; - $window.mousemove(function(e) { - mousemove = true; - self.options.position = Ox.limit( - self.options.position + (x - e.clientX) / self.fps, - 0, self.options.duration - ); - x = e.clientX; - setPosition(); - that.triggerEvent("change", { - position: self.options.position - }); - }); - $window.one("mouseup", function() { - $window.unbind("mousemove"); - if (!mousemove) { - self.options.position = Ox.limit( - self.options.position + (e.clientX - that.$element.offset().left - self.center) / self.fps, - 0, self.options.duration - ); - setPosition(); - } - that.triggerEvent("change", { - position: self.options.position - }); - }); - e.preventDefault(); - } - - function mouseleave(e) { - self.$tooltip.hide(); - } - - function mousemove(e) { - if (!self.$tooltip) { - self.$tooltip = Ox.Tooltip(); - } - self.$tooltip - .options({ - title: Ox.formatDuration(self.options.position + (e.clientX - that.offset().left - self.center) / self.fps, 3) - }) - .show(e.clientX, e.clientY); - } - - function setMarkerPoint(i) { - self.$markerPoint[i].css({ - left: (self.options.points[i] * self.fps) + "px" - }); - } - - function setMarker() { - self.$markerPosition.css({ - left: (self.center - 4) + "px", - }); - } - - function setPosition() { - self.tile = parseInt(self.options.position * self.fps / self.tileWidth); - self.$timeline.css({ - marginLeft: (-self.options.position * self.fps) + "px" - }); - $.each(Ox.range(Math.max(self.tile - 1, 0), Math.min(self.tile + 2, self.tiles)), function(i, v) { - if (!self.$tiles[v]) { - self.$tiles[v] = $("") - .attr({ - src: "/" + self.options.videoId + "/timelines/" + (stripTimeline ? "strip" : "timeline") + ".64." + v + ".png" - }) - .css({ - left: (v * self.tileWidth) + "px" - }) - .appendTo(self.$timeline); - } - }); - } - - function setWidth() { - self.center = parseInt(self.options.width / 2); - that.css({ - width: self.options.width + "px" - }); - self.$timeline.css({ - left: self.center + "px" - }); - setMarker(); - } - - self.onChange = function(key, value) { - if (key == "points") { - setMarkerPoint(0); - setMarkerPoint(1); - } else if (key == "position") { - setPosition(); - } else if (key == "width") { - setWidth(); - } - }; - - return that; - - }; - - Ox.SmallTimeline = function(options, self) { - - var self = self || {}, - that = new Ox.Element("div", self) - .defaults({ - cuts: [], - duration: 0, - find: "", - matches: [], - points: [0, 0], - position: 0, - subtitles: [], - videoId: "", - width: 0 - }) - .options(options || {}) - .addClass("OxTimelineSmall") - .mousedown(mousedown) - .mouseleave(mouseleave) - .mousemove(mousemove); - - $.extend(self, { - $images: [], - $lines: [], - $markerPoint: [], - $subtitles: [], - height: 16, - lines: Math.ceil(self.options.duration / self.options.width), - margin: 8, - subtitlesImageURL: getSubtitlesImageURL() - }); - - $.each(Ox.range(0, self.lines), function(i) { - addLine(i); - }); - - self.$markerPosition = $("") - .addClass("OxMarkerPosition") - .attr({ - src: "/static/oxjs/build/png/ox.ui/videoMarkerPlay.png" - }) - .css({ - position: "absolute", - width: "9px", - height: "5px", - zIndex: 10 - }) - .appendTo(that.$element); - - setPosition(); - - $.each(["in", "out"], function(i, v) { - var titleCase = Ox.toTitleCase(v); - self.$markerPoint[i] = $("") - .addClass("OxMarkerPoint" + titleCase) - .attr({ - src: "/static/oxjs/build/png/ox.ui/videoMarker" + titleCase + ".png" - }) - .appendTo(that.$element); - setMarkerPoint(i); - }); - - function addLine(i) { - self.$lines[i] = new Ox.Element("div") - .css({ - top: i * (self.height + self.margin) + "px", - width: self.options.width + "px" - }) - .appendTo(that); - self.$images[i] = $("") - .addClass("OxTimelineSmallImage") - .attr({ - src: "/" + self.options.videoId + "/timelines/timeline.16." + 0 + ".png" - }) - .css({ - marginLeft: (-i * self.options.width) + "px" - }) - .appendTo(self.$lines[i].$element); - self.$subtitles[i] = $("") - .attr({ - src: self.subtitlesImageURL - }) - .css({ - marginLeft: (-i * self.options.width) + "px" - }) - .appendTo(self.$lines[i].$element); - } - - function getSubtitle(position) { - var subtitle = null; - $.each(self.options.subtitles, function(i, v) { - if (v["in"] <= position && v["out"] >= position) { - subtitle = v; - return false; - } - }); - return subtitle; - } - - function getSubtitlesImageURL() { - var height = 18, - width = Math.ceil(self.options.duration), - $canvas = $("") - .attr({ - height: height, - width: width - }), - canvas = $canvas[0], - context = canvas.getContext("2d"), - imageData = context.createImageData(width, height), - data = imageData.data; - $.each(self.options.subtitles, function(i, v) { - var color = matches.indexOf(i) > -1 ? [255, 255, 0] : [255, 255, 255] - $.each(Ox.range( - Math.round(v["in"]), - Math.round(v["out"]) + 1 - ), function(i, x) { - $.each(Ox.range(0, 18), function(i, y) { - var index = x * 4 + y * 4 * width; - data[index] = color[0]; - data[index + 1] = color[1]; - data[index + 2] = color[2]; - data[index + 3] = (y == 0 || y == 17) ? 255 : 128 - }); - }); - }); - context.putImageData(imageData, 0, 0); - return canvas.toDataURL() - } - - function mousedown(e) { - var offset = that.offset(), - x = e.clientX, - y = e.clientY - //FIXME: this might still be broken in opera according to http://acko.net/blog/mouse-handling-and-absolute-positions-in-javascript - self.options.position = e.offsetX?e.offsetX:e.clientX-$(e.target).offset().left; - setPosition(); - that.triggerEvent("change", { - position: self.options.position - }); - $window.mousemove(function(e) { - if ($(e.target).is("img")) { - self.options.position = e.offsetX?e.offsetX:e.clientX-$(e.target).offset().left; - setPosition(); - that.triggerEvent("change", { - position: self.options.position - }); - } - }); - $window.one("mouseup", function() { - $window.unbind("mousemove"); - }) - e.preventDefault(); - } - - function mouseleave(e) { - self.$tooltip.hide(); - } - - function mousemove(e) { - //FIXME: this might still be broken in opera according to http://acko.net/blog/mouse-handling-and-absolute-positions-in-javascript - var position = e.offsetX?e.offsetX:e.clientX-$(e.target).offset().left, - subtitle = getSubtitle(position); - Ox.print("position", position, e) - self.$tooltip = new Ox.Tooltip({ - title: subtitle ? - "" + - highlight(subtitle.text, self.options.find).replace(/\n/g, "
") + "

" + - Ox.formatDuration(subtitle["in"], 3) + " - " + Ox.formatDuration(subtitle["out"], 3) : - Ox.formatDuration(position) - }) - .css({ - textAlign: "center" - }) - .show(e.clientX, e.clientY); - } - - function setMarker() { - self.$markerPosition - .css({ - left: (self.options.position % self.options.width) + "px", - top: (parseInt(self.options.position / self.options.width) * (self.height + self.margin) + 2) + "px", - }); - } - - function setMarkerPoint(i) { - var position = self.options.points[i]; - self.$markerPoint[i] - .css({ - left: (position % self.options.width) + "px", - top: (parseInt(position / self.options.width) * (self.height + self.margin) + 16) + "px", - }); - } - - function setPosition() { - self.options.position = Ox.limit(self.options.position, 0, self.options.duration); - setMarker(); - } - - function setWidth() { - self.lines = Math.ceil(self.options.duration / self.options.width); - $.each(Ox.range(self.lines), function(i, v) { - if (self.$lines[i]) { - self.$lines[i].css({ - width: self.options.width + "px" - }); - self.$images[i].css({ - marginLeft: (-i * self.options.width) + "px" - }); - self.$subtitles[i].css({ - marginLeft: (-i * self.options.width) + "px" - }); - } else { - addLine(i); - } - }); - while (self.$lines.length > self.lines) { - self.$lines[self.$lines.length - 1].remove(); - self.$lines.pop(); - } - setMarker(); - setMarkerPoint(0); - setMarkerPoint(1); - } - - self.onChange = function(key, value) { - if (key == "points") { - setMarkerPoint(0); - setMarkerPoint(1); - } else if (key == "position") { - setPosition(); - } else if (key == "width") { - setWidth(); - } - }; - - return that; - - }; - - Ox.VideoPlayer = function(options, self) { - - var self = self || {}, - that = new Ox.Element("div", self) - .defaults({ - find: "", - height: 0, - points: [0, 0], - position: 0, - posterFrame: 0, - 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; - - self.$video = $("