refactor: FFmpeg builder #36

Merged
Anri merged 84 commits from builder into main 2025-12-21 16:27:08 +01:00
Owner
  • Less error-prone as we don't do string interpolation everytime we call ffmpeg, we will rely on our builder that will do the bare minimum
  • So all error related to ffmpeg will be in our ffmpeg-mega-class-that-do-all-the-interpolation

Goal:

  • toString/build shouldn't be doing much checks, just putting the ffmpeg commands together
  • Checks should be done individually in daisy calls
  • Do some testing on Windows
  • Split the toString logic into multiple pieces
  • Tests

This PR have a lot more going on that a simple refactor. There is a lot of optimization and fixes that came from the new way of creating ffmpeg commands.

  • H265 2pass
  • 1 file merging audios
  • 10 bit CPU fallback
  • Better GPU acceleration support
    • Don't 2pass as its not supported (previously we were encoding files 2 times for nothing)
    • Add flags to specific hw encoders so it produce better files (!! need testing : are we exceeding file size limits?)
      • Talking about : VBR/maxrate/bufsize, multipass encoding for nvenc, transcoding preset for amf
- Less error-prone as we don't do string interpolation everytime we call ffmpeg, we will rely on our builder that will do the bare minimum - So all error related to ffmpeg will be in our ffmpeg-mega-class-that-do-all-the-interpolation Goal: - [x] `toString`/`build` shouldn't be doing much checks, just putting the ffmpeg commands together - [x] Checks should be done individually in daisy calls - [x] Do some testing on Windows - [x] Split the `toString` logic into multiple pieces - [x] Tests --- This PR have a lot more going on that a simple refactor. There is a lot of optimization and fixes that came from the new way of creating ffmpeg commands. - H265 2pass - 1 file merging audios - 10 bit CPU fallback - Better GPU acceleration support - Don't 2pass as its not supported (previously we were encoding files 2 times for nothing) - Add flags to specific hw encoders so it produce better files (!! need testing : are we exceeding file size limits?) - Talking about : VBR/maxrate/bufsize, multipass encoding for nvenc, transcoding preset for amf
@ -37,6 +37,7 @@ const getFiles = async () => {
}
return true;
})
.filter((file) => file !== ".")
Author
Owner

Unrelated fix

Unrelated fix
Anri marked this conversation as resolved
Anri left a comment
Author
Owner

good

good
src/ffmpeg.ts Outdated
@ -0,0 +427,4 @@
// Pass-specific logic
switch (pass) {
case 1: {
args.push("-pass 1");
Author
Owner

Split: "-pass", "1"

Split: "-pass", "1"
Anri marked this conversation as resolved
src/ffmpeg.ts Outdated
@ -0,0 +443,4 @@
return args.join(" ");
}
case 2: {
args.push("-pass 2");
Author
Owner

Split: "-pass", "2"

Split: "-pass", "2"
Anri marked this conversation as resolved
src/ffmpeg.ts Outdated
@ -0,0 +476,4 @@
this._metadata.forEach((m) => {
args.push(
`-metadata:s:${m.track.type.prefix}:${m.track.index}`,
`${m.key}="${m.value}"`,
Author
Owner

We could have a toString function for Metadatas

We could have a toString function for Metadatas
Anri marked this conversation as resolved
src/ffmpeg.ts Outdated
@ -0,0 +379,4 @@
if (FFmpegBuilder.changed(this._hw)) {
let isVAAPI = this._hw === FFmpegArgument.HardwareBackend.VAAPI;
// Common arguments
Author
Owner

What is common?

What is common?
Anri marked this conversation as resolved
src/ffmpeg.ts Outdated
@ -0,0 +397,4 @@
}
const bitrate = this._bitrates.find(
(s) => s.type === FFmpegArgument.Stream.Type.Video,
Author
Owner

Also as we wanna use the first video as reference, find index also based on index

Also as we wanna use the first video as reference, find index also based on index
Anri marked this conversation as resolved
src/ffmpeg.ts Outdated
@ -0,0 +431,4 @@
// No audio in pass 1
// https://trac.ffmpeg.org/wiki/Encode/H.264#Two-PassExample
args.push("-vsync cfr");
Author
Owner

Split, "-vsync", "cfr"

Split, "-vsync", "cfr"
Anri marked this conversation as resolved
src/main.ts Outdated
@ -186,0 +218,4 @@
),
)
.audioCodec(FFmpegArgument.Codecs.Audio.AAC)
.profile(FFmpegArgument.Profile.Main)
Author
Owner

Is the profile really needed all the time? Does it help for compression? I remember that it was added during 10 bit support

Is the profile really needed all the time? Does it help for compression? I remember that it was added during 10 bit support
Anri marked this conversation as resolved
src/main.ts Outdated
@ -186,0 +219,4 @@
)
.audioCodec(FFmpegArgument.Codecs.Audio.AAC)
.profile(FFmpegArgument.Profile.Main)
.tracks(FFmpegArgument.Tracks.AllVideos)
Author
Owner

Do we want all videos or only the first?

Do we want all videos or only the first?
Author
Owner

We were taking all the videos of the first input, and we probably will only ever encounter a file with one video stream.

We were taking all the videos of the first input, and we probably will only ever encounter a file with one video stream.
Anri marked this conversation as resolved
Anri changed title from WIP: FFmpeg builder to FFmpeg builder 2025-12-19 22:45:03 +01:00
Author
Owner
For AMF, we could use -usage flag? https://github.com/GPUOpen-LibrariesAndSDKs/AMF/wiki/AMF%20Encoder%20Settings%20and%20Tuning%20in%20FFmpeg#-usage
Author
Owner

PR is mostly ready. Have to do some extensive testing as I rewrote ALL ffmpeg command using the new builder.

When ready, I think a squash will be welcome, as there is (too) many commits that are not worth being alone

PR is mostly ready. Have to do some extensive testing as I rewrote ALL ffmpeg command using the new builder. When ready, I think a squash will be welcome, as there is (too) many commits that are not worth being alone
Author
Owner

A note for profile:

They were initially implemented but I removed them because :

  • I don't use them
  • They are codec-specific
A note for profile: They were initially implemented but I removed them because : - I don't use them - They are codec-specific
Anri changed title from FFmpeg builder to refactor: FFmpeg builder 2025-12-20 02:51:22 +01:00
src/main.ts Outdated
@ -182,0 +221,4 @@
.input(file)
.output(finalFile)
.videoCodec(
",".concat(...process.argv).includes("265")
Author
Owner

Do real argument parsing, don't mash all args to a string to do a basic string matching.

Do real argument parsing, don't mash all args to a string to do a basic string matching.
Author
Owner

ajouter le AV1 tant qu'on y est

ajouter le AV1 tant qu'on y est
Anri marked this conversation as resolved
Anri merged commit 0836a51733 into main 2025-12-21 16:27:08 +01:00
Anri deleted branch builder 2025-12-21 16:27:09 +01:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Anri/dsr!36
No description provided.