From 26013077affafc6160a64bc875762c02f0c3ca89 Mon Sep 17 00:00:00 2001 From: Mikael Finstad Date: Fri, 30 Jan 2026 13:44:59 +0800 Subject: [PATCH] add smartcut option `-bf` based on `has_b_frames` #2690 #126 --- src/renderer/src/hooks/useFfmpegOperations.ts | 7 +++++-- src/renderer/src/smartcut.ts | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/renderer/src/hooks/useFfmpegOperations.ts b/src/renderer/src/hooks/useFfmpegOperations.ts index 996fbfb5..f8fa41f8 100644 --- a/src/renderer/src/hooks/useFfmpegOperations.ts +++ b/src/renderer/src/hooks/useFfmpegOperations.ts @@ -427,7 +427,7 @@ function useFfmpegOperations({ filePath, treatInputFileModifiedTimeAsStart, trea }, [appendFfmpegCommandLog, cutFromAdjustmentFrames, cutToAdjustmentFrames, filePath, getOutputPlaybackRateArgs, treatInputFileModifiedTimeAsStart, treatOutputFileModifiedTimeAsStart]); // inspired by https://gist.github.com/fernandoherreradelasheras/5eca67f4200f1a7cc8281747da08496e - const cutEncodeSmartPart = useCallback(async ({ cutFrom, cutTo, outPath, outFormat, videoCodec, videoBitrate, videoTimebase, allFilesMeta, copyFileStreams, videoStreamIndex, ffmpegExperimental }: { + const cutEncodeSmartPart = useCallback(async ({ cutFrom, cutTo, outPath, outFormat, videoCodec, videoBitrate, videoTimebase, allFilesMeta, copyFileStreams, videoStreamIndex, ffmpegExperimental, hasBFrames }: { cutFrom: number, cutTo: number, outPath: string, @@ -439,6 +439,7 @@ function useFfmpegOperations({ filePath, treatInputFileModifiedTimeAsStart, trea copyFileStreams: CopyfileStreams, videoStreamIndex: number, ffmpegExperimental: boolean, + hasBFrames: number | undefined, }) => { invariant(filePath != null); @@ -481,6 +482,8 @@ function useFfmpegOperations({ filePath, treatInputFileModifiedTimeAsStart, trea ...getVideoTimescaleArgs(videoTimebase), + ...(hasBFrames ? ['-bf', String(hasBFrames)] : []), + ...getExperimentalArgs(ffmpegExperimental), '-f', outFormat, '-y', outPath, @@ -583,7 +586,7 @@ function useFfmpegOperations({ filePath, treatInputFileModifiedTimeAsStart, trea invariant(sourceCodecParams.videoTimebase != null); invariant(filePath != null); invariant(outFormat != null); - await cutEncodeSmartPart({ cutFrom, cutTo, outPath, outFormat, videoCodec, videoBitrate: encCustomBitrate != null ? encCustomBitrate * 1000 : sourceCodecParams.videoBitrate, videoStreamIndex: videoStream.index, videoTimebase: sourceCodecParams.videoTimebase, allFilesMeta, copyFileStreams: copyFileStreamsFiltered, ffmpegExperimental }); + await cutEncodeSmartPart({ cutFrom, cutTo, outPath, outFormat, videoCodec, videoBitrate: encCustomBitrate != null ? encCustomBitrate * 1000 : sourceCodecParams.videoBitrate, videoStreamIndex: videoStream.index, videoTimebase: sourceCodecParams.videoTimebase, allFilesMeta, copyFileStreams: copyFileStreamsFiltered, ffmpegExperimental, hasBFrames: sourceCodecParams.videoStream.has_b_frames }); } const cutEncodeWholePart = async () => { diff --git a/src/renderer/src/smartcut.ts b/src/renderer/src/smartcut.ts index 20c02e08..4d18892c 100644 --- a/src/renderer/src/smartcut.ts +++ b/src/renderer/src/smartcut.ts @@ -50,7 +50,7 @@ export async function needsSmartCut({ path, desiredCutFrom, videoStream }: { export async function getCodecParams({ path, fileDuration, streams }: { path: string, fileDuration: number | undefined, - streams: Pick[], + streams: Pick[], }) { const videoStreams = getRealVideoStreams(streams); if (videoStreams.length > 1) throw new Error('Can only smart cut video with exactly one video stream');