Trimming to milllisecond in FFmpeg causing massive slowdown in processing speed

1

I'm new here, first time joining a forum site like this so my sincerest apologies if I suck! Thanks in advance for your patience. I'm running Windows CMD on my laptop.

I am trying to trim (delete) the first 7.3 seconds out of a dance video which has audio synced to those moves. Here's the line of code I started out with:

ffmpeg -ss 7.3 -i myVideo.mp4 -c copy trimmed.mp4

While this edit happens instantly (great), the millisecond gets ignored and the resulting output file is trimmed starting at 7 seconds rather than 7.3. So then I tried revising to the following (by switching order of inputs):

ffmpeg -i myVideo.mp4 -ss 7.3 -c copy trimmed.mp4

Here, the edit was again instantaneous (great) AND cut at the correct millisecond level of detail, however a delay on my audio was introduced (rendering the edited video useless). I'm currently using generic software 'Movies & TV' to playback the video, but will eventually be uploading these videos to Vimeo, from where they'll be streamed across multiple devices.

I looked all over and found only one solution:

ffmpeg -ss 7.3 -i myVideo.mp4 -c:v libx264 -c:a aac trimmed.mp4

While this works accurately, it unfortunately ends up taking ~45 minutes to process for a 450 MB file. I have about 800 similar videos to edit (all of which have the same exact intro that needs to be trimmed out) and was wondering if there's any way to get the millisecond level of precision without creating the massive processing slowdown? Or perhaps I could otherwise solve this problem through a faster computer? I'm open to any and all ideas, thank you so so much for your help!

Here is the uncut command line output from my second command:

ffmpeg -i myVideo.mp4 -ss 7.3 -c copy trimmed.mp4
ffmpeg version N-94576-g1965161ef6 Copyright (c) 2000-2019 the FFmpeg developers
  built with gcc 9.1.1 (GCC) 20190807
  configuration: --enable-gpl --enable-version3 --enable-sdl2 --enable-fontconfig --enable-gnutls --enable-iconv --enable-libass --enable-libdav1d --enable-libbluray --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libtheora --enable-libtwolame --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libzimg --enable-lzma --enable-zlib --enable-gmp --enable-libvidstab --enable-libvorbis --enable-libvo-amrwbenc --enable-libmysofa --enable-libspeex --enable-libxvid --enable-libaom --enable-libmfx --enable-amf --enable-ffnvcodec --enable-cuvid --enable-d3d11va --enable-nvenc --enable-nvdec --enable-dxva2 --enable-avisynth --enable-libopenmpt
  libavutil      56. 33.100 / 56. 33.100
  libavcodec     58. 55.100 / 58. 55.100
  libavformat    58. 31.101 / 58. 31.101
  libavdevice    58.  9.100 / 58.  9.100
  libavfilter     7. 58.100 /  7. 58.100
  libswscale      5.  6.100 /  5.  6.100
  libswresample   3.  6.100 /  3.  6.100
  libpostproc    55.  6.100 / 55.  6.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'myVideo.mp4':
  Metadata:
    major_brand     : mp42
    minor_version   : 1
    compatible_brands: mp41mp42isom
    creation_time   : 2019-07-18T19:40:35.000000Z
  Duration: 00:03:37.25, start: 0.000000, bitrate: 20007 kb/s
    Stream #0:0(eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 126 kb/s (default)
    Metadata:
      creation_time   : 2019-07-18T19:40:35.000000Z
      handler_name    : Core Media Audio
    Stream #0:1(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709, progressive), 1920x1080 [SAR 1:1 DAR 16:9], 19864 kb/s, 29.97 fps, 29.97 tbr, 30k tbn, 60k tbc (default)
    Metadata:
      creation_time   : 2019-07-18T19:40:35.000000Z
      handler_name    : Core Media Video
Output #0, mp4, to 'trimmed.mp4':
  Metadata:
    major_brand     : mp42
    minor_version   : 1
    compatible_brands: mp41mp42isom
    encoder         : Lavf58.31.101
    Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709, progressive), 1920x1080 [SAR 1:1 DAR 16:9], q=2-31, 19864 kb/s, 29.97 fps, 29.97 tbr, 30k tbn, 30k tbc (default)
    Metadata:
      creation_time   : 2019-07-18T19:40:35.000000Z
      handler_name    : Core Media Video
    Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 126 kb/s (default)
    Metadata:
      creation_time   : 2019-07-18T19:40:35.000000Z
      handler_name    : Core Media Audio
Stream mapping:
  Stream #0:1 -> #0:0 (copy)
  Stream #0:0 -> #0:1 (copy)
Press [q] to stop, [?] for help
frame= 6271 fps=2425 q=-1.0 Lsize=  523124kB time=00:03:29.93 bitrate=20412.9kbits/s speed=81.2x
video:519589kB audio:3357kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.034075%

stopper0607

Posted 2019-08-22T05:18:37.417

Reputation: 13

Please show the full, uncut command line output of the first ffmpeg command. In which software are you playing the resulting trimmed video that exhibits audio delay? – slhck – 2019-08-22T06:53:41.210

Hey there - thanks so much. I added the requested information as well as additional clarification (I noticed one typo on my original post regarding the order of the inputs, which is now fixed). – stopper0607 – 2019-08-22T19:28:11.603

Thanks for the updates. I'd recommend you try with VLC or do a test upload to see how Vimeo treats the file. – slhck – 2019-08-22T19:38:19.350

Answers

0

When you're cutting a video with bitstream copy (-c copy), you cannot cut at arbitrary timestamps. A video can only be cut at key frames (intra frames or I-frames), as these frames do not require other frames to be present in the bitstream in order to be decoded.

What ffmpeg will do is that it'll still include all the frames required for frame at the point you specified (7.2 s) to be decodable. This means that your cut video might contain as many frames as your original one. ffmpeg will however assign these frames a negative timestamp so that they should not be shown — not all players respect that though. This may lead to A/V sync issues.

Either way, the only method to achieve full accuracy here is to re-encode the video, as you've shown in your second command. The only way to speed this up is to use a faster CPU, use a faster GPU encoder (e.g. NVENC if you have a supported NVIDIA GPU), or allow the encoder to disable some features, which will make the output file a little larger (encoding will be less efficient). See the H.264 encoding guide for more info. Example:

ffmpeg -ss 7.3 -i myVideo.mp4 -c:v libx264 -preset faster -c:a aac trimmed.mp4

The -preset value can be set to other presets according to how much patience you have for encoding.

slhck

Posted 2019-08-22T05:18:37.417

Reputation: 182 472

super helpful. one question for clarification: if i use a specific number of frames rather than an amount of time, might that solve the problem? – stopper0607 – 2019-08-22T19:29:15.267

If you know where the keyframe is, you can specify that as the input timestamp. But the process is a little bit more complex. You can get the closest keyframe to a certain timestamp as shown here: https://superuser.com/a/554679/48078

– slhck – 2019-08-22T19:40:32.827