0

I need to create a really long video from a looping clip but it needs to fade in at the beginning and fade out at the end. I'm taking the looping segment and using this command:

ffmpeg -stream_loop 128 -i "{input}" -y -c copy "{output_looped}"

followed by:

ffmpeg -i "{output_looped}" -y -vf "fade=t=in:st=0:d=4,fade=t=out:st=1920:d=4" -c:a copy "{output}"

input file and ffmpeg info:

ffmpeg -i input.mp4
ffmpeg version N-94150-g231d0c819f Copyright (c) 2000-2019 the FFmpeg developers
  built with gcc 9.1.1 (GCC) 20190621
  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. 30.100 / 56. 30.100
  libavcodec     58. 53.101 / 58. 53.101
  libavformat    58. 28.101 / 58. 28.101
  libavdevice    58.  7.100 / 58.  7.100
  libavfilter     7. 55.100 /  7. 55.100
  libswscale      5.  4.101 /  5.  4.101
  libswresample   3.  4.100 /  3.  4.100
  libpostproc    55.  4.100 / 55.  4.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'input.mp4':
  Metadata:
    major_brand     : mp42
    minor_version   : 0
    compatible_brands: mp42mp41
    creation_time   : 2020-09-08T22:05:04.000000Z
  Duration: 00:00:13.96, start: 0.000000, bitrate: 24636 kb/s
    Stream #0:0(eng): Video: h264 (Main) (avc1 / 0x31637661), yuv420p(tv, bt709), 1920x1080, 24626 kb/s, 24 fps, 24 tbr, 24k tbn, 48 tbc (default)
    Metadata:
      creation_time   : 2020-09-08T22:05:04.000000Z
      handler_name    : ?Mainconcept Video Media Handler
      encoder         : AVC Coding

However, this is extremely slow because the looped segment is so long and ffmpeg is (presumably) re-encoding it. It would be ideal if I could add the fade out to the beginning and the end of the video without re-encoding the middle section. So perhaps splitting output_looped into 3 sections, applying the fade in to the beginning, leaving the middle the same, and applying the fade out to the end, and then concatenating the streams back together somehow.

Is this possible in ffmpeg? If so, how would you do it? Or is there any other way to avoid re-encoding the middle section while applying a fade in to the beginning and a fade out to the end?

2
  • The complete log from command #1 is required to give you an answer you can copy and paste.
    – llogan
    Commented Sep 9, 2020 at 0:00
  • @llogan, here it is: pastebin.com/Shgbv59X. Please let me know if that's what you were looking for. Thanks! Commented Sep 9, 2020 at 4:29

1 Answer 1

1

Because your original input is fairly short it is fast and simple to only encode the first and last iterations.

  1. Make beginning, middle, and end segments:

    ffmpeg -i input.mp4 -vf "fade=t=in:st=0:d=4" -profile:v main -video_track_timescale 24k -c:a copy begin.mp4
    ffmpeg -stream_loop 126 -i input.mp4 -c copy middle.mp4
    ffmpeg -i input.mp4 -vf "fade=t=out:st=9.96:d=4" -profile:v main -video_track_timescale 24k -c:a copy end.mp4
    
    • All segments must have the same attributes to concatenate properly. By default ffmpeg handles most things, but with your particular file the H.264 profile and timescale had to be manually set so begin.mp4 and end.mp4 match middle.mp4.

    • Your input has no audio, but I added -c:a copy for demonstration purposes in case it did. Does not matter if you use -c:a copy for an input without audio.

  2. Make input.txt containing:

    file 'begin.mp4'
    file 'middle.mp4'
    file 'end.mp4'
    
  3. Concatenate using the concat demuxer:

    ffmpeg -f concat -i input.txt -c copy output.mp4
    
4
  • This works great, athough for some reason VLC Media player crashes at 13 seconds (right when it gets to the loop). Windows media player doesn't have any issues, and neither does After Effects, so I guess it's just a bug in VLC. Commented Sep 9, 2020 at 22:12
  • Another question; suppose the looping segment was much longer. What would you do in that case? Commented Sep 9, 2020 at 22:17
  • 1
    @jippyjoe4 Not sure why VLC is crashing. I would expect the others to crash before VLC. The output from ffmpeg -f concat -i input.txt -c copy output.mp4 may have some clues (such as Non-monotonous DTS messages indicating mismatched timescales for example). As for a much longer input you could do something similar to Cut a video in between key frames without re-encoding the full video using ffmpeg?
    – llogan
    Commented Sep 10, 2020 at 2:50
  • @llogan can you help me I am trying to repeat fade in and fade out on video. But when I applied it, I encountered the difficulty that the video would repeat from the beginning instead of continuing. Is there any solution for this? my code. [0]crop=iw/1.1:ih/1.1,scale=1000:1080,fade=in:st=0:d=3:alpha=1,fade=out:st=6:d=3:alpha=1,loop=999:225,setpts=N/25/TB [ovr];[1]mpdecimate,setpts=N/25/TB[v2];[v2][ovr] overlay=(main_w-overlay_w)/2:(main_h-overlay_h)/2" Commented Jun 17, 2021 at 15:14

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .