#!/bin/bash
mkdir -p temp source
# change source container to mkv with ts to zero
for file in *.mp4; do
filename="${file%.*}"
ffmpeg -hide_banner -i "$file" -c copy -an -avoid_negative_ts make_zero "$filename".mkv && mv "$file" ./source
done
prepare_source() {
for filename in *.mkv; do
file_num=1
ffmpeg -hide_banner -i "$filename" -to 10 -c copy -an -avoid_negative_ts make_zero "$file_num-seg1-$filename"
ffprobe -report -i "$filename"
duration=$(cat ffprobe*.log | grep DURATION | cut -d':' -f2-4 | tr -d ' ')
rm ffprobe*.log
# strip leading zeros
hours=$(echo "$duration" | awk -F: '{print $1}' | sed 's/^0*//')
minutes=$(echo "$duration" | awk -F: '{print $2}' | sed 's/^0*//')
seconds=$(echo "$duration" | awk -F: '{print $3}' | cut -d '.' -f 1 | sed 's/^0*//')
# if fields are 00 then set to 0
hours=${hours:-0}
minutes=${minutes:-0}
seconds=${seconds:-0}
runtime_seconds=$((hours * 3600 + minutes * 60 + seconds))
runtime_minus=$((runtime_seconds - 10))
echo -e "$hours $minutes $seconds\n$runtime_seconds\n$runtime_minus"
ffmpeg -hide_banner -i "$filename" -ss 10 -to "$runtime_minus" -c copy -an -avoid_negative_ts make_zero "to_mux_$file_num-seg2-$filename"
ffmpeg -hide_banner -i "$filename" -ss "$runtime_minus" -c copy -an -avoid_negative_ts make_zero "$file_num-seg3-$filename"
file_num=$((file_num + 1))
done
}
fade_in() {
file_list1=(*seg1*.mkv)
for file1 in "${file_list1[@]}"; do
ffmpeg -hide_banner -y -i "$file1" -vf fade=in:0:60 -an -avoid_negative_ts auto -preset ultrafast "to_mux_$file1"
mv "$file1" ./temp
done
}
fade_out() {
file_list2=(*seg3*.mkv)
for file2 in "${file_list2[@]}"; do
frame_count=$(ffmpeg -i "$file2" -map 0:v:0 -c copy -f null -y /dev/null 2>&1 | grep -Eo 'frame= *[0-9]+ *' | grep -Eo '[0-9]+' | tail -1)
frame_start=$((frame_count - 60))
ffmpeg -hide_banner -y -i "$file2" -vf fade=out:"$frame_start":60 -an -avoid_negative_ts auto -preset ultrafast "to_mux_$file2"
mv "$file2" ./temp
done
}
prepare_source
fade_in
fade_out
ls --quoting-style=shell-always -1v *to_mux_*.mkv > tmp.txt
sed 's/^/file /' tmp.txt > list.txt && rm tmp.txt
ffmpeg -f concat -safe 0 -i list.txt -c copy -avoid_negative_ts auto -movflags +faststart faded_muxed_final.mkv
rm to_mux*to_mux_* list.txt
rm -rf ./temp
exit 0
#!/bin/bash
mkdir -p temp source
# change source container to mkv with ts to zero
for file in *.mp4; do
filename="${file%.*}"
ffmpeg -hide_banner -i "$file" -c copy -an -avoid_negative_ts make_zero "$filename".mkv && mv "$file" ./source
done
prepare_source() {
for filename in *.mkv; do
file_num=1
ffmpeg -hide_banner -i "$filename" -to 10 -c copy -an -avoid_negative_ts make_zero "$file_num-seg1-$filename"
ffprobe -report -i "$filename"
duration=$(cat ffprobe*.log | grep DURATION | cut -d':' -f2-4 | tr -d ' ')
rm ffprobe*.log
# strip leading zeros
hours=$(echo "$duration" | awk -F: '{print $1}' | sed 's/^0*//')
minutes=$(echo "$duration" | awk -F: '{print $2}' | sed 's/^0*//')
seconds=$(echo "$duration" | awk -F: '{print $3}' | cut -d '.' -f 1 | sed 's/^0*//')
# if fields are 00 then set to 0
hours=${hours:-0}
minutes=${minutes:-0}
seconds=${seconds:-0}
runtime_seconds=$((hours * 3600 + minutes * 60 + seconds))
runtime_minus=$((runtime_seconds - 10))
echo -e "$hours $minutes $seconds\n$runtime_seconds\n$runtime_minus"
ffmpeg -hide_banner -i "$filename" -ss 10 -to "$runtime_minus" -c copy -an -avoid_negative_ts make_zero "to_mux_$file_num-seg2-$filename"
ffmpeg -hide_banner -i "$filename" -ss "$runtime_minus" -c copy -an -avoid_negative_ts make_zero "$file_num-seg3-$filename"
file_num=$((file_num + 1))
done
}
fade_in() {
file_list1=(*seg1*.mkv)
for file1 in "${file_list1[@]}"; do
ffmpeg -hide_banner -y -i "$file1" -vf fade=in:0:60 -an -avoid_negative_ts auto -preset ultrafast "to_mux_$file1"
mv "$file1" ./temp
done
}
fade_out() {
file_list2=(*seg3*.mkv)
for file2 in "${file_list2[@]}"; do
frame_count=$(ffmpeg -i "$file2" -map 0:v:0 -c copy -f null -y /dev/null 2>&1 | grep -Eo 'frame= *[0-9]+ *' | grep -Eo '[0-9]+' | tail -1)
frame_start=$((frame_count - 60))
ffmpeg -hide_banner -y -i "$file2" -vf fade=out:"$frame_start":60 -an -avoid_negative_ts auto -preset ultrafast "to_mux_$file2"
mv "$file2" ./temp
done
}
prepare_source
fade_in
fade_out
ls --quoting-style=shell-always -1v *.mkv > tmp.txt
sed 's/^/file /' tmp.txt > list.txt && rm tmp.txt
ffmpeg -f concat -safe 0 -i list.txt -c copy -avoid_negative_ts auto -movflags +faststart faded_muxed_final.mkv
rm to_mux* list.txt
rm -rf ./temp
exit 0
#!/bin/bash
mkdir -p temp source
# change source container to mkv with ts to zero
for file in *.mp4; do
filename="${file%.*}"
ffmpeg -hide_banner -i "$file" -c copy -an -avoid_negative_ts make_zero "$filename".mkv && mv "$file" ./source
done
prepare_source() {
for filename in *.mkv; do
file_num=1
ffmpeg -hide_banner -i "$filename" -to 10 -c copy -an -avoid_negative_ts make_zero "$file_num-seg1-$filename"
ffprobe -report -i "$filename"
duration=$(cat ffprobe*.log | grep DURATION | cut -d':' -f2-4 | tr -d ' ')
rm ffprobe*.log
# strip leading zeros
hours=$(echo "$duration" | awk -F: '{print $1}' | sed 's/^0*//')
minutes=$(echo "$duration" | awk -F: '{print $2}' | sed 's/^0*//')
seconds=$(echo "$duration" | awk -F: '{print $3}' | cut -d '.' -f 1 | sed 's/^0*//')
# if fields are 00 then set to 0
hours=${hours:-0}
minutes=${minutes:-0}
seconds=${seconds:-0}
runtime_seconds=$((hours * 3600 + minutes * 60 + seconds))
runtime_minus=$((runtime_seconds - 10))
echo -e "$hours $minutes $seconds\n$runtime_seconds\n$runtime_minus"
ffmpeg -hide_banner -i "$filename" -ss 10 -to "$runtime_minus" -c copy -an -avoid_negative_ts make_zero "to_mux_$file_num-seg2-$filename"
ffmpeg -hide_banner -i "$filename" -ss "$runtime_minus" -c copy -an -avoid_negative_ts make_zero "$file_num-seg3-$filename"
file_num=$((file_num + 1))
done
}
fade_in() {
file_list1=(*seg1*.mkv)
for file1 in "${file_list1[@]}"; do
ffmpeg -hide_banner -y -i "$file1" -vf fade=in:0:60 -an -avoid_negative_ts auto -preset ultrafast "to_mux_$file1"
mv "$file1" ./temp
done
}
fade_out() {
file_list2=(*seg3*.mkv)
for file2 in "${file_list2[@]}"; do
frame_count=$(ffmpeg -i "$file2" -map 0:v:0 -c copy -f null -y /dev/null 2>&1 | grep -Eo 'frame= *[0-9]+ *' | grep -Eo '[0-9]+' | tail -1)
frame_start=$((frame_count - 60))
ffmpeg -hide_banner -y -i "$file2" -vf fade=out:"$frame_start":60 -an -avoid_negative_ts auto -preset ultrafast "to_mux_$file2"
mv "$file2" ./temp
done
}
prepare_source
fade_in
fade_out
ls --quoting-style=shell-always -1v to_mux_*.mkv > tmp.txt
sed 's/^/file /' tmp.txt > list.txt && rm tmp.txt
ffmpeg -f concat -safe 0 -i list.txt -c copy -avoid_negative_ts auto -movflags +faststart faded_muxed_final.mkv
rm to_mux_* list.txt
rm -rf ./temp
exit 0
#!/bin/bash
mkdir -p temp source
# change source container to mkv with ts to zero
for filenamefile in *.mp4; do
filename="${file%.*}"
ffmpeg -hide_banner -i "$filename""$file" -c copy -an -avoid_negative_ts make_zero "$filename".mkv && mv "$filename""$file" ./source
done
prepare_source() {
for filename in *.mkv; do
file_num=1
ffmpeg -hide_banner -i "$filename" -to 10 -c copy -an -avoid_negative_ts make_zero "$file_num-seg1-$filename"
ffprobe -report -i "$filename"
duration=$(cat ffprobe*.log | grep DURATION | cut -d':' -f2-4 | tr -d ' ')
rm ffprobe*.log
# strip leading zeros
hours=$(echo "$duration" | awk -F: '{print $1}' | sed 's/^0*//')
minutes=$(echo "$duration" | awk -F: '{print $2}' | sed 's/^0*//')
seconds=$(echo "$duration" | awk -F: '{print $3}' | cut -d '.' -f 1 | sed 's/^0*//')
# if fields are 00 then set to 0
hours=${hours:-0}
minutes=${minutes:-0}
seconds=${seconds:-0}
runtime_seconds=$((hours * 3600 + minutes * 60 + seconds))
runtime_minus=$((runtime_seconds - 10))
echo -e "$hours $minutes $seconds\n$runtime_seconds\n$runtime_minus"
ffmpeg -hide_banner -i "$filename" -ss 10 -to "$runtime_minus" -c copy -an -avoid_negative_ts make_zero "to_mux_$file_num-seg2-$filename"
ffmpeg -hide_banner -i "$filename" -ss "$runtime_minus" -c copy -an -avoid_negative_ts make_zero "$file_num-seg3-$filename"
file_num=$((file_num + 1))
done
}
fade_in() {
file_list1=(*seg1*.mkv)
for file1 in "${file_list1[@]}"; do
ffmpeg -hide_banner -y -i "$file1" -vf fade=in:0:60 -an -avoid_negative_ts auto -preset ultrafast "to_mux_$file1"
mv "$file1" ./temp
done
}
fade_out() {
file_list2=(*seg3*.mkv)
for file2 in "${file_list2[@]}"; do
frame_count=$(ffmpeg -i "$file2" -map 0:v:0 -c copy -f null -y /dev/null 2>&1 | grep -Eo 'frame= *[0-9]+ *' | grep -Eo '[0-9]+' | tail -1)
frame_start=$((frame_count - 60))
ffmpeg -hide_banner -y -i "$file2" -vf fade=out:"$frame_start":60 -an -avoid_negative_ts auto -preset ultrafast "to_mux_$file2"
mv "$file2" ./temp
done
}
prepare_source
fade_in
fade_out
ls --quoting-style=shell-always -1v *.mkv > tmp.txt
sed 's/^/file /' tmp.txt > list.txt && rm tmp.txt
ffmpeg -f concat -safe 0 -i list.txt -c copy -avoid_negative_ts auto -movflags +faststart faded_muxed_final.mkv
rm to_mux* list.txt
rm -rf ./temp
exit 0
#!/bin/bash
mkdir -p temp source
# change source container to mkv with ts to zero
for filename in *.mp4; do
ffmpeg -hide_banner -i "$filename" -c copy -an -avoid_negative_ts make_zero "$filename".mkv && mv "$filename" ./source
done
prepare_source() {
for filename in *.mkv; do
file_num=1
ffmpeg -hide_banner -i "$filename" -to 10 -c copy -an -avoid_negative_ts make_zero "$file_num-seg1-$filename"
ffprobe -report -i "$filename"
duration=$(cat ffprobe*.log | grep DURATION | cut -d':' -f2-4 | tr -d ' ')
rm ffprobe*.log
# strip leading zeros
hours=$(echo "$duration" | awk -F: '{print $1}' | sed 's/^0*//')
minutes=$(echo "$duration" | awk -F: '{print $2}' | sed 's/^0*//')
seconds=$(echo "$duration" | awk -F: '{print $3}' | cut -d '.' -f 1 | sed 's/^0*//')
# if fields are 00 then set to 0
hours=${hours:-0}
minutes=${minutes:-0}
seconds=${seconds:-0}
runtime_seconds=$((hours * 3600 + minutes * 60 + seconds))
runtime_minus=$((runtime_seconds - 10))
echo -e "$hours $minutes $seconds\n$runtime_seconds\n$runtime_minus"
ffmpeg -hide_banner -i "$filename" -ss 10 -to "$runtime_minus" -c copy -an -avoid_negative_ts make_zero "to_mux_$file_num-seg2-$filename"
ffmpeg -hide_banner -i "$filename" -ss "$runtime_minus" -c copy -an -avoid_negative_ts make_zero "$file_num-seg3-$filename"
file_num=$((file_num + 1))
done
}
fade_in() {
file_list1=(*seg1*.mkv)
for file1 in "${file_list1[@]}"; do
ffmpeg -hide_banner -y -i "$file1" -vf fade=in:0:60 -an -avoid_negative_ts auto -preset ultrafast "to_mux_$file1"
mv "$file1" ./temp
done
}
fade_out() {
file_list2=(*seg3*.mkv)
for file2 in "${file_list2[@]}"; do
frame_count=$(ffmpeg -i "$file2" -map 0:v:0 -c copy -f null -y /dev/null 2>&1 | grep -Eo 'frame= *[0-9]+ *' | grep -Eo '[0-9]+' | tail -1)
frame_start=$((frame_count - 60))
ffmpeg -hide_banner -y -i "$file2" -vf fade=out:"$frame_start":60 -an -avoid_negative_ts auto -preset ultrafast "to_mux_$file2"
mv "$file2" ./temp
done
}
prepare_source
fade_in
fade_out
ls --quoting-style=shell-always -1v *.mkv > tmp.txt
sed 's/^/file /' tmp.txt > list.txt && rm tmp.txt
ffmpeg -f concat -safe 0 -i list.txt -c copy -avoid_negative_ts auto -movflags +faststart faded_muxed_final.mkv
rm to_mux* list.txt
rm -rf ./temp
exit 0
#!/bin/bash
mkdir -p temp source
# change source container to mkv with ts to zero
for file in *.mp4; do
filename="${file%.*}"
ffmpeg -hide_banner -i "$file" -c copy -an -avoid_negative_ts make_zero "$filename".mkv && mv "$file" ./source
done
prepare_source() {
for filename in *.mkv; do
file_num=1
ffmpeg -hide_banner -i "$filename" -to 10 -c copy -an -avoid_negative_ts make_zero "$file_num-seg1-$filename"
ffprobe -report -i "$filename"
duration=$(cat ffprobe*.log | grep DURATION | cut -d':' -f2-4 | tr -d ' ')
rm ffprobe*.log
# strip leading zeros
hours=$(echo "$duration" | awk -F: '{print $1}' | sed 's/^0*//')
minutes=$(echo "$duration" | awk -F: '{print $2}' | sed 's/^0*//')
seconds=$(echo "$duration" | awk -F: '{print $3}' | cut -d '.' -f 1 | sed 's/^0*//')
# if fields are 00 then set to 0
hours=${hours:-0}
minutes=${minutes:-0}
seconds=${seconds:-0}
runtime_seconds=$((hours * 3600 + minutes * 60 + seconds))
runtime_minus=$((runtime_seconds - 10))
echo -e "$hours $minutes $seconds\n$runtime_seconds\n$runtime_minus"
ffmpeg -hide_banner -i "$filename" -ss 10 -to "$runtime_minus" -c copy -an -avoid_negative_ts make_zero "to_mux_$file_num-seg2-$filename"
ffmpeg -hide_banner -i "$filename" -ss "$runtime_minus" -c copy -an -avoid_negative_ts make_zero "$file_num-seg3-$filename"
file_num=$((file_num + 1))
done
}
fade_in() {
file_list1=(*seg1*.mkv)
for file1 in "${file_list1[@]}"; do
ffmpeg -hide_banner -y -i "$file1" -vf fade=in:0:60 -an -avoid_negative_ts auto -preset ultrafast "to_mux_$file1"
mv "$file1" ./temp
done
}
fade_out() {
file_list2=(*seg3*.mkv)
for file2 in "${file_list2[@]}"; do
frame_count=$(ffmpeg -i "$file2" -map 0:v:0 -c copy -f null -y /dev/null 2>&1 | grep -Eo 'frame= *[0-9]+ *' | grep -Eo '[0-9]+' | tail -1)
frame_start=$((frame_count - 60))
ffmpeg -hide_banner -y -i "$file2" -vf fade=out:"$frame_start":60 -an -avoid_negative_ts auto -preset ultrafast "to_mux_$file2"
mv "$file2" ./temp
done
}
prepare_source
fade_in
fade_out
ls --quoting-style=shell-always -1v *.mkv > tmp.txt
sed 's/^/file /' tmp.txt > list.txt && rm tmp.txt
ffmpeg -f concat -safe 0 -i list.txt -c copy -avoid_negative_ts auto -movflags +faststart faded_muxed_final.mkv
rm to_mux* list.txt
rm -rf ./temp
exit 0
Here's a bash script to splice the fades into the video's
It then merges into a single file.
#!/bin/bash
mkdir -p temp source
# change source container to mkv with ts to zero
for filename in *.mp4; do
ffmpeg -hide_banner -i "$filename" -c copy -an -avoid_negative_ts make_zero "$filename".mkv && mv "$filename" ./source
done
prepare_source() {
for filename in *.mkv; do
file_num=1
ffmpeg -hide_banner -i "$filename" -to 10 -c copy -an -avoid_negative_ts make_zero "$file_num-seg1-$filename"
ffprobe -report -i "$filename"
duration=$(cat ffprobe*.log | grep DURATION | cut -d':' -f2-4 | tr -d ' ')
rm ffprobe*.log
# strip leading zeros
hours=$(echo "$duration" | awk -F: '{print $1}' | sed 's/^0*//')
minutes=$(echo "$duration" | awk -F: '{print $2}' | sed 's/^0*//')
seconds=$(echo "$duration" | awk -F: '{print $3}' | cut -d '.' -f 1 | sed 's/^0*//')
# if fields are 00 then set to 0
hours=${hours:-0}
minutes=${minutes:-0}
seconds=${seconds:-0}
runtime_seconds=$((hours * 3600 + minutes * 60 + seconds))
runtime_minus=$((runtime_seconds - 10))
echo -e "$hours $minutes $seconds\n$runtime_seconds\n$runtime_minus"
ffmpeg -hide_banner -i "$filename" -ss 10 -to "$runtime_minus" -c copy -an -avoid_negative_ts make_zero "to_mux_$file_num-seg2-$filename"
ffmpeg -hide_banner -i "$filename" -ss "$runtime_minus" -c copy -an -avoid_negative_ts make_zero "$file_num-seg3-$filename"
file_num=$((file_num + 1))
done
}
fade_in() {
file_list1=(*seg1*.mkv)
for file1 in "${file_list1[@]}"; do
ffmpeg -hide_banner -y -i "$file1" -vf fade=in:0:60 -an -avoid_negative_ts auto -preset ultrafast "to_mux_$file1"
mv "$file1" ./temp
done
}
fade_out() {
file_list2=(*seg3*.mkv)
for file2 in "${file_list2[@]}"; do
frame_count=$(ffmpeg -i "$file2" -map 0:v:0 -c copy -f null -y /dev/null 2>&1 | grep -Eo 'frame= *[0-9]+ *' | grep -Eo '[0-9]+' | tail -1)
frame_start=$((frame_count - 60))
ffmpeg -hide_banner -y -i "$file2" -vf fade=out:"$frame_start":60 -an -avoid_negative_ts auto -preset ultrafast "to_mux_$file2"
mv "$file2" ./temp
done
}
prepare_source
fade_in
fade_out
ls --quoting-style=shell-always -1v *.mkv > tmp.txt
sed 's/^/file /' tmp.txt > list.txt && rm tmp.txt
ffmpeg -f concat -safe 0 -i list.txt -c copy -avoid_negative_ts auto -movflags +faststart faded_muxed_final.mkv
rm to_mux* list.txt
rm -rf ./temp
exit 0
Save as: fade_splice.sh
Make executable: chmod +x fade_splice.sh
Usage: ./fade_splice.sh
Run from the directory containing only the trimmed files.