auto-foley-editor / custom_script.js
TMBoeren's picture
Initial commit
df8fe58
raw
history blame
4.86 kB
function manageTimeBar(elemId, time) {
if (!window.visTimelineInstances) {
console.error(`Timeline instances collection not found`);
return;
}
const timeline = window.visTimelineInstances[elemId];
if (!timeline) {
console.error(`Timeline instance ${elemId} not found`);
return;
}
if (!window.customTimeBarIds) {
window.customTimeBarIds = {};
}
try {
timeline.setCustomTime(time, elemId);
} catch (e) {
timeline.addCustomTime(time, elemId);
}
}
function setTimeBarDirect(elemId, time) {
manageTimeBar(elemId, time);
}
function setTimeBarNormalized(elemId, start, end, normalizedPos) {
const time = start + (end - start) * normalizedPos;
manageTimeBar(elemId, time);
}
class VideoTimelineSync {
constructor(videoId, timelineId, trackLengthItemId) {
this.timelineId = timelineId;
try {
const trackLengthItemData = getTimelineItemData(timelineId, trackLengthItemId);
if (trackLengthItemData != null) {
const trackLengthStart = trackLengthItemData.start;
const trackLengthEnd = trackLengthItemData.end;
this.trackLength = trackLengthEnd - trackLengthStart;
}
} catch (error) {
console.error('Error setting timeline video sync:', error);
return;
}
const container = document.getElementById(videoId);
if (!container) {
console.error('Video container not found');
return;
}
this.progressElement = container.querySelector('progress');
if (!this.progressElement) {
console.error('Progress element not found');
return;
}
this.setupProgressObserver();
}
setupProgressObserver() {
// Create mutation observer to watch for value changes of the progress element
this.observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.type === 'attributes' && mutation.attributeName === 'value') {
this.onProgressUpdate();
}
});
});
// Observe the progress element for value changes
this.observer.observe(this.progressElement, {
attributes: true,
attributeFilter: ['value']
});
}
onProgressUpdate() {
const value = this.progressElement.value;
if (value === undefined || value === null) return;
// Value is already normalized (between 0 and 1)
this.syncTimeBarToPlayback(value);
}
syncTimeBarToPlayback(normalizedPosition) {
const timeline = window.visTimelineInstances[this.timelineId];
if (timeline) {
setTimeBarNormalized(this.timelineId, 0, this.trackLength, normalizedPosition);
}
}
cleanup() {
// Disconnect observer
if (this.observer) {
this.observer.disconnect();
this.observer = null;
}
}
}
function initVideoSync(videoId, timelineId, trackLengthItemId) {
try {
// Initialize syncs container if it doesn't exist
if (!window.timelineSyncs) {
window.timelineSyncs = {};
}
// Cleanup existing sync if any
if (window.timelineSyncs[timelineId]) {
window.timelineSyncs[timelineId].cleanup();
}
// Create new sync instance
window.timelineSyncs[timelineId] = new VideoTimelineSync(videoId, timelineId, trackLengthItemId);
} catch (error) {
console.error('Error initializing video sync:', error);
}
return null;
}
function getTimelineItemData(timelineId, itemId) {
const timeline = window.visTimelineInstances[timelineId];
if (!timeline) {
console.error(`Timeline instance ${timelineId} not found`);
return null;
}
const items = timeline.itemSet?.items;
if (!items) {
console.error('Timeline items not found');
return null;
}
const item = items[itemId];
if (!item) {
return null;
}
const itemData = item.data;
if (!itemData) {
console.error('Track length item data not found');
return null;
}
return item.data;
}
function setTimelineWindowToItemLength(timelineId, itemId) {
const itemData = getTimelineItemData(timelineId, itemId);
if (!itemData) {
return;
}
try {
const timeline = window.visTimelineInstances[timelineId];
console.log(itemData.end);
timeline.setWindow(itemData.start, new Date(itemData.end.getTime() + 20), {animation: false});
} catch (error) {
console.error('Error setting timeline window:', error);
}
}