Run Prettier on other Thrimbletrimmer files

It had not been run in previous PRs
pull/449/head
ElementalAlchemist 3 weeks ago committed by Christopher Usher
parent c8899f5133
commit fc82b2b17f

@ -5,7 +5,7 @@
<title>VST Video Editor</title>
<link rel="stylesheet" href="styles/thrimbletrimmer.css" />
<link rel="stylesheet" href="styles/jcrop.css">
<link rel="stylesheet" href="styles/jcrop.css" />
<script src="scripts/hls.min.js"></script>
<script src="scripts/luxon.min.js"></script>
@ -258,15 +258,17 @@
<div class="video-info-thumbnail-mode-options" id="video-info-thumbnail-position-options">
<details>
<summary>Advanced Templating Options</summary>
Crop specifies the region of the video frame to capture. <br/>
Location specifies the region within the template image where the cropped image will be placed. <br/>
Regions are given as pixel coordinates of the top-left and bottom-right corners. <br/>
Note that if the regions are different sizes, the image will be stretched. <br/>
Crop specifies the region of the video frame to capture. <br />
Location specifies the region within the template image where the cropped image will
be placed. <br />
Regions are given as pixel coordinates of the top-left and bottom-right corners.
<br />
Note that if the regions are different sizes, the image will be stretched. <br />
<button id="video-info-thumbnail-template-source-image-update">
Update Source Images
</button>
<br/>
<br />
<div class="video-info-thumbnail-advanced-crop-flex-wrapper">
<div class="video-info-thumbnail-advanced-crop-flex-item">
@ -274,23 +276,41 @@
id="video-info-thumbnail-template-video-source-image"
class="hidden"
alt="Thumbnail preview image"
height="360" width="640"
height="360"
width="640"
/>
<br/>
<br />
Crop:
<input type="text" class="video-info-thumbnail-position" id="video-info-thumbnail-crop-0" />
<input type="text" class="video-info-thumbnail-position" id="video-info-thumbnail-crop-1" />
<input
type="text"
class="video-info-thumbnail-position"
id="video-info-thumbnail-crop-0"
/>
<input
type="text"
class="video-info-thumbnail-position"
id="video-info-thumbnail-crop-1"
/>
to
<input type="text" class="video-info-thumbnail-position" id="video-info-thumbnail-crop-2" />
<input type="text" class="video-info-thumbnail-position" id="video-info-thumbnail-crop-3" />
<br/>
<input
type="text"
class="video-info-thumbnail-position"
id="video-info-thumbnail-crop-2"
/>
<input
type="text"
class="video-info-thumbnail-position"
id="video-info-thumbnail-crop-3"
/>
<br />
</div>
<div class="video-info-thumbnail-advanced-crop-flex-item hidden" id="video-info-thumbnail-aspect-ratio-controls">
<div
class="video-info-thumbnail-advanced-crop-flex-item hidden"
id="video-info-thumbnail-aspect-ratio-controls"
>
<div class="video-info-thumbnail-advanced-crop-flex-column">
<div>
Aspect Ratio
</div>
<div>Aspect Ratio</div>
<div>
<button id="video-info-thumbnail-aspect-ratio-match-right">
--Match-&gt;
@ -303,7 +323,7 @@
</div>
<div>
<label>
<input type="checkbox" id="video-info-thumbnail-lock-aspect-ratio">
<input type="checkbox" id="video-info-thumbnail-lock-aspect-ratio" />
Lock
</label>
</div>
@ -315,19 +335,35 @@
id="video-info-thumbnail-template-overlay-image"
class="hidden"
alt="Thumbnail preview image"
height="360" width="640"
height="360"
width="640"
/>
<br/>
<br />
Location:
<input type="text" class="video-info-thumbnail-position" id="video-info-thumbnail-location-0" />
<input type="text" class="video-info-thumbnail-position" id="video-info-thumbnail-location-1" />
<input
type="text"
class="video-info-thumbnail-position"
id="video-info-thumbnail-location-0"
/>
<input
type="text"
class="video-info-thumbnail-position"
id="video-info-thumbnail-location-1"
/>
to
<input type="text" class="video-info-thumbnail-position" id="video-info-thumbnail-location-2" />
<input type="text" class="video-info-thumbnail-position" id="video-info-thumbnail-location-3" />
<br/>
<input
type="text"
class="video-info-thumbnail-position"
id="video-info-thumbnail-location-2"
/>
<input
type="text"
class="video-info-thumbnail-position"
id="video-info-thumbnail-location-3"
/>
<br />
</div>
</div>
</details>
</div>
<div

@ -222,9 +222,11 @@ window.addEventListener("DOMContentLoaded", async (event) => {
}
}
document.getElementById("range-definition-chapter-marker-first-description").addEventListener("input", (event) => {
validateChapterDescription(event.target);
});
document
.getElementById("range-definition-chapter-marker-first-description")
.addEventListener("input", (event) => {
validateChapterDescription(event.target);
});
document.getElementById("video-info-title").addEventListener("input", (event) => {
validateVideoTitle();
document.getElementById("video-info-title-abbreviated").innerText =
@ -269,7 +271,9 @@ window.addEventListener("DOMContentLoaded", async (event) => {
document
.getElementById("video-info-thumbnail-template-source-image-update")
.addEventListener("click", async (_event) => {
const videoFrameImageElement = document.getElementById("video-info-thumbnail-template-video-source-image");
const videoFrameImageElement = document.getElementById(
"video-info-thumbnail-template-video-source-image",
);
const timeEntryElement = document.getElementById("video-info-thumbnail-time");
const imageTime = wubloaderTimeFromVideoHumanTime(timeEntryElement.value);
@ -285,55 +289,84 @@ window.addEventListener("DOMContentLoaded", async (event) => {
videoFrameImageElement.src = `/frame/${globalStreamName}/source.png?${videoFrameQuery}`;
videoFrameImageElement.classList.remove("hidden");
const templateImageElement = document.getElementById("video-info-thumbnail-template-overlay-image");
const templateImageElement = document.getElementById(
"video-info-thumbnail-template-overlay-image",
);
templateImageElement.src = `/thrimshim/template/${imageTemplate}.png`;
templateImageElement.classList.remove("hidden");
const aspectRatioControls = document.getElementById("video-info-thumbnail-aspect-ratio-controls");
const aspectRatioControls = document.getElementById(
"video-info-thumbnail-aspect-ratio-controls",
);
aspectRatioControls.classList.remove("hidden");
createTemplateCropWidgets();
});
document.getElementById("video-info-thumbnail-crop-0").addEventListener("input", updateTemplateCropWidgets);
document.getElementById("video-info-thumbnail-crop-1").addEventListener("input", updateTemplateCropWidgets);
document.getElementById("video-info-thumbnail-crop-2").addEventListener("input", updateTemplateCropWidgets);
document.getElementById("video-info-thumbnail-crop-3").addEventListener("input", updateTemplateCropWidgets);
document.getElementById("video-info-thumbnail-location-0").addEventListener("input", updateTemplateCropWidgets);
document.getElementById("video-info-thumbnail-location-1").addEventListener("input", updateTemplateCropWidgets);
document.getElementById("video-info-thumbnail-location-2").addEventListener("input", updateTemplateCropWidgets);
document.getElementById("video-info-thumbnail-location-3").addEventListener("input", updateTemplateCropWidgets);
document.getElementById("video-info-thumbnail-lock-aspect-ratio").addEventListener("change", updateTemplateCropAspectRatio);
document.getElementById("video-info-thumbnail-aspect-ratio-match-right").addEventListener("click", function(){
// Calculate and copy the aspect ratio from the video field to the template
const videoFieldX1 = document.getElementById("video-info-thumbnail-crop-0");
const videoFieldY1 = document.getElementById("video-info-thumbnail-crop-1");
const videoFieldX2 = document.getElementById("video-info-thumbnail-crop-2");
const videoFieldY2 = document.getElementById("video-info-thumbnail-crop-3");
const videoFieldAspectRatio = (videoFieldX2.value-videoFieldX1.value)/(videoFieldY2.value-videoFieldY1.value);
templateStage.setOptions({aspectRatio: videoFieldAspectRatio});
// Re-apply the locked/unlocked status
updateTemplateCropAspectRatio();
});
document
.getElementById("video-info-thumbnail-crop-0")
.addEventListener("input", updateTemplateCropWidgets);
document
.getElementById("video-info-thumbnail-crop-1")
.addEventListener("input", updateTemplateCropWidgets);
document
.getElementById("video-info-thumbnail-crop-2")
.addEventListener("input", updateTemplateCropWidgets);
document
.getElementById("video-info-thumbnail-crop-3")
.addEventListener("input", updateTemplateCropWidgets);
document
.getElementById("video-info-thumbnail-location-0")
.addEventListener("input", updateTemplateCropWidgets);
document
.getElementById("video-info-thumbnail-location-1")
.addEventListener("input", updateTemplateCropWidgets);
document
.getElementById("video-info-thumbnail-location-2")
.addEventListener("input", updateTemplateCropWidgets);
document
.getElementById("video-info-thumbnail-location-3")
.addEventListener("input", updateTemplateCropWidgets);
document.getElementById("video-info-thumbnail-aspect-ratio-match-left").addEventListener("click", function(){
// Calculate and copy the aspect ratio from the template to the video field
const templateFieldX1 = document.getElementById("video-info-thumbnail-location-0");
const templateFieldY1 = document.getElementById("video-info-thumbnail-location-1");
const templateFieldX2 = document.getElementById("video-info-thumbnail-location-2");
const templateFieldY2 = document.getElementById("video-info-thumbnail-location-3");
const templateFieldAspectRatio = (templateFieldX2.value-templateFieldX1.value)/(templateFieldY2.value-templateFieldY1.value);
document
.getElementById("video-info-thumbnail-lock-aspect-ratio")
.addEventListener("change", updateTemplateCropAspectRatio);
videoFrameStage.setOptions({aspectRatio: templateFieldAspectRatio});
document
.getElementById("video-info-thumbnail-aspect-ratio-match-right")
.addEventListener("click", function () {
// Calculate and copy the aspect ratio from the video field to the template
const videoFieldX1 = document.getElementById("video-info-thumbnail-crop-0");
const videoFieldY1 = document.getElementById("video-info-thumbnail-crop-1");
const videoFieldX2 = document.getElementById("video-info-thumbnail-crop-2");
const videoFieldY2 = document.getElementById("video-info-thumbnail-crop-3");
const videoFieldAspectRatio =
(videoFieldX2.value - videoFieldX1.value) / (videoFieldY2.value - videoFieldY1.value);
templateStage.setOptions({ aspectRatio: videoFieldAspectRatio });
// Re-apply the locked/unlocked status
updateTemplateCropAspectRatio();
});
// Re-apply the locked/unlocked status
updateTemplateCropAspectRatio();
});
document
.getElementById("video-info-thumbnail-aspect-ratio-match-left")
.addEventListener("click", function () {
// Calculate and copy the aspect ratio from the template to the video field
const templateFieldX1 = document.getElementById("video-info-thumbnail-location-0");
const templateFieldY1 = document.getElementById("video-info-thumbnail-location-1");
const templateFieldX2 = document.getElementById("video-info-thumbnail-location-2");
const templateFieldY2 = document.getElementById("video-info-thumbnail-location-3");
const templateFieldAspectRatio =
(templateFieldX2.value - templateFieldX1.value) /
(templateFieldY2.value - templateFieldY1.value);
videoFrameStage.setOptions({ aspectRatio: templateFieldAspectRatio });
// Re-apply the locked/unlocked status
updateTemplateCropAspectRatio();
});
document
.getElementById("video-info-thumbnail-template-preview-generate")
@ -375,7 +408,7 @@ window.addEventListener("DOMContentLoaded", async (event) => {
const thumbnailTemplatesListResponse = await fetch("/thrimshim/templates");
if (thumbnailTemplatesListResponse.ok) {
const thumbnailTemplatesList = await thumbnailTemplatesListResponse.json();
const templateNames = thumbnailTemplatesList.map(t => t.name);
const templateNames = thumbnailTemplatesList.map((t) => t.name);
templateNames.sort();
for (const template of thumbnailTemplatesList) {
thumbnailTemplates[template.name] = template;
@ -401,7 +434,8 @@ window.addEventListener("DOMContentLoaded", async (event) => {
}
if (videoInfo.thumbnail_location !== null) {
for (let i = 0; i < 4; i++) {
document.getElementById(`video-info-thumbnail-location-${i}`).value = videoInfo.thumbnail_location[i];
document.getElementById(`video-info-thumbnail-location-${i}`).value =
videoInfo.thumbnail_location[i];
}
}
document.getElementById("video-info-thumbnail-mode").value = videoInfo.thumbnail_mode;
@ -479,11 +513,12 @@ window.addEventListener("DOMContentLoaded", async (event) => {
});
});
async function loadTransitions() {
const response = await fetch("/thrimshim/transitions");
if (!response.ok) {
addError("Failed to fetch possible transition types. This probably means the wubloader host is down.");
addError(
"Failed to fetch possible transition types. This probably means the wubloader host is down.",
);
return;
}
knownTransitions = await response.json();
@ -776,8 +811,12 @@ async function initializeVideoInfo() {
if (rangeIndex > 0) {
const transition = videoInfo.video_transitions[rangeIndex - 1];
const transitionType = rangeContainer.getElementsByClassName("range-transition-type")[0];
const transitionDuration = rangeContainer.getElementsByClassName("range-transition-duration")[0];
const transitionDurationSection = rangeContainer.getElementsByClassName("range-transition-duration-section")[0];
const transitionDuration = rangeContainer.getElementsByClassName(
"range-transition-duration",
)[0];
const transitionDurationSection = rangeContainer.getElementsByClassName(
"range-transition-duration-section",
)[0];
if (transition === null) {
transitionType.value = "";
transitionDuration.value = "";
@ -796,7 +835,7 @@ async function initializeVideoInfo() {
const option = document.createElement("option");
option.value = type;
option.textContent = type;
transitionType.append(option)
transitionType.append(option);
}
// Set type and duration.
transitionType.value = type;
@ -1062,11 +1101,13 @@ function validateChapterDescription(chapterDescField) {
if (chapterDesc.indexOf("<") !== -1 || chapterDesc.indexOf(">") !== -1) {
chapterDescField.classList.add("input-error");
chapterDescField.title = "Chapter description may not contain angle brackets (< or >)";
} else if (Array.from(chapterDesc).some(c => c.charCodeAt(0) > 127)) { // any char is non-ascii
} else if (Array.from(chapterDesc).some((c) => c.charCodeAt(0) > 127)) {
// any char is non-ascii
// We don't know what chars are safe outside the ascii range, so we just warn on any of them.
// We know emoji are not safe.
chapterDescField.classList.add("input-error");
chapterDescField.title = "Chapter descriptions with non-ascii characters may cause issues; proceed with caution";
chapterDescField.title =
"Chapter descriptions with non-ascii characters may cause issues; proceed with caution";
} else {
chapterDescField.classList.remove("input-error");
chapterDescField.title = "";
@ -1115,7 +1156,9 @@ async function sendVideoData(newState, overrideChanges) {
const transitionTypeElements = rangeContainer.getElementsByClassName("range-transition-type");
if (transitionTypeElements.length > 0) {
const transitionType = transitionTypeElements[0].value;
const transitionDurationStr = rangeContainer.getElementsByClassName("range-transition-duration")[0].value;
const transitionDurationStr = rangeContainer.getElementsByClassName(
"range-transition-duration",
)[0].value;
if (transitionType === "") {
transitions.push(null);
} else {
@ -1123,11 +1166,13 @@ async function sendVideoData(newState, overrideChanges) {
// but 0 is an error here anyway.
// Note that !(x > 0) is not equivalent to (x <= 0) due to NaN.
const transitionDuration = Number(transitionDurationStr);
if ( !(transitionDuration > 0) ) {
submissionError(`Couldn't submit edits: Invalid transition duration: "${transitionDurationStr}"`);
if (!(transitionDuration > 0)) {
submissionError(
`Couldn't submit edits: Invalid transition duration: "${transitionDurationStr}"`,
);
return;
}
transitions.push([transitionType, transitionDuration])
transitions.push([transitionType, transitionDuration]);
// Since we're overlapping with the previous range, this range's start time is
// actually earlier. This matters for chapter markers.
rangeStartInFinalVideo -= transitionDuration;
@ -1186,7 +1231,9 @@ async function sendVideoData(newState, overrideChanges) {
continue;
}
if (startFieldTime < rangeStartPlayer || startFieldTime > rangeEndPlayer) {
submissionError(`The chapter at "${startField.value}" is outside its containing time range.`);
submissionError(
`The chapter at "${startField.value}" is outside its containing time range.`,
);
return;
}
const chapterStartTime = rangeStartInFinalVideo + startFieldTime - rangeStartPlayer;
@ -1494,7 +1541,7 @@ async function uploadedImageToBase64() {
const fileLoadData = fileReader.result;
if (fileLoadData.error) {
throw new Error(
`An error (${fileLoadData.error.name}) occurred loading the thumbnail: ${fileLoadData.error.message}`
`An error (${fileLoadData.error.name}) occurred loading the thumbnail: ${fileLoadData.error.message}`,
);
}
if (fileLoadData.substring(0, 22) !== "data:image/png;base64,") {
@ -1536,7 +1583,7 @@ async function renderThumbnail() {
}
// Converting the result into base64 is similarly painful.
const blob = await res.blob();
const data = await new Promise(resolve => {
const data = await new Promise((resolve) => {
const reader = new FileReader();
reader.onload = () => resolve(reader.result);
reader.readAsDataURL(blob);
@ -1558,13 +1605,15 @@ function updateDownloadLink() {
const transitionTypeElements = rangeContainer.getElementsByClassName("range-transition-type");
if (transitionTypeElements.length > 0) {
const transitionType = transitionTypeElements[0].value;
const transitionDurationStr = rangeContainer.getElementsByClassName("range-transition-duration")[0].value;
const transitionDurationStr = rangeContainer.getElementsByClassName(
"range-transition-duration",
)[0].value;
if (transitionType === "") {
transitions.push("");
} else {
let transitionDuration = Number(transitionDurationStr);
// We don't have a sensible way to error out here, so default invalid durations to 1s
if ( !(transitionDuration > 0) ) {
if (!(transitionDuration > 0)) {
transitionDuration = 1;
}
transitions.push(`${transitionType},${transitionDuration}`);
@ -1711,9 +1760,12 @@ function makeElement(tag, classes = [], values = {}) {
function rangeDefinitionDOM() {
// Shortcut builder for image-based buttons
const button = (cls, src, alt) => makeElement("img", [cls, "click"], {
src, alt, title: alt,
});
const button = (cls, src, alt) =>
makeElement("img", [cls, "click"], {
src,
alt,
title: alt,
});
const rangeContainer = makeElement("div", ["range-definition-removable"]);
@ -1731,7 +1783,10 @@ function rangeDefinitionDOM() {
updateTransitionTypes([transitionType]);
// Duration always starts hidden because type always starts as cut.
const transitionDurationSection = makeElement("div", ["range-transition-duration-section", "hidden"]);
const transitionDurationSection = makeElement("div", [
"range-transition-duration-section",
"hidden",
]);
// Add/remove hidden when type changes
transitionType.addEventListener("change", (event) => {
if (transitionType.value === "") {
@ -1754,7 +1809,7 @@ function rangeDefinitionDOM() {
transitionContainer.append("Transition: ", transitionType, transitionDurationSection);
const rangeTimesContainer = makeElement("div", ["range-definition-times"]);
const rangeStart = makeElement("input", ["range-definition-start"], {type: "text"});
const rangeStart = makeElement("input", ["range-definition-start"], { type: "text" });
const rangeStartSet = button(
"range-definition-set-start",
"images/pencil.png",
@ -1766,7 +1821,7 @@ function rangeDefinitionDOM() {
"Play from start point",
);
const rangeTimeGap = makeElement("div", ["range-definition-between-time-gap"]);
const rangeEnd = makeElement("input", ["range-definition-end"], {type: "text"});
const rangeEnd = makeElement("input", ["range-definition-end"], { type: "text" });
const rangeEndSet = button(
"range-definition-set-end",
"images/pencil.png",
@ -1777,11 +1832,7 @@ function rangeDefinitionDOM() {
"images/play_to.png",
"Play from end point",
);
const removeRange = button(
"range-definition-remove",
"images/minus.png",
"Remove range",
);
const removeRange = button("range-definition-remove", "images/minus.png", "Remove range");
if (canEditVideo()) {
rangeStartSet.addEventListener("click", getRangeSetClickHandler("start"));
@ -2239,20 +2290,20 @@ function isNonVideoInput(element) {
*/
function createTemplateCropWidgets() {
if (videoFrameStage == null) {
videoFrameStage = Jcrop.attach('video-info-thumbnail-template-video-source-image');
videoFrameStage.listen('crop.update',function(widget,e){
videoFrameStage = Jcrop.attach("video-info-thumbnail-template-video-source-image");
videoFrameStage.listen("crop.update", function (widget, e) {
const pos = widget.pos;
const fieldX1 = document.getElementById("video-info-thumbnail-crop-0");
const fieldY1 = document.getElementById("video-info-thumbnail-crop-1");
const fieldX2 = document.getElementById("video-info-thumbnail-crop-2");
const fieldY2 = document.getElementById("video-info-thumbnail-crop-3");
// 640x320 -> 1920x1080
fieldX1.value = Math.round(pos.x*3);
fieldY1.value = Math.round(pos.y*3);
fieldX2.value = Math.round((pos.x+pos.w)*3);
fieldY2.value = Math.round((pos.y+pos.h)*3);
fieldX1.value = Math.round(pos.x * 3);
fieldY1.value = Math.round(pos.y * 3);
fieldX2.value = Math.round((pos.x + pos.w) * 3);
fieldY2.value = Math.round((pos.y + pos.h) * 3);
});
videoFrameStage.listen('crop.change',function(widget,e){
videoFrameStage.listen("crop.change", function (widget, e) {
// This only fires when the user is finished dragging, not every time the size
// of the cropped area updates. This avoids the template area updating every
// instant due to minute changes in the aspect ratio, which causes it to shrink
@ -2261,18 +2312,18 @@ function createTemplateCropWidgets() {
});
}
if (templateStage == null) {
templateStage = Jcrop.attach('video-info-thumbnail-template-overlay-image');
templateStage.listen('crop.update',function(widget,e){
templateStage = Jcrop.attach("video-info-thumbnail-template-overlay-image");
templateStage.listen("crop.update", function (widget, e) {
const pos = widget.pos;
const fieldX1 = document.getElementById("video-info-thumbnail-location-0");
const fieldY1 = document.getElementById("video-info-thumbnail-location-1");
const fieldX2 = document.getElementById("video-info-thumbnail-location-2");
const fieldY2 = document.getElementById("video-info-thumbnail-location-3");
// 640x320 -> 1280x720
fieldX1.value = Math.round(pos.x*2);
fieldY1.value = Math.round(pos.y*2);
fieldX2.value = Math.round((pos.x+pos.w)*2);
fieldY2.value = Math.round((pos.y+pos.h)*2);
fieldX1.value = Math.round(pos.x * 2);
fieldY1.value = Math.round(pos.y * 2);
fieldX2.value = Math.round((pos.x + pos.w) * 2);
fieldY2.value = Math.round((pos.y + pos.h) * 2);
});
}
@ -2290,7 +2341,12 @@ function updateTemplateCropWidgets() {
const videoFieldX2 = document.getElementById("video-info-thumbnail-crop-2");
const videoFieldY2 = document.getElementById("video-info-thumbnail-crop-3");
// Video frame: 640x360 -> 1920x1080
const videoFrameRect = Jcrop.Rect.create(videoFieldX1.value/3, videoFieldY1.value/3, (videoFieldX2.value-videoFieldX1.value)/3, (videoFieldY2.value-videoFieldY1.value)/3);
const videoFrameRect = Jcrop.Rect.create(
videoFieldX1.value / 3,
videoFieldY1.value / 3,
(videoFieldX2.value - videoFieldX1.value) / 3,
(videoFieldY2.value - videoFieldY1.value) / 3,
);
if (videoFrameStage.active == null) {
videoFrameStage.newWidget(videoFrameRect);
} else {
@ -2303,7 +2359,12 @@ function updateTemplateCropWidgets() {
const templateFieldX2 = document.getElementById("video-info-thumbnail-location-2");
const templateFieldY2 = document.getElementById("video-info-thumbnail-location-3");
// Template: 640x360 -> 1280x720
const templateRect = Jcrop.Rect.create(templateFieldX1.value/2, templateFieldY1.value/2, (templateFieldX2.value-templateFieldX1.value)/2, (templateFieldY2.value-templateFieldY1.value)/2);
const templateRect = Jcrop.Rect.create(
templateFieldX1.value / 2,
templateFieldY1.value / 2,
(templateFieldX2.value - templateFieldX1.value) / 2,
(templateFieldY2.value - templateFieldY1.value) / 2,
);
if (templateStage.active == null) {
templateStage.newWidget(templateRect);
} else {
@ -2321,11 +2382,12 @@ function updateTemplateCropAspectRatio() {
const videoFieldY1 = document.getElementById("video-info-thumbnail-crop-1");
const videoFieldX2 = document.getElementById("video-info-thumbnail-crop-2");
const videoFieldY2 = document.getElementById("video-info-thumbnail-crop-3");
const videoFieldAspectRatio = (videoFieldX2.value-videoFieldX1.value)/(videoFieldY2.value-videoFieldY1.value);
videoFrameStage.setOptions({aspectRatio: videoFieldAspectRatio});
templateStage.setOptions({aspectRatio: videoFieldAspectRatio});
const videoFieldAspectRatio =
(videoFieldX2.value - videoFieldX1.value) / (videoFieldY2.value - videoFieldY1.value);
videoFrameStage.setOptions({ aspectRatio: videoFieldAspectRatio });
templateStage.setOptions({ aspectRatio: videoFieldAspectRatio });
} else {
videoFrameStage.setOptions({aspectRatio: null});
templateStage.setOptions({aspectRatio: null});
videoFrameStage.setOptions({ aspectRatio: null });
templateStage.setOptions({ aspectRatio: null });
}
}

@ -137,7 +137,7 @@ function generateDownloadURL(startTime, endTime, downloadType, allowHoles, quali
const query = new URLSearchParams({
type: downloadType,
allow_holes: allowHoles
allow_holes: allowHoles,
});
if (startURLTime) {
query.append("start", startURLTime);

Loading…
Cancel
Save