// 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.$('
').addClass('standard-marker' + ' ' + this._cssClass); $marker.append(Clappr.$('').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("") } });