135 lines
5.6 KiB
JavaScript
135 lines
5.6 KiB
JavaScript
// TODO: Do we need to detach events when the page is changed?
|
|
App.VideoAnalysis = {
|
|
initPlayerWithAnalysis: function(videoElement, bookmarkData) {
|
|
// Initialize the video player
|
|
var player = App.VideoPlayer.init(videoElement);
|
|
|
|
// Attach custom keyboard shortcuts
|
|
var oldBindKeyEvents = player.core.mediaControl.bindKeyEvents.bind(player.core.mediaControl);
|
|
var oldUnbindKeyEvents = player.core.mediaControl.unbindKeyEvents.bind(player.core.mediaControl);
|
|
player.core.mediaControl.bindKeyEvents = function() {
|
|
oldBindKeyEvents();
|
|
player.core.mediaControl.bindKeyAndShow('d', function() {
|
|
var markersPlugin = player.getPlugin("markers-plugin");
|
|
markersPlugin.getAll().forEach(function(marker, index) {
|
|
if ( Math.abs(marker.getTime() - player.getCurrentTime()) < 2 ) {
|
|
markersPlugin.removeMarker(marker);
|
|
}
|
|
});
|
|
});
|
|
}
|
|
player.core.mediaControl.unbindKeyEvents = function() {
|
|
console.log("Unbinding key events");
|
|
oldUnbindKeyEvents();
|
|
if (player.core.mediaControl.kibo) {
|
|
player.core.mediaControl.kibo.off('d')
|
|
}
|
|
}
|
|
|
|
function ClassyMarker(time, tooltipText, cssClass) {
|
|
this._cssClass = cssClass || null;
|
|
ClapprMarkersPlugin.StandardMarker.call(this, time, tooltipText);
|
|
}
|
|
ClassyMarker.prototype = Object.create(ClapprMarkersPlugin.StandardMarker.prototype);
|
|
ClassyMarker.prototype.constructor = ClassyMarker;
|
|
ClassyMarker.prototype._buildMarkerEl = function() {
|
|
var $marker = Clappr.$('<div />').addClass('standard-marker' + ' ' + this._cssClass);
|
|
$marker.append(Clappr.$('<div />').addClass('standard-marker-inner'));
|
|
return $marker;
|
|
}
|
|
|
|
function RemovableMarker(time, tooltipText, cssClass, url) {
|
|
this._url = url || null;
|
|
ClassyMarker.call(this, time, tooltipText, cssClass);
|
|
}
|
|
RemovableMarker.prototype = Object.create(ClassyMarker.prototype);
|
|
RemovableMarker.prototype.constructor = RemovableMarker;
|
|
RemovableMarker.prototype.onDestroy = function() {
|
|
$.ajax({ url: this.source._url, type: "DELETE", headers: { 'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content') } });
|
|
};
|
|
|
|
// Add existing bookmarks to the timeline and set up handlers for adding new bookmarks
|
|
var addBookmark = function(bookmark) {
|
|
var markers = player.getPlugin("markers-plugin");
|
|
// TODO: Move the remove URL into a serializer?
|
|
var marker = new RemovableMarker(Number(bookmark.time_elapsed), bookmark.notes + " (Press 'D' to delete)", "bookmark-marker", "/bookmarks/" + bookmark.id);
|
|
markers.addMarker(marker);
|
|
}
|
|
bookmarkData.forEach(function(bookmark, index) {
|
|
addBookmark(bookmark)
|
|
});
|
|
$(document).on("addBookmark-" + $(videoElement).data("video-id"), function(event, bookmark) {
|
|
addBookmark(bookmark);
|
|
});
|
|
|
|
// TODO: Where to put this??
|
|
player.on("timeupdate", function(event) {
|
|
$("[data-ujs-target=bookmark-form] input[name='bookmark[time_elapsed]']").val(event.current);
|
|
$("[data-ujs-target=unreleased-appearance-form] input[name='unreleased_appearance[time_elapsed]']").val(event.current);
|
|
$("[data-ujs-target=video-release-confirmation-form] input[name='video_release_confirmation[time_elapsed]']").val(event.current);
|
|
$("[data-ujs-target=audio-confirmation-form] input[name='audio_confirmation[time_elapsed]']").val(event.current);
|
|
$("[data-ujs-target=graphics-element-form] input[name='graphics_element[time_elapsed]']").val(event.current);
|
|
$("[data-ujs-target=edl-event-form] input[name='edl_event[time_elapsed]']").val(event.current);
|
|
});
|
|
|
|
// // Add event handler to show recommendations as the video plays
|
|
player.on("timeupdate", function(event) {
|
|
$("#suggested_matches [data-time]").each(function(index, item) {
|
|
var time = $(item).data("time");
|
|
if (event.current > time) {
|
|
$(item).show();
|
|
} else {
|
|
$(item).hide();
|
|
}
|
|
});
|
|
$("#graphics_elements_matches [data-time]").each(function(index, item) {
|
|
var time = $(item).data("time");
|
|
if (event.current > time) {
|
|
$(item).show();
|
|
} else {
|
|
$(item).hide();
|
|
}
|
|
});
|
|
$("#audio_matches [data-time]").each(function(index, item) {
|
|
var time = $(item).data("time");
|
|
if (event.current > time) {
|
|
$(item).show();
|
|
} else {
|
|
$(item).hide();
|
|
}
|
|
});
|
|
});
|
|
|
|
$(document).on("click", "#seek_button", () => {
|
|
try {
|
|
const timecode = new Timecode($("#seek_input").val(), 30);
|
|
player.seek(timecode.frameCount / timecode.frameRate);
|
|
} catch(e) {
|
|
$("#seek_input").val("")
|
|
}
|
|
});
|
|
$(document).on('click',"[data-behavior~=seekable-timecode]", function(e){
|
|
e.preventDefault();
|
|
const timeCodeText = e.target.innerText;
|
|
let extractedTime = timeCodeText;
|
|
const startOfTimeCode = 8; // MOV TC: 00:00....
|
|
if (timeCodeText.startsWith('MOV')){
|
|
extractedTime = timeCodeText.slice(startOfTimeCode);
|
|
}
|
|
const timeCode = new Timecode(extractedTime, 30);
|
|
player.seek(timeCode.frameCount / timeCode.frameRate);
|
|
});
|
|
}
|
|
}
|
|
|
|
$(document).on("click", "#go_button", function () {
|
|
const timecode = $("#go_to").val()
|
|
const $edlEvent = $(`[data-timecode-in='${timecode}']`).first()
|
|
const edlEventContainer = $("#edl_events_list").parent();
|
|
|
|
if ($edlEvent.length > 0) {
|
|
edlEventContainer.scrollTop($edlEvent.offset().top - edlEventContainer.offset().top + edlEventContainer.scrollTop())
|
|
} else {
|
|
$("#go_to").val("")
|
|
}
|
|
}); |