diff --git a/.gitignore b/.gitignore index 32f94f0..65377ff 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ public/assets/scripts/ffmpeg/ +public/assets/scripts/core/ diff --git a/public/assets/scripts/main.js b/public/assets/scripts/main.js index c589022..9a88228 100644 --- a/public/assets/scripts/main.js +++ b/public/assets/scripts/main.js @@ -8,18 +8,45 @@ async function compress() { const filesizeUnit = document.getElementById("filesize-unit").value; const file = document.getElementById("file-input").files[0]; + const videoLength = document.getElementById("uploaded-video").duration; + let targetFilesize; // Stored in kBit + switch (filesizeUnit) { + case "K": targetFilesize = filesize * 8.192; break; + case "M": targetFilesize = filesize * 8388.608; break; + } + updateProgress(0); - ffmpeg.on("progress", data => { - console.log(data); - updateProgress(data.progress); + ffmpeg.on("log", event => { + console.log("[ffmpeg]", event.type, event.message); + }); + + let pass; + + ffmpeg.on("progress", event => { + updateProgress(event.progress, pass); }); await ffmpeg.load({ coreURL: "/assets/scripts/core/package/dist/umd/ffmpeg-core.js" }); await ffmpeg.writeFile(file.name, await readFromBlob(file)); - await ffmpeg.exec(["-i", file.name, "-preset", "veryfast", "-fs", filesize + filesizeUnit, "compressed.mp4"]); + // Use Two-Pass to create a video file with desired file size + // https://trac.ffmpeg.org/wiki/Encode/H.264#twopass + + const bitrate = Math.round(targetFilesize / videoLength) - 128; // Subtract audio bitrate + + console.debug("Target bitrate:", bitrate); + + const options = ["-i", file.name, "-preset", "veryfast", "-c:v", "libx264", "-b:v", bitrate + "k"]; + + pass = 1; + + await ffmpeg.exec(["-y", ...options, "-pass", "1", "-vsync", "cfr", "-f", "null", "/dev/null"]); + + pass = 2; + + await ffmpeg.exec([...options, "-pass", "2", "-c:a", "aac", "-b:a", "128k", "compressed.mp4"]); const video = await ffmpeg.readFile("compressed.mp4"); @@ -32,9 +59,10 @@ function cancel() { showSection("file-picker"); } -function updateProgress(progress) { +function updateProgress(progress, pass) { const percent = (progress * 100).toFixed(1) + "%"; + document.getElementById("progress-step-value").innerText = pass; document.getElementById("progress-percentage").innerText = percent; document.getElementById("progress-indicator").style.clipPath = `rect(0 ${percent} 100% 0)`; } diff --git a/public/assets/style/main.css b/public/assets/style/main.css index 54cdee7..3576868 100644 --- a/public/assets/style/main.css +++ b/public/assets/style/main.css @@ -157,7 +157,7 @@ input:focus, select:focus { #loading-title { color: #757575; - font-size: 3rem; + font-size: 2.5rem; font-weight: bold; margin-top: 4rem; margin-bottom: 0; @@ -175,7 +175,6 @@ input:focus, select:focus { margin: auto; background-color: #E0E0E0; position: relative; - margin-top: 3rem; } #progress-indicator { @@ -192,3 +191,8 @@ input:focus, select:focus { font-size: 1.2rem; } +#progress-step { + font-weight: bold; + margin-top: 3rem; + margin-bottom: 0.5rem; +} diff --git a/public/index.html b/public/index.html index 2d5a8fd..b3a7ec8 100644 --- a/public/index.html +++ b/public/index.html @@ -29,7 +29,6 @@ --> @@ -39,6 +38,7 @@
This may take a while
+Step 1/2