diff --git a/server/lib/recorder/ffmeg_test.go b/server/lib/recorder/ffmeg_test.go index 89b4a0ca..edb649c4 100644 --- a/server/lib/recorder/ffmeg_test.go +++ b/server/lib/recorder/ffmeg_test.go @@ -68,6 +68,21 @@ func TestFFmpegRecorder_Params(t *testing.T) { assert.Equal(t, *params.OutputDir, *got.OutputDir) } +func TestFFmpegArgs_PadsOddDimensions(t *testing.T) { + tempDir := t.TempDir() + args, err := ffmpegArgs(defaultParams(tempDir), filepath.Join(tempDir, "out.mp4")) + require.NoError(t, err) + + var vf string + for i, a := range args { + if a == "-vf" && i+1 < len(args) { + vf = args[i+1] + break + } + } + assert.Equal(t, "pad=ceil(iw/2)*2:ceil(ih/2)*2", vf) +} + func TestFFmpegRecorder_ForceStop(t *testing.T) { tempDir := t.TempDir() rec := &FFmpegRecorder{ diff --git a/server/lib/recorder/ffmpeg.go b/server/lib/recorder/ffmpeg.go index 48a82178..a44c0286 100644 --- a/server/lib/recorder/ffmpeg.go +++ b/server/lib/recorder/ffmpeg.go @@ -498,6 +498,10 @@ func ffmpegArgs(params FFmpegRecordingParams, outputPath string) ([]string, erro // Output options next args = append(args, []string{ + // yuv420p requires even width and height; pad odd source dimensions by one pixel + // so libx264 doesn't fail to open the encoder. + "-vf", "pad=ceil(iw/2)*2:ceil(ih/2)*2", + // Video encoding "-c:v", "libx264", "-profile:v", "high", // Explicit web-compatible profile