ffmpeg: соответствует продолжительности аудио-видео после объединения - PullRequest
0 голосов
/ 20 января 2020

Я написал это 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...