Skip to main content
added 7 characters in body
Source Link
JayCravens
  • 539
  • 3
  • 8
#!/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
added 15 characters in body
Source Link
JayCravens
  • 539
  • 3
  • 8
#!/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
Source Link
JayCravens
  • 539
  • 3
  • 8

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.