-
-
Save coderofsalvation/8dd3cafd0d21d1fa6dd9cb0de8e58628 to your computer and use it in GitHub Desktop.
#!/bin/bash | |
[[ ! -n $3 ]] && { echo "Usage: crossfadevideo <input.mp4> <fade in seconds> <output.mp4> [looptimes]"; exit; } | |
input="$1" | |
fade="$2" | |
duration="$(ffprobe -v error -select_streams v:0 -show_entries stream=duration -of default=noprint_wrappers=1:nokey=1 "$input")" | |
duration=$(echo "$duration-($fade)" | bc | sed 's/\..*//g') | |
[[ ${duration:0:1} == "." ]] && duration="0$duration" | |
output="$3" | |
[[ -n $4 ]] && loop=$4 && output="${output}.mkv" | |
set -x | |
ffmpeg -y -i "$input" -filter_complex ' | |
[0]split[body][pre]; | |
[pre]trim=duration='$fade',format=yuva420p,fade=d='$fade':alpha=1,setpts=PTS+('$(($duration-$fade))'/TB)[jt]; | |
[body]trim='$fade',setpts=PTS-STARTPTS[main]; | |
[main][jt]overlay' "$output" | |
# we use mkv for looping since ffmpeg loops mp4 badly | |
[[ -n $loop ]] && ffmpeg -y -stream_loop $loop -i $output -c copy ${output/\.mkv/} |
Fixed a typo in my fork. Should work now.
My man, this is absolutely beautiful. Thanks for taking the time to take the oneliner into this very usable script.
Duration always returned empty for me so (thanks to this post) I replaced line 5 with
duration=$(ffmpeg -i cut.mp4 2>&1 | grep "Duration"| cut -d ' ' -f 4 | sed s/,// | sed 's@\..*@@g' | awk '{ split($1, A, ":"); split(A[3], B, "."); print 3600*A[1] + 60*A[2] + B[1] }')
Also final loop length was fade
seconds longer than needed, so my setpts
bit looks like setpts=PTS+('$(($duration-$fade))'/TB)[jt]
With that, everything works perfect for me
@mexomagno thank you for the fix, I've integrated it (and added a looptimes
param too)
Version of this script that supports transparent videos: https://gist.github.com/api-haus/e4845156845ce07de1744a5fa45db5be
The last command of the last line deleted all the mkv files in my folder. Luckily I didn't need any of them. But maybe it would be better to fix this
Hi. Can you be so kind to explain me what variables should be changed in the code to make it work for me? Which parts?
When I try to execute it, returns only echo and nothing happens
@weweb1 sure! Please copy/paste the command you typed in your terminal.
Thanks a lot! @coderofsalvation
I directly copied your code from above, making sure that I run it in the folder with the video, and with the video name called input.mp4:
im getting a freeze for fade
seconds at the end of the video (if i do not provide looptimes
), and also between every loop when i do provide looptimes
. any idea how i can fix this?
this is my ffmpeg version
ffmpeg version 6.0 Copyright (c) 2000-2023 the FFmpeg developers
built with Apple clang version 14.0.3 (clang-1403.0.22.14.1)
configuration: --prefix=/opt/homebrew/Cellar/ffmpeg/6.0_1 --enable-shared --enable-pthreads --enable-version3 --cc=clang --host-cflags= --host-ldflags= --enable-ffplay --enable-gnutls --enable-gpl --enable-libaom --enable-libaribb24 --enable-libbluray --enable-libdav1d --enable-libjxl --enable-libmp3lame --enable-libopus --enable-librav1e --enable-librist --enable-librubberband --enable-libsnappy --enable-libsrt --enable-libsvtav1 --enable-libtesseract --enable-libtheora --enable-libvidstab --enable-libvmaf --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libspeex --enable-libsoxr --enable-libzmq --enable-libzimg --disable-libjack --disable-indev=jack --enable-videotoolbox --enable-audiotoolbox --enable-neon
libavutil 58. 2.100 / 58. 2.100
libavcodec 60. 3.100 / 60. 3.100
libavformat 60. 3.100 / 60. 3.100
libavdevice 60. 1.100 / 60. 1.100
libavfilter 9. 3.100 / 9. 3.100
libswscale 7. 1.100 / 7. 1.100
libswresample 4. 10.100 / 4. 10.100
libpostproc 57. 1.100 / 57. 1.100
EDIT: i think this is because im using a file with two streams. removing the audio stream fixes the problem. would be great if we can detect and handle such files in the script
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'input.mp4':
Metadata:
major_brand : mp42
minor_version : 0
compatible_brands: mp42mp41
creation_time : 2021-12-11T19:25:10.000000Z
Duration: 00:00:10.00, start: 0.000000, bitrate: 100323 kb/s
Stream #0:0[0x1](eng): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709, progressive), 3840x2160, 99986 kb/s, 30 fps, 30 tbr, 30k tbn (default)
Metadata:
creation_time : 2021-12-11T19:25:10.000000Z
handler_name : ?Mainconcept Video Media Handler
vendor_id : [0][0][0][0]
encoder : AVC Coding
Stream #0:1[0x2](eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 316 kb/s (default)
Metadata:
creation_time : 2021-12-11T19:25:10.000000Z
handler_name : #Mainconcept MP4 Sound Media Handler
vendor_id : [0][0][0][0]
Awesome ! Thank you for your reply