video-compressor/public/assets/scripts/main.js

126 lines
3.6 KiB
JavaScript

import { UiManager } from "./UiManager.js";
import { Notifier } from "./Notifier.js";
import { ProgressBar } from "./ProgressBar.js";
import { VideoCompressor } from "./VideoCompressor.js";
import { FileSelector } from "./FileSelector.js";
const ui = new UiManager();
const notifier = new Notifier();
const progressBar = new ProgressBar();
const videoCompressor = new VideoCompressor(progressBar);
const fileSelector = new FileSelector("video/");
fileSelector.addInput(document.getElementById("file-input"));
fileSelector.addDropZone(document.getElementById("file-drop-area"));
fileSelector.onFileSelected = file => {
document.getElementById("uploaded-video").src = URL.createObjectURL(file);
document.getElementById("uploaded-video").load();
ui.hideElements("#file-drop-area", "#file-input-spacing");
ui.showElements("#uploaded-video", "#change-file");
};
async function compress(filesize, filesizeUnit) {
document.getElementById("uploaded-video").pause();
if (!fileSelector.selectedFile) {
alert("Please select a file");
return;
}
const sectionChangePromise = ui.showSection("loading");
const videoLength = document.getElementById("uploaded-video").duration;
let targetFilesize;
switch (filesizeUnit) {
case "kb": targetFilesize = filesize * 1000; break;
case "mb": targetFilesize = filesize * 1000000; break;
}
let result;
try {
result = await videoCompressor.compress(fileSelector.selectedFile, targetFilesize, videoLength);
} catch (e) {
await sectionChangePromise; // Avoid changing sections at the same time
alert(e.message);
ui.showSection("file-picker");
return;
}
if (!result) return;
notifier.notifyFinished();
const url = URL.createObjectURL(result);
document.getElementById("compressed-video").src = url;
document.getElementById("compressed-video").load();
document.getElementById("result-size").innerText = bytesToSizeString(result.size);
document.getElementById("download").onclick = () => {
const a = document.createElement("a");
a.href = url;
a.download = result.name;
a.click();
};
const shareData = {
text: "Compressed using " + window.origin,
files: [result],
};
if (navigator.share && (!navigator.canShare || navigator.canShare(shareData))) {
document.getElementById("share").style.display = "inline-block";
document.getElementById("share").onclick = () => navigator.share(shareData);
} else {
document.getElementById("share").style.display = "none";
}
ui.showSection("result");
}
document.getElementById("compress").onclick = async () => {
const filesize = document.getElementById("filesize").value;
const filesizeUnit = document.getElementById("filesize-unit").value;
await compress(filesize, filesizeUnit);
}
document.getElementById("cancel").onclick = () => {
videoCompressor.stop();
ui.showSection("file-picker");
};
document.getElementById("change-file").onclick = () => document.getElementById("file-input").click();
document.getElementById("back").onclick = () => ui.showSection("file-picker");
window.onbeforeunload = event => {
if (videoCompressor.inProgress) event.preventDefault();
};
function bytesToSizeString(bytes) {
if (bytes >= 1000000000) return (bytes / 1000000000).toFixed(1) + " GB";
if (bytes >= 1000000) return (bytes / 1000000).toFixed(1) + " MB";
if (bytes >= 1000) return (bytes / 1000).toFixed(1) + " KB";
return bytes + " B";
}
for (const tabbable of document.querySelectorAll("[tabindex='0']")) {
tabbable.onkeydown = event => {
if (['Enter', 'Space'].includes(event.code))
tabbable.click();
}
}
for (const preset of document.getElementsByClassName("preset")) {
preset.onclick = () => compress(parseInt(preset.dataset.size), preset.dataset.unit);
}