mediapipe/mediapipe2/examples/desktop/youtube8m/viewer/static/main.js
2021-06-10 23:01:19 +00:00

218 lines
5.7 KiB
JavaScript

/**
* @license
* Copyright 2019 The MediaPipe Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
const STATE_PLAYER=0;
const STATE_COVER=1;
const STATE_SPINNER=2;
/**
* Looks up the value of a url parameter.
*
* @param {string} param The name of the parameter.
* @return {?string} The parameter value or null if there is no such parameter.
*/
var getUrlParameter = function(param) {
const url = decodeURIComponent(window.location.search.substring(1));
const url_parts = url.split('&');
for (var i = 0; i < url_parts.length; i++) {
const param_name = url_parts[i].split(/=(.*)/);
if (param_name[0] === param) {
return param_name[1] === undefined ? null : param_name[1];
}
}
};
/**
* Sets the fields in the form to match the values of the URL parameters.
*/
const updateFormFromURL = function() {
const form_elements = document.getElementById('form').elements;
const url = decodeURIComponent(window.location.search.substring(1));
const url_parts = url.split('&');
for (var i = 0; i < url_parts.length; i++) {
const p = url_parts[i].split(/=(.*)/);
if (p.length >= 2) {
if (form_elements[p[0]]) {
form_elements[p[0]].value = decodeURIComponent(p[1]);
}
}
}
};
let player = null;
let intervalID = undefined;
let entries = [];
/**
* Constructs the embedded YouTube player.
*/
window.onYouTubeIframeAPIReady = () => {
player = new YT.Player('ytplayer', {
events: {
'onReady': onPlayerReady,
'onStateChange': onStateChange
}
});
};
/**
* Listens for YouTube video events. When video is playing, periodically checks
* the time signature and updates the feedback with labels. When video stops,
* shuts off interval timer to save cycles.
* @param {!Event} event YouTube API Event.
*/
function onStateChange(event) {
if (event.data === 1) {
// Youtube switched to playing.
intervalID = setInterval(function(){
const currentTime = player.getCurrentTime();
let winner = undefined;
let first = undefined;
for (entry of entries) {
if (!first) {
first = entry.labels;
}
if (entry.time < currentTime) {
winner = entry.labels;
} else {
break;
}
}
if (!winner) {
winner = first;
}
const threshold =
document.getElementById('form').elements['threshold'].value;
let message = "";
for (var label of winner) {
if (label.score >= threshold) {
message = `${message}${label.label} (score: ${label.score})\n`;
}
}
$("textarea#feedback").val(message);
});
} else {
if (intervalID) {
clearInterval(intervalID);
}
}
}
/**
* Turns elements of the player on and off to reflect the state of the "app".
* @param {number} state One of STATE_COVER | STATE_SPINNER | STATE_PLAYER.
*/
function showState(state) {
switch(state) {
case STATE_COVER:
$('#cover').show();
$('#spinner').hide();
$('#ytplayer').hide();
break;
case STATE_SPINNER:
$('#cover').hide();
$('#spinner').show();
$('#ytplayer').hide();
break;
case STATE_PLAYER:
default:
$('#cover').hide();
$('#spinner').hide();
$('#ytplayer').show();
break;
}
}
/**
* Hide error field and clear its message.
*/
function hideError() {
$('#error_msg').css("visibility", "hidden").text('');
}
/**
* Set the error to visible and set its message.
* @param {string} msg Error message as a string.
*/
function showError(msg) {
$('#error_msg').css("visibility", "visible").text(msg);
}
/**
* Privides numeric feedback for the slider.
*/
function connectSlider() {
$('#threshold_label').text(
`Score Threshold (${$('#threshold')[0].value})`);
$('#threshold').on('input', () => {
$('#threshold_label').text(
`Score Threshold (${$('#threshold')[0].value})`);
});
$('#segments_label').text(
`Segment Size (${$('#segments')[0].value})`);
$('#segments').on('input', () => {
$('#segments_label').text(
`Segment Size (${$('#segments')[0].value})`);
});
}
/**
* Retrieve video information from backend.
* @param {string} filePath name of a tfrecord file.
* @param {number} segments desired number of segments (1-300)
*/
function fetchVideo(filePath, segments) {
const url = "/video?file=" + filePath + "&segments=" + segments;
$.ajax({
url: url,
success: function(result) {
const videoId = result["video_id"];
player.loadVideoById(videoId);
entries = result['entries'];
showState(STATE_PLAYER);
},
error: (err) => {
showState(STATE_COVER);
console.log(err);
showError(err.responseText);
},
datatype: "json"
});
}
/**
* Called when the embedded YouTube player has finished loading. It loads the
* requested video into the player and calls the golden6_viewer API to retrieve
* the frame-level data for that video.
*/
function onPlayerReady() {
const filePath = getUrlParameter('file') || "";
const segments = parseInt(getUrlParameter('segments')) || 0;
updateFormFromURL();
hideError();
connectSlider();
if (!filePath) {
return;
}
showState(STATE_SPINNER);
fetchVideo(filePath, segments);
}