$(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 = $("<div>") .css({ left: self.center + "px" }) .appendTo(that.$element) $.each(self.options.subtitles, function(i, v) { self.$subtitles[i] = $("<div>") .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] = $("<img>") .addClass("OxCut") .attr({ src: "/static/oxjs/build/png/ox.ui/videoMarkerCut.png" }) .css({ left: (v * self.fps) + "px" }) .appendTo(self.$timeline) }); self.$markerPosition = $("<img>") .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] = $("<img>") .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] = $("<img>") .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 = $("<img>") .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] = $("<img>") .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] = $("<img>") .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] = $("<img>") .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 = $("<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 ? "<span class=\"OxBright\">" + highlight(subtitle.text, self.options.find).replace(/\n/g, "<br/>") + "</span><br/>" + 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 = $("<video preload=auto>") .css({ height: self.options.height + "px", width: self.options.width + "px" }) .appendTo(that.$element); self.video = self.$video[0]; var other = $('video[src='+self.options.url+']')[0]; if(self.video.mozLoadFrom && other) self.video.mozLoadFrom(other); else self.video.src = self.options.url; 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 = {} $.each(["in", "out"], function(i, point) { self.$markerPoint[point] = {}; $.each(["top", "bottom"], function(i, edge) { var titleCase = Ox.toTitleCase(point) + Ox.toTitleCase(edge); self.$markerPoint[point][edge] = $("<img>") .addClass("OxMarkerPoint OxMarker" + titleCase) .attr({ src: "/static/oxjs/build/png/ox.ui/videoMarker" + titleCase + ".png" }) .hide() .appendTo(that.$element); if (self.options.points[point == "in" ? 0 : 1] == 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); } 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) }) .css({ float: "right", }) .appendTo(self.$controls) self.$positionInput.css({ width: "98px" }); // 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" }).addClass("foo"); }); self.$loadingIcon = new Ox.LoadingIcon() .css({ position: "absolute", left: (parseInt(self.options.width / 2) - 8) + "px", top: (parseInt(self.options.height / 2) - 8) + "px" }) .appendTo(that) .start(); self.loadInterval = setInterval(function() { if (self.video.readyState) { clearInterval(self.loadInterval); self.$loadingIcon.stop(); setPosition(); } }, 50); function getSubtitle() { var subtitle = ""; $.each(self.options.subtitles, function(i, v) { if (v["in"] <= self.options.position && v["out"] > self.options.position) { subtitle = v.text; return false; } }); return subtitle; } function goToPoint() { that.triggerEvent("change", { position: self.options.points[self.options.type == "in" ? 0 : 1] }); } function playing() { self.options.position = self.video.currentTime; if (self.video.ended) { self.$playButton.trigger("click"); } if (self.playingInToOut && self.options.position >= self.options.points[1]) { self.$playButton.trigger("click"); self.options.position = self.options.points[1]; } setMarkers(); setSubtitle(); self.$positionInput.options({ value: Ox.formatDuration(self.options.position) }); that.triggerEvent("change", { position: self.options.position }); } function setHeight() { that.css({ height: (self.options.height + 16) + "px" }); self.$video.css({ height: self.options.height + "px" }); setSubtitleSize(); } function setMarkers() { self.options.position == self.options.posterFrame ? self.$markerFrame.show() : self.$markerFrame.hide(); $.each(self.$markerPoint, function(point, markers) { $.each(markers, function(edge, 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() { self.video.currentTime = self.options.position; setMarkers(); setSubtitle(); self.$positionInput.options({ value: Ox.formatDuration(self.options.position) }); } function setSubtitle() { var subtitle = getSubtitle(); if (subtitle != self.subtitle) { self.subtitle = subtitle; self.$subtitle.html(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.$video.css({ width: self.options.width + "px" }); setSubtitleSize(); } function toggleMute() { self.video.muted = !self.video.muted; } function togglePlay() { self.video.paused ? that.play() : that.pause(); } 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.muted = true; return that; }; that.pause = function() { self.video.pause(); clearInterval(self.playInterval); self.playingInToOut = false; return that; }; that.play = function() { self.video.play(); self.playInterval = setInterval(playing, 40); return that; }; that.playInToOut = function() { self.options.position = self.options.points[0]; setPosition(); Ox.print("sop", self.options.position, self.options.points); self.playingInToOut = true; self.video.paused && self.$playButton.trigger("click"); 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.muted = false; return that; }; return that; } $.getJSON("/" + videoId + "/data/subtitles.json", function(data) { subtitles = data; $.getJSON("/" + videoId + "/data/cuts.json", function(data) { cuts = data; $main = new Ox.SplitPanel({ elements: [ { element: $lists = new Ox.Container({ id: "lists" }), resizable: true, resize: [128, 192, 256], size: 192 }, { element: $panel = new Ox.SplitPanel({ elements: [ { element: $annotation = new Ox.Container({ id: "annotation" }), resizable: true, resize: [128, 192, 256], size: 192 }, { element: $editor = new Ox.Editor({ cuts: cuts, duration: duration, find: find, id: "editor", largeTimeline: true, matches: matches, points: points, position: position, posterFrame: posterFrame, subtitles: subtitles, videoHeight: videoHeight, videoId: videoId, videoWidth: videoWidth, videoSize: "large", width: pageWidth }) }, ], id: "panel", orientation: "horizontal", }) } ], id: "main", orientation: "horizontal" }).appendTo($body); }); }); }); function highlight(txt, str) { return str ? txt.replace( new RegExp("(" + str + ")", "ig"), "<span class=\"OxHighlight\">$1</span>" ) : txt; } $window.resize(function() { $editor.options({ width: $document.width() - 384 -2 }); //resizeVideoPlayers($window.width() - 384 - 2); }) Ox.theme("modern") });