Use two-pass with ffmpeg
This commit is contained in:
parent
5bb14ef3f7
commit
574478db84
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,2 +1,3 @@
|
|||||||
public/assets/scripts/ffmpeg/
|
public/assets/scripts/ffmpeg/
|
||||||
|
public/assets/scripts/core/
|
||||||
|
|
||||||
|
|||||||
@ -8,18 +8,45 @@ async function compress() {
|
|||||||
const filesizeUnit = document.getElementById("filesize-unit").value;
|
const filesizeUnit = document.getElementById("filesize-unit").value;
|
||||||
const file = document.getElementById("file-input").files[0];
|
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);
|
updateProgress(0);
|
||||||
|
|
||||||
ffmpeg.on("progress", data => {
|
ffmpeg.on("log", event => {
|
||||||
console.log(data);
|
console.log("[ffmpeg]", event.type, event.message);
|
||||||
updateProgress(data.progress);
|
});
|
||||||
|
|
||||||
|
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.load({ coreURL: "/assets/scripts/core/package/dist/umd/ffmpeg-core.js" });
|
||||||
|
|
||||||
await ffmpeg.writeFile(file.name, await readFromBlob(file));
|
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");
|
const video = await ffmpeg.readFile("compressed.mp4");
|
||||||
|
|
||||||
@ -32,9 +59,10 @@ function cancel() {
|
|||||||
showSection("file-picker");
|
showSection("file-picker");
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateProgress(progress) {
|
function updateProgress(progress, pass) {
|
||||||
const percent = (progress * 100).toFixed(1) + "%";
|
const percent = (progress * 100).toFixed(1) + "%";
|
||||||
|
|
||||||
|
document.getElementById("progress-step-value").innerText = pass;
|
||||||
document.getElementById("progress-percentage").innerText = percent;
|
document.getElementById("progress-percentage").innerText = percent;
|
||||||
document.getElementById("progress-indicator").style.clipPath = `rect(0 ${percent} 100% 0)`;
|
document.getElementById("progress-indicator").style.clipPath = `rect(0 ${percent} 100% 0)`;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -157,7 +157,7 @@ input:focus, select:focus {
|
|||||||
|
|
||||||
#loading-title {
|
#loading-title {
|
||||||
color: #757575;
|
color: #757575;
|
||||||
font-size: 3rem;
|
font-size: 2.5rem;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
margin-top: 4rem;
|
margin-top: 4rem;
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
@ -175,7 +175,6 @@ input:focus, select:focus {
|
|||||||
margin: auto;
|
margin: auto;
|
||||||
background-color: #E0E0E0;
|
background-color: #E0E0E0;
|
||||||
position: relative;
|
position: relative;
|
||||||
margin-top: 3rem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#progress-indicator {
|
#progress-indicator {
|
||||||
@ -192,3 +191,8 @@ input:focus, select:focus {
|
|||||||
font-size: 1.2rem;
|
font-size: 1.2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#progress-step {
|
||||||
|
font-weight: bold;
|
||||||
|
margin-top: 3rem;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|||||||
@ -29,7 +29,6 @@
|
|||||||
--><select id="filesize-unit">
|
--><select id="filesize-unit">
|
||||||
<option value="K">KB</option>
|
<option value="K">KB</option>
|
||||||
<option value="M" selected>MB</option>
|
<option value="M" selected>MB</option>
|
||||||
<option value="G">GB</option>
|
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<button id="compress" onclick="compress()" class="primary">Go!</button>
|
<button id="compress" onclick="compress()" class="primary">Go!</button>
|
||||||
@ -39,6 +38,7 @@
|
|||||||
<h3 id="loading-title">Please wait...</h3>
|
<h3 id="loading-title">Please wait...</h3>
|
||||||
<p id="loading-description">This may take a while</p>
|
<p id="loading-description">This may take a while</p>
|
||||||
|
|
||||||
|
<p id="progress-step">Step <span id="progress-step-value">1</span>/2</p>
|
||||||
<div id="progress-container">
|
<div id="progress-container">
|
||||||
<div id="progress-indicator"></div>
|
<div id="progress-indicator"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user