3

I have a very short 120fps video.

ffprobe input.mp4 shows 118.99fps:

ffprobe version 3.0 Copyright (c) 2007-2016 the FFmpeg developers
  built with Apple LLVM version 7.3.0 (clang-703.0.29)
  configuration: --prefix=/usr/local/Cellar/ffmpeg/3.0 --enable-shared --enable-pthreads --enable-gpl --enable-version3 --enable-hardcoded-tables --enable-avresample --cc=clang --host-cflags= --host-ldflags= --enable-opencl --enable-libx264 --enable-libmp3lame --enable-libxvid --enable-ffplay --enable-vda
  libavutil      55. 17.103 / 55. 17.103
  libavcodec     57. 24.102 / 57. 24.102
  libavformat    57. 25.100 / 57. 25.100
  libavdevice    57.  0.101 / 57.  0.101
  libavfilter     6. 31.100 /  6. 31.100
  libavresample   3.  0.  0 /  3.  0.  0
  libswscale      4.  0.100 /  4.  0.100
  libswresample   2.  0.101 /  2.  0.101
  libpostproc    54.  0.100 / 54.  0.100
[h264 @ 0x7f8262009600] Increasing reorder buffer to 1
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'input.mp4':
  Metadata:
    major_brand     : mp42
    minor_version   : 1
    compatible_brands: mp41mp42isom
    creation_time   : 2016-04-27 10:43:14
  Duration: 00:00:02.76, start: 0.000000, bitrate: 10318 kb/s
    Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709), 720x1280, 10272 kb/s, 118.99 fps, 600 tbr, 600 tbn, 1200 tbc (default)
    Metadata:
      creation_time   : 2016-04-27 10:43:14
      handler_name    : Core Media Video

I'm running a square crop and resize operation:

ffmpeg -i input.mp4 -vf "crop='if(gte(iw,ih),ih,iw):if(gte(ih,iw),iw,ih)', scale=640x640" -an -c:v libx264 -profile:v high -level 4.1 -preset veryslow -crf 20 output.mp4

This gives:

....
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'input.mp4':
  Metadata:
    major_brand     : mp42
    minor_version   : 1
    compatible_brands: mp41mp42isom
    creation_time   : 2016-04-27 10:43:14
  Duration: 00:00:02.76, start: 0.000000, bitrate: 10318 kb/s
    Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709), 720x1280, 10272 kb/s, 118.99 fps, 600 tbr, 600 tbn, 1200 tbc (default)
....
Output #0, mp4, to 'output.mp4':
  Metadata:
    major_brand     : mp42
    minor_version   : 1
    compatible_brands: mp41mp42isom
    encoder         : Lavf57.25.100
    Stream #0:0(und): Video: h264 (libx264) ([33][0][0][0] / 0x0021), yuv420p, 640x640, q=-1--1, 600 fps, 19200 tbn, 600 tbc (default)
....

And sure enough, ffprobe output.mp4 confirms that output.mp4 is at 600fps, as does VLC.

How can I ensure that ffmpeg will encode my video using the same framerate as the input (be that 30, 60, 120, or 240fps)?

4

Update: The PTS entries of the input and output for the command below are identical in version N-79630-g9ac154d. Looks like the file is falsely flagged as VFR. But this single-step command below works for the sample video.

Use

ffmpeg -i input.mp4 -vf "crop='if(gte(iw,ih),ih,iw):if(gte(ih,iw),iw,ih)', scale=640x640" \
   -an -c:v libx264 -profile:v high -level 4.1 -preset veryslow -crf 20 -vsync 0 output.mp4

The framerate stored in the container (tbr) is 600, whereas the reported fps of 118.99 is arrived at by counting the number of video packets and dividing by the total duration. If this is not a variable frame rate stream, then add -r 118.99 as an output option.


For older versions, Alternatively, output to MKV i.e.

ffmpeg -i input.mp4 -vf "crop='if(gte(iw,ih),ih,iw):if(gte(ih,iw),iw,ih)', scale=640x640" \
   -vsync 0 -an -c:v libx264 -profile:v high -level 4.1 -preset veryslow -crf 20 output.mkv

If you then mux the MKV to MP4,

ffmpeg -i output.mkv -c copy output.mp4

The resulting MP4 will show (close to) the source framerate.

Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'no-rc.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf57.34.103
  Duration: 00:00:02.75, start: 0.000000, bitrate: 2462 kb/s
    Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 640x640, 2444 kb/s, 119.88 fps, 600 tbr, 16k tbn (default)
| improve this answer | |
  • Thanks - the issue with using -r 118.99 is that the input can be at different framerates. Is there a way to make it dynamic so that -r <value> matches the input fps? – awidgery Apr 28 '16 at 13:12
  • Not directly, but yes, if you go through the MKV method as edited. – Gyan Apr 28 '16 at 13:19
  • Cool workaround - it works. I'm going to leave the question open for a couple of days to see if anyone comes up with a one-step process - if not then I'll accept! – awidgery Apr 29 '16 at 11:22
  • If there's a bug, please file one at trac.ffmpeg.org ... – rogerdpack May 5 '16 at 21:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.