tc-video-generic: big refactoring using ffprobe
parent
a71718abcb
commit
5706de388d
|
@ -141,12 +141,6 @@ if ! command -v ffmpeg >/dev/null; then
|
|||
exit
|
||||
fi
|
||||
|
||||
_duration()
|
||||
{
|
||||
## In seconds.
|
||||
ffmpeg -nostdin -i "$1" 2>&1 | awk '/Duration/ {split($2, time, /:|\./); print time[1]*60*60 + time[2]*60 + time[3]}'
|
||||
}
|
||||
|
||||
_highfreq()
|
||||
{
|
||||
awk 'BEGIN{max=0} /crop=/ {t[$NF]++; if (t[$NF]>max) {max=t[$NF]; val=$NF}} END{print val}'
|
||||
|
@ -157,7 +151,7 @@ _cropvalue()
|
|||
## For 5 different timeslices of 1 second at every 1/6th of the video, we
|
||||
## sample the crop values. We keep the values with highest frequency. This
|
||||
## is much faster than encoding in one pass with low framerate.
|
||||
STEP=$(($(_duration "$1")/6))
|
||||
STEP=$((${format_duration:-$streams_stream_0_duration}/6))
|
||||
for i in $(seq $STEP $STEP $((5*$STEP))); do
|
||||
ffmpeg -nostdin -ss $i -i "$1" -t 10 -vf "cropdetect=24:2:0" -f null - 2>&1
|
||||
done | _highfreq
|
||||
|
@ -165,7 +159,7 @@ _cropvalue()
|
|||
|
||||
_croppreview()
|
||||
{
|
||||
STEP=$(($(_duration "$1")/6))
|
||||
STEP=$((${format_duration:-$streams_stream_0_duration}/6))
|
||||
for i in $(seq $STEP $STEP $((5*$STEP))); do
|
||||
ffmpeg -nostdin -v warning -y -ss $i -i "$1" \
|
||||
-f image2 -vframes 1 $VIDEO_FILTER "${1%.*}-preview-$i-cropped.png" \
|
||||
|
@ -173,23 +167,29 @@ _croppreview()
|
|||
done
|
||||
}
|
||||
|
||||
## Return the audio encoding parameters. For instance
|
||||
## -c:2 libvorbis -b:2 384k -c:5 copy
|
||||
## If some stream bitrates are missing, we have two possibilities:
|
||||
## either we copy the stream (default), or we encode it to a default value.
|
||||
_audiobitrate()
|
||||
{
|
||||
## As of 2013-10-23, ffmpeg sucks at retrieving audio bitrate. Therefore we
|
||||
## use mediainfo if available, ffmpeg otherwise.
|
||||
local bitrate
|
||||
|
||||
## In the end, if some stream bitrates are missing, we have two
|
||||
## possibilities: either we copy the stream (default), or we encode it to a
|
||||
## default value.
|
||||
for i in $(seq 0 $(($format_nb_streams-1)) ); do
|
||||
## Skip non audio tracks.
|
||||
[ "$(eval echo \$streams_stream_${i}_codec_type)" != "audio" ] && continue
|
||||
|
||||
## AWK note: in "(bitrate+0 > 500)", the +0 is required to make sure bitrate is numeric.
|
||||
if command -v mediainfo >/dev/null; then
|
||||
## WARNING: mediainfo puts a space every 3 digits, hence the 'for' loop.
|
||||
mediainfo "$1" | awk 'BEGIN {id=0} /^Audio/ { while(getline && ! index($0,"Bit rate ") && NF != 0); for(i=4; i<NF; i++) res=res $i; print id, res; id++}'
|
||||
else
|
||||
ffmpeg -nostdin -i "$1" 2>&1 | awk 'BEGIN {id=0} /^ *Stream.*Audio/ {match($0, / [^ ]+ kb\/s/); res=substr($0, RSTART+1, RLENGTH-6); print id, res; id++}'
|
||||
fi | awk -v codec="$AUDIO_CODEC" -v bitrate="$AUDIO_DEFAULT_RATE" \
|
||||
'{if($2 || bitrate) {if($2) bitrate=$2; if(bitrate+0 > 500) bitrate=500; printf "-c:a:" $1 " " codec " -b:a:" $1 " " bitrate "k "} else printf "-c:a:" $1 " copy "} END {print ""}'
|
||||
bitrate=$(( $(eval echo \$streams_stream_${i}_bit_rate) / 1000))
|
||||
if [ -z "$bitrate" ] || [ "$bitrate" -le 0 ]; then
|
||||
bitrate="$AUDIO_DEFAULT_RATE"
|
||||
fi
|
||||
if [ -n "$bitrate" ] && [ "$bitrate" -gt 0 ]; then
|
||||
[ $bitrate -gt 500 ] && bitrate=500
|
||||
printf -- "-c:%s %s -b:%s %sk " $i "$AUDIO_CODEC" $i "$bitrate"
|
||||
else
|
||||
printf -- "-c:%s copy " $i
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
_transcode()
|
||||
|
@ -198,10 +198,18 @@ _transcode()
|
|||
OUTPUT="${1%.*}.$EXT"
|
||||
[ -e "$OUTPUT" ] && OUTPUT="${1%.*}-$(date '+%F-%H%M%S').$EXT"
|
||||
|
||||
## Metadata (i.e. tags + technical data).
|
||||
_buffer="$(ffprobe -v quiet -print_format flat=s=_ -show_streams -show_format "$1")"
|
||||
if [ $? -ne 0 ]; then
|
||||
_error "File [$1] is unsupported by FFmpeg."
|
||||
return
|
||||
fi
|
||||
eval "$_buffer"
|
||||
unset _buffer
|
||||
|
||||
STREAM_TITLE=""
|
||||
if $OPT_REMOVE_TITLE; then
|
||||
STREAM_NUM=$(ffmpeg -nostdin -i "$1" 2>&1 | grep -c 'Stream')
|
||||
for i in $(seq 0 $STREAM_NUM); do
|
||||
for i in $(seq 0 $(($format_nb_streams-1)) ); do
|
||||
STREAM_TITLE="${STREAM_TITLE}-metadata:s:$i title= "
|
||||
done
|
||||
fi
|
||||
|
@ -237,11 +245,6 @@ EOF
|
|||
|
||||
$OPT_PREVIEW && return
|
||||
|
||||
## Zsh compatibility. We need it otherwise word splitting of parameter like
|
||||
## SAMPLE will not work.
|
||||
STATUS="$(set -o | awk '/shwordsplit / {print $2}')"
|
||||
[ "$STATUS" = "off" ] && set -o shwordsplit
|
||||
|
||||
ffmpeg -nostdin $OVERWRITE -i "$1" \
|
||||
$VIDEO_PARAM $VIDEO_FILTER \
|
||||
$AUDIO_PARAM \
|
||||
|
@ -249,10 +252,6 @@ EOF
|
|||
-map 0 $STREAM_TITLE \
|
||||
$SAMPLE $TC_VIDEO_OPT "$OUTPUT"
|
||||
|
||||
## Restore Zsh previous options. This will not turn off shwordsplit if it
|
||||
## was on before calling the function.
|
||||
[ "$STATUS" = "off" ] && set +o shwordsplit
|
||||
|
||||
if $OPT_OVERWRITE; then
|
||||
rm "$1"
|
||||
mv -f "$OUTPUT" "${1%.*}.$EXT"
|
||||
|
|
Loading…
Reference in New Issue