VideoInpainterHF / app /static /slideshow.js
Kevin L
Initial commit
5fd3fc6
Raw History Blame Contribute Delete
5.14 kB
class Slideshow {
constructor(num_frames, fps, video_id) {
this.num_frames = num_frames;
this.fps = fps;
this.video_id = video_id;
this._slides = document.getElementById('slideshow');
this.value = document.getElementById('frames_display');
this.is_paused = true;
this._current_frame = 0;
this.playbutton = document.getElementById('play_button');
this._frames = [];
this._masks = [];
// Add options to datalist, which adds tick marks below the input slider
this._slider = document.getElementById('slider');
// Remove tick marks if there are too many
let num_ticks = (this.num_frames > 200) ? 0 : this.num_frames;
let markers = document.getElementById("markers");
for (let i = 0; i < num_ticks; i++) {
let tick = document.createElement('div');
tick.classList.add('tick');
tick.setAttribute('value', i);
markers.appendChild(tick);
}
// Called when slider is being moved
this._slider.addEventListener("change", (event) => {
this._current_frame = parseInt(event.target.value);
this.update_slideshow();
this.reset_interaction();
});
this.playbutton.addEventListener('click', this.play_or_pause.bind(this));
setInterval(this.play_slideshow.bind(this), 1 / this.fps * 1000);
}
load_masks() {
let promise = Promise.resolve(); // Start with a resolved promise
for (let i = 0; i < num_frames; i++) {
promise = promise
.then(() => fetch('/mask/' + String(this.video_id) + '/' + String(i)))
.then(response => response.blob())
.then(blob => {
const blob_url = URL.createObjectURL(blob);
this._masks[i] = blob_url;
});
}
// Return the final promise that resolves when all fetches are complete
return promise;
}
set_current_mask() {
let promise = Promise.resolve(); // Start with a resolved promise
promise = promise
.then(() => fetch('/mask/' + String(this.video_id) + '/' + String(this._current_frame)))
.then(response => response.blob())
.then(blob => {
const blob_url = URL.createObjectURL(blob);
this._masks[this._current_frame] = blob_url;
});
// Return the final promise that resolves when all fetches are complete
return promise;
}
preload_frames() {
let promise = Promise.resolve(); // Start with a resolved promise
for (let i = 0; i < num_frames; i++) {
promise = promise
.then(() => fetch('/frame/' + String(this.video_id) + '/' + String(i)))
.then(response => response.blob())
.then(blob => {
const blob_url = URL.createObjectURL(blob);
this._frames.push(blob_url);
});
}
// Return the final promise that resolves when all fetches are complete
return promise;
}
async initialize() {
await this.preload_frames();
await this.load_masks();
// Set first frame
this.update_slideshow();
}
reset_interaction() {
// Reset interactions in manager
fetch('/reset_interaction', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({video_id: this.video_id})
}).catch(error => {
console.error('Error:', error);
});
}
set_seekbar_value(n) {
this._slider.value = n;
}
play_or_pause() {
this.is_paused = !this.is_paused;
}
/*
Simulate video playing by changing the image
*/
update_slideshow() {
throw new Error('Not implemented');
}
play_slideshow() {
if (!this.is_paused) {
this._current_frame++;
if (this._current_frame > this.num_frames - 1) {
this._current_frame = 0;
}
this.set_seekbar_value(this._current_frame);
this.update_slideshow();
}
}
highlight_tick() {
let tick = document.querySelector(`.tick[value='${this.current_frame}']`);
tick.classList.add('highlight_tick');
}
remove_tick_highlight() {
let tick = document.querySelector(`.tick[value='${this.current_frame}']`);
tick.classList.remove('highlight_tick');
}
remove_all_highlights() {
let highlighted_ticks = document.querySelectorAll('.highlight_tick');
highlighted_ticks.forEach(t => t.classList.remove('highlight_tick'));
}
get current_frame() {
return this._current_frame;
}
get slides() {
return this._slides;
}
get slider() {
return this._slider;
}
get frames() {
return this._frames;
}
get masks() {
return this._masks;
}
}