How do set output framerate “same as source” in ffmpeg

ffmpegframerate

ffmpeg -i input.3gp -someoptions output.flv

will by default always use a framerate of 30 for output regardless of the framerate of the source file.

I know how to set a given framerate e.g. "-r 15" for 15fps but how do I set the framerate to "same as source"?

Here's the output from ffmpeg:

$ ffmpeg -i video7741.3gp -ar 22050 video7741.flv
ffmpeg version 0.8.3-4:0.8.3-0ubuntu0.12.04.1, Copyright (c) 2000-2012 the Libav developers
  built on Jun 12 2012 16:37:58 with gcc 4.6.3
*** THIS PROGRAM IS DEPRECATED ***
This program is only provided for compatibility and will be removed in a future release. Please use avconv instead.
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'video7741.3gp':
  Metadata:
    major_brand     : 3gp5
    minor_version   : 768
    compatible_brands: 3gp53gp43g2aisom
    creation_time   : 2011-07-13 19:45:38
  Duration: 00:00:08.96, start: 0.000000, bitrate: 78 kb/s
    Stream #0.0(eng): Video: h263, yuv420p, 128x96 [PAR 12:11 DAR 16:11], 64 kb/s, 7.46 fps, 29.97 tbr, 15750 tbn, 29.97 tbc
    Metadata:
      creation_time   : 2011-07-13 19:45:38
    Stream #0.1(eng): Audio: amrnb, 8000 Hz, 1 channels, flt, 12 kb/s
    Metadata:
      creation_time   : 2011-07-13 19:45:38
File 'video7741.flv' already exists. Overwrite ? [y/N] y
[buffer @ 0x91db320] w:128 h:96 pixfmt:yuv420p
Incompatible sample format 'flt' for codec 'adpcm_swf', auto-selecting format 's16'
Output #0, flv, to 'video7741.flv':
  Metadata:
    major_brand     : 3gp5
    minor_version   : 768
    compatible_brands: 3gp53gp43g2aisom
    creation_time   : 2011-07-13 19:45:38
    encoder         : Lavf53.21.0
    Stream #0.0(eng): Video: flv, yuv420p, 128x96 [PAR 12:11 DAR 16:11], q=2-31, 200 kb/s, 1k tbn, 29.97 tbc
    Metadata:
      creation_time   : 2011-07-13 19:45:38
    Stream #0.1(eng): Audio: adpcm_swf, 22050 Hz, 1 channels, s16, 88 kb/s
    Metadata:
      creation_time   : 2011-07-13 19:45:38
Stream mapping:
  Stream #0.0 -> #0.0
  Stream #0.1 -> #0.1
Press ctrl-c to stop encoding
Warning, using s16 intermediate sample format for resampling
Multiple frames in a packet from stream 1
frame=   66 fps=  0 q=5.0 Lsize=     194kB time=8.74 bitrate= 181.4kbits/s    
video:92kB audio:97kB global headers:0kB muxing overhead 2.364636%

Best Answer

Usually, ffmpeg will set the framerate to "same as source" automatically. Just don't specify any -r option to get that behavior.

One notable exception is the case where (1) your source format uses a variable framerate and (2) ffmpeg defaults to a fixed framerate for the output format (happens for MP4 for example). To get a "same as source" framerate in that case, you do (according to this answer):

ffmpeg -i input.3gp -vsync vfr output.flv

Without this option, ffmpeg will use a default framerate that is the same as the source file's container framerate. The container framerate is the maximum value that the source file's variable framerate can possibly have. To compensate for the cases where the variable framerate is lower, ffmpeg then duplicates some input frames in the output file. This leads to a larger output file (7% in one test I did).

To know if your source file uses variable framerate, look at the output of ffprobe input.ext: if it contains both fps and tbr values, then it does use variable framerate. Namely, tbr is the container framerate and fps is the average framerate.