101

I found this example

 ffmpeg -i input.mkv -filter:v "setpts=0.5*PTS" output.mkv 

but I have a video I want to speed up by 60 times, not just 2X.

watercollider
  • 1,112
  • 2
  • 8
  • 8

7 Answers7

140

Simply multiply by the reciprocal of the speed factor.

ffmpeg -i input.mkv -filter:v "setpts=PTS/60" output.mkv

This does not affect the audio speed. Use -an to not include audio in the output.


A faster method, but which can have unexpected results with audio (pauses or async):

ffmpeg -itsscale 0.01666 -i input.mkv -c copy output.mkv

where 0.01666 is 1/60 in decimal representation.

Gyan
  • 34,439
  • 6
  • 56
  • 98
  • 19
    While the playback speed seems to be changed for this, the video duration seems to be represented incorrectly; e.g., a 3 minute video sped up 3x will still show as being 3 minutes long. If you play it in a video player (e.g., VLC) the video will only take up the first minute and then freeze on a frame for the remaining 2 minutes. – jrh Nov 19 '18 at 21:55
  • 1
    Does it have audio? – Gyan Nov 20 '18 at 05:45
  • 14
    It does make sense that ffmpeg would leave the full length of the video because there was still audio data. Good catch, it turns out, it did have audio (my speakers were muted). With the `-an` parameter, the length of the video is set properly. – jrh Nov 20 '18 at 18:12
  • this is too slow. for me it's encoding 2 frames/second. i've got about 30 minutes of video! – Michael Jan 19 '20 at 00:31
  • See new method. – Gyan Jan 19 '20 at 05:08
  • The second method is creating a file around 99.99% the size of the input with 60% of the duration - when I play it, I see each individual frame rendered for several seconds. Both with and without `-an` (although I'm not sure exactly where it's supposed to go) – Michael Feb 25 '20 at 01:54
  • Ok, so correct me if I'm wrong, but the second method is faster because it doesn't actually do anything - the whole video is still there, just with metadata that is instructing the player to play it at an impossibly fast rate. (Which quite honestly, is useless and not what i was expecting) – Michael Feb 25 '20 at 02:36
  • 6
    Yes, video playback speed is governed by packet metadata. 60x is a very high speed up and players will usually choke. You'll see more expected results with, say, a 6x speed up. Players can't "skip" frames in a compressed video bitstream since almost all frames depend on one or more surrounding frames for decoding. So, you have to drop frames and re-encode i.e. a timelapse, e.g. `ffmpeg -i input -vf framestep=60,setpts=N/30/TB -r 30 -an out.mp4` – Gyan Feb 25 '20 at 04:15
  • 2
    There's a large difference in these two methods in terms of file size, at least for my specific movie. The former outputs a video that's ~100x smaller, while the latter outputs a file that's the same size as the original. – Jessime Kirk Mar 29 '20 at 00:20
  • Yes, the latter keeps all frames since it is copying the stream and only changes their timestamps. The former changes all timestamps but the frame rate control logic which is applied later during re-encoding drops frames closer in time than given frame rate. – Gyan Mar 29 '20 at 08:23
  • @Michael it outputs 2 fps of the *new video*, which is 120 fps of the original video. – qwr May 14 '21 at 08:47
  • I used this to correct a faulty bad PowerPoint 41-second screen recording reducing a 400MB file, 41-minute file to a 400K file, 41-second file (1000:1 reduction in file size, and a 60:1 reduction in playback speed). `ffmpeg -y -i bad-powerpoint.mp4 -filter:v "setpts=PTS/60" -an -r 1 fast.mp4` – Stephen Quan Feb 13 '23 at 00:57
42

If you also want to speed up the audio, you need to do this:

ffmpeg -i input.mkv -filter_complex "[0:v]setpts=0.5*PTS[v];[0:a]atempo=2[a]" -map "[v]" -map "[a]" output.mkv

Docs: https://trac.ffmpeg.org/wiki/How%20to%20speed%20up%20/%20slow%20down%20a%20video

The command above works if you want to multiply by 2 the speed. If you want to multiply by any x (between 0 and 100), the parameters become:

  ffmpeg -i input.mkv -filter_complex "[0:v]setpts=1/<x>*PTS[v];[0:a]atempo=<x>[a]" -map "[v]" -map "[a]" output.mkv

For instance, if you want to multiply by 1.15, the command is

  ffmpeg -i input.mkv -filter_complex "[0:v]setpts=0.87*PTS[v];[0:a]atempo=1.15[a]" -map "[v]" -map "[a]" output.mkv
dopexxx
  • 530
  • 4
  • 7
  • 1
    atempo has a range 0 to 2. can't be any x. – Harry Jan 04 '21 at 20:42
  • 2
    atempo now has a range up to 100: https://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=29cddc99cd8302e462bbae572e885e88f63d6dc3 – Armin Samii Feb 11 '22 at 20:15
  • How can we speed up a specific portion of the video given a time range?? – Mary Sep 27 '22 at 14:09
  • the easiest would be splitting the video into chunks, speeding up the desired chunk and stitching them back together – dopexxx Sep 28 '22 at 07:57
  • Related: [Is it possible to speed up video with audio using ffmpeg, without changing audio pitch?](https://superuser.com/q/1324525/53514) – Mateen Ulhaq Jul 12 '23 at 02:03
  • You can leave math expressions in, no need to calculate them yourself, eg 1/1.15 is fine. I would prefer the non-complex filter option: `-vf "setpts=2*PTS" -af "atempo=1/2"`, this way you can use the same command regardless of whether audio is present or not. Also, this will drop frames to slow down a video, you can prevent this by setting a framerate with `-r`. – Mattwmaster58 Aug 30 '23 at 16:03
  • My zsh alias: `alias ffmpeg_speed='(){ffmpeg -hide_banner -i "$2" -vf "setpts=1/($1)*PTS" -af "atempo=$1" -r 60 "$3" ;}'` – Mattwmaster58 Aug 30 '23 at 16:17
8

For a stop-motion project where I wanted to reduce the delay between frames (instead of dropping frames), I wanted to speed up the audio and video many times beyond 2x too. For 60x speed, do the following. It may be a bit verbose, but it works great. The problem is that atempo cannot be greater than two or less than 0.5, so we must repeat atempo many times to get the sound to the rate that we want it.

ffmpeg -i input.mkv -filter:v "setpts=PTS/60" -filter:a "atempo=2,atempo=2,atempo=2,atempo=2,atempo=2,atempo=1.875" output.mkv

Press Ctrl+Shift+I, and click the "console" tab. In the console, to start typing/pasting text, click in the whitespace just right of the blue horizontal chevron (double chevron in FireFox). In Firefox, type allow pasting into the console to allow copy'n'paste, then Ctrl+A then backspace to remove that text. Then, copy and paste this code into the console and press Enter to run. The code also works with slowing down the video.

var speed=eval(prompt("Enter speed up or slowdown factor (>1 is speedup, " +
    "<1 is slowdown; can use 1/X for slowdown): ", "60"));

var k=speed, audio="";
while (2 < k && k === k) k /= 2, audio+="atempo=2,";
while (k < 0.5 && k === k) k *= 2, audio+="atempo=0.5,";
audio += "atempo=" + k;
prompt(
    "Copy the following commandline: ",
    'ffmpeg -i input.mkv -filter:v "setpts=PTS/' + speed +
    '" -filter:a "' + audio + '" output.mkv'
);

This code will prompt you to enter a value and present you with the result. Entering 60 yields a 60X speedup, entering 0.1 yields a 10X slowdown, and entering 1/30 yields a 30X slowdown. I hope this helps.

Jack G
  • 214
  • 2
  • 5
  • From another comment on a different answer, atempo now can be up to 100: https://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=29cddc99cd8302e462bbae572e885e88f63d6dc3 – Mattwmaster58 Aug 30 '23 at 15:59
4

Speed up by 60x, with 60x the original fps

ffmpeg -i input.mkv -filter:v "setpts=PTS/60" -an output.mkv

Speed up by 60x, then resample to 24 fps

ffmpeg -i input.mkv -filter:v "setpts=PTS/60,fps=24" -an output.mkv
  • setpts=PTS/60 divides each frame's presentation time-stamp by 60.
  • fps=24 outputs 24 frames per second.
  • -an removes the audio.
Mateen Ulhaq
  • 3,452
  • 6
  • 35
  • 56
  • 1
    this answer is very helpful, as my goal was to speed up and compress at the same time. Thank you! – Alleo May 08 '23 at 05:51
1

For me, using setpts in conjunction with atempo left the audio rate low (and with low pitch). What finally worked for me is:

#!/bin/sh
# Note: First use ffprobe to get the audio rate.
# Adjust below if it's not 48000.
# The example below increases the speed of audio and video
# rate by a factor of 4 (adjust as needed).
# Sources:
# https://superuser.com/questions/1261678/how-do-i-speed-up-a-video-by-60x-in-ffmpeg
# https://stackoverflow.com/questions/53374590/ffmpeg-change-tone-frequency-pitch-audio
ffmpeg -i $1 -filter:v "setpts=PTS/4" -af "asetrate=48000*4,aresample=48000" out.mp4
StefanQ
  • 151
  • 2
1

Only for video, like timelapses:

ffmpeg -i input.mp4 -map 0:v -c:v copy -bsf:v h264_mp4toannexb raw.h264

ffmpeg -fflags +genpts -r 30 -i raw.h264 -c:v copy output.mp4
ZygD
  • 2,459
  • 12
  • 26
  • 43
0

This will only work on 4.4 and up:

ffmpeg -i input.mkv -bsf:v setts=TS/60 -af atempo=60 -c:v copy output.mkv
FFmpegEnthusiast
  • 308
  • 1
  • 16