Skip to content

Commit 29ef564

Browse files
CopilotSwaggyMacro
andcommitted
Fix playback speed by using ffmpeg setpts filter for proper speed adjustment
- Use ffmpeg's setpts filter to actually change video speed before frame extraction - Formula: setpts=(1/playbackSpeed)*PTS adjusts video presentation timestamps - This properly speeds up/slows down video by dropping/duplicating frames - File sizes now correctly differ based on speed (fewer frames for speedup, more for slowdown) - Simplified delay calculation since speed is handled by ffmpeg Co-authored-by: SwaggyMacro <38845682+SwaggyMacro@users.noreply.github.com>
1 parent c5594da commit 29ef564

1 file changed

Lines changed: 11 additions & 7 deletions

File tree

LottieViewConvert/ViewModels/TgsDownloadViewModel.cs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -559,12 +559,17 @@ await Task.Run(async () =>
559559
// Get the frame rate from the WebM file
560560
var fps = await GetVideoFrameRateAsync(sticker.FilePath, exec);
561561

562-
// Extract frames with proper frame rate
562+
// Apply speed adjustment using ffmpeg's setpts filter
563+
// For speed adjustment: setpts=PTS/speed (e.g., PTS/2 for 2x speed, PTS*2 for 0.5x speed)
564+
var ptsMultiplier = 1.0 / playbackSpeed; // Inverse for setpts filter
565+
var videoFilter = $"setpts={ptsMultiplier:F4}*PTS,format=yuva420p";
566+
567+
// Extract frames with speed adjustment applied
563568
var extractArgs = new List<string>
564569
{
565570
"-hide_banner", "-y",
566571
"-i", sticker.FilePath,
567-
"-vf", "format=yuva420p",
572+
"-vf", videoFilter,
568573
"-c:v", "png", "-pix_fmt", "rgba",
569574
Path.Combine(tempDir, "frame_%03d.png")
570575
};
@@ -578,13 +583,12 @@ await Task.Run(async () =>
578583
img.Alpha(AlphaOption.Set);
579584
imgList.Add(img);
580585
}
581-
// Calculate delay based on the actual frame rate and playback speed
582-
// delay in centiseconds = (100 / fps) / playbackSpeed
583-
var baseDelay = fps > 0 ? 100.0 / fps : 3.33;
584-
var adjustedDelay = (uint)Math.Max(1, Math.Round(baseDelay / playbackSpeed));
586+
// Calculate delay based on the actual frame rate
587+
// Since we've already adjusted speed in ffmpeg, use the original fps for delay
588+
var delay = fps > 0 ? (uint)Math.Max(1, Math.Round(100.0 / fps)) : 3;
585589
foreach (var img in imgList)
586590
{
587-
img.AnimationDelay = adjustedDelay;
591+
img.AnimationDelay = delay;
588592
img.Format = MagickFormat.Gif;
589593
img.GifDisposeMethod = GifDisposeMethod.Background;
590594
img.BackgroundColor = MagickColors.Transparent;

0 commit comments

Comments
 (0)