Я написал это bash, чтобы автоматизировать объединение видео для потоковой передачи da sh mpeg бесконечно l oop. Я не могу получить одинаковую продолжительность для аудио и видео, с видео, которые я использую для тестирования, я всегда получаю на 6 мс больше для звуковой дорожки. Может попросить помочь отладить его и понять, как получить одинаковую длительность как для аудио, так и для видео дорожки?
#!/bin/bash
#CANCAT 0.3
cd input
fps=()
# GET FPS OF EACH VIDEO INTO ARRAY
for f in *.mp4; do
_f=$(ffmpeg -i "$f" 2>&1 | sed -n "s/.*, \\(.*\\) fp.*/\\1/p")
fps+=("$_f")
done
#GET NUMBER OF ELEMENTS IN FPS ARRAY
tLen=${#fps[@]}
#CHECK FPS EQUALITY
for tLen in "${fps[@]:1}"; do
if [[ $tLen != ${fps[0]} ]]; then
printf "WARNING: VIDEO’S FRAME-RATE ARE NOT EQUALS, THE PROCESS CAN’T START."
printf "%s\\0" "${fps[@]}" |
sort -zu |
xargs -0 printf " %s"
printf "\\n"
exit 1
fi
done
#AUDIO ENCODING
for f in *.mp4;
do
NAME=$(echo "$f" | cut -d'.' -f1)
ffmpeg -y -i "$f" -c copy -video_track_timescale 90k -c:a aac -b:a 384k -ar 44100 -ac 2 -shortest -af aresample=async=1 ../buffer/${NAME}_buffer.mp4
done
#-af aresample=async=1000
#-filter_complex " [1:0] apad "
cd ..
cd buffer
times=()
for f in *.mp4;
do
echo "file '$f'" >> list.txt;
# GET DURATION OF EACH VIDEO
_t=$(ffprobe -i "$f" -show_entries format=duration -v quiet -of csv="p=0")
times+=("$_t")
done
#SUM ALL DURATIONS
TOTALDURATION=$( echo "${times[@]}" | sed 's/ /+/g' | bc )
DURROUND=$(echo "$TOTALDURATION" | cut -d'.' -f1)
TOTDELTA="$((DURROUND%2))"
TOTDUR="$(($DURROUND-$TOTDELTA))"
#GET FPS
FPS="$(ffmpeg -i ${f[0]} 2>&1 | sed -n "s/.*, \(.*\) fp.*/\1/p")"
#ROUND FPS
FPSC=$( echo "($FPS+0.5)/1" | bc )
#GET GOP
GOP="$((FPSC*2))"
#ENCODING MASTER TRACK
ffmpeg -f concat -safe 0 -y -i list.txt -loop 1 -i ../logo/logo.png -c:a copy -c:v libx264 -x264opts keyint=$GOP:min-keyint=$GOP:no-scenecut -bf 0 -r $FPSC -b:v 4800k -maxrate 9600k -bufsize 19200k -profile:v main -crf 22 -filter_complex "[0:v][1:v]overlay=main_w-overlay_w-10:10,scale=1920:1080,setsar=1" -t $TOTDUR 1080set.mp4
#EXTRACTING AUDIO FROM MASTER VIDEO TRACK
ffmpeg -y -i 1080set.mp4 -c copy -vn ../output/output_audio.mp4
#REMOVE AUDIO FROM MASTER VIDEO TRACK
ffmpeg -y -i 1080set.mp4 -c copy -an ../output/output_1080.mp4
#CLEAN BUFFER
rm *.mp4
rm *.txt
cd ..
cd output
#ENCODE 720p
ffmpeg -y -i output_1080.mp4 -an -c:v libx264 -x264opts keyint=$GOP:min-keyint=$GOP:no-scenecut -bf 0 -s 1280x720 -r $FPSC -b:v 2400k -maxrate 4800k -bufsize 9600k -profile:v main -crf 22 output_720.mp4
#ENCODE 360p
ffmpeg -y -i output_1080.mp4 -an -c:v libx264 -x264opts keyint=$GOP:min-keyint=$GOP:no-scenecut -bf 0 -s 640x360 -r $FPSC -b:v 800k -maxrate 1600k -bufsize 3200k -profile:v main -crf 22 output_360.mp4
#VALIDATOR
echo 1080p ENCODING
echo GOP: $GOP
echo VIDEO FORMAT CONTAINER DURATION:
ffprobe -v error -show_entries format=duration \
-of default=noprint_wrappers=1:nokey=1 output_1080.mp4
echo VIDEO STREAM DURATION:
ffprobe -v error -select_streams v:0 -show_entries stream=duration \
-of default=noprint_wrappers=1:nokey=1 output_1080.mp4
echo AUDIO FORMAT CONTAINER DURATION:
ffprobe -v error -show_entries format=duration \
-of default=noprint_wrappers=1:nokey=1 output_audio.mp4
echo ______________________________________________________________
echo 720p ENCODING
echo GOP: $GOP
echo VIDEO FORMAT CONTAINER DURATION:
ffprobe -v error -show_entries format=duration \
-of default=noprint_wrappers=1:nokey=1 output_720.mp4
echo VIDEO STREAM DURATION:
ffprobe -v error -select_streams v:0 -show_entries stream=duration \
-of default=noprint_wrappers=1:nokey=1 output_720.mp4
echo DONE
exit 1
Вот скрипт с моими видео для тестовых и относительных папок: https://gofile.io/?c=WPAC0Q