diff --git a/video-convert b/video-convert index 5291b3f..ae59ea8 100755 --- a/video-convert +++ b/video-convert @@ -1,11 +1,20 @@ #!/bin/bash # Look into HW video encoding to vp9 instead of h264: # https://www.reddit.com/r/VP9/comments/g9uzzv/hardware_encoding_vp9_on_intel/ + fail() { echo "$*" >&2 exit -1 } +VIDEO=$(getent group video | sed -E 's,^video:[^:]*:([^:]*):.*$,\1,') +RENDER=$(getent group render | sed -E 's,^render:[^:]*:([^:]*):.*$,\1,') + +[[ "${VIDEO}" != "" ]] || fail "No video group found." + +ADD_GROUPS="--group-add ${VIDEO}" +[[ "${RENDER}" != "" ]] && ADD_GROUPS+=" --group-add ${RENDER}" + video_detect() { for file in "${*}"; do INFO=($(ffprobe -v error \ @@ -90,7 +99,7 @@ function convert { fi echo -n "Counting frames in ${IN}: " - FRAMES=$(ffprobe -v error -select_streams v:0 -count_packets -show_entries stream=nb_read_packets -of csv=p=0 "${IN}") + FRAMES=$(ffprobe -v error -select_streams v:0 -count_packets -show_entries stream=nb_read_packets -of csv=p=0 "${IN}") || fail "Unable to count frames" echo "${FRAMES} frames." # Use stdbuf to flush stdout/stderr every line @@ -101,16 +110,26 @@ function convert { OUT=$(realpath "${OUT}") DIN=$(dirname "${IN}") DOUT=$(dirname "${OUT}") - NO_COLOR=1 \ - docker run --user=1000 --device=/dev/dri \ + if false; then + quiet=" + -v quiet + -loglevel fatal + " + else + quiet="" + fi + + docker run \ + --device=/dev/dri \ + --user=$(id -u) \ --rm \ + ${ADD_GROUPS} \ -v "${DIN}:${DIN}" \ -v "${DOUT}:${DOUT}" \ intel-media-ffmpeg \ ffmpeg \ + ${quiet} \ -nostdin \ - -v quiet \ - -loglevel fatal \ ${input_flags} \ -i "${IN}" \ -progress /dev/stdout \ @@ -118,26 +137,35 @@ function convert { ${output_flags} \ -movflags +faststart \ "${OUT}" \ - -y | while read line; do - POS=$(echo $line | sed -n 's/^frame=*\(.*\)/\1/p') - if [[ "${POS}" != "" ]]; then - NOW=$(date +%s) - ELAPSEDTIME=$(( NOW - LASTTIME )) - if (( ELAPSEDTIME > 5 )); then - ELAPSEDFRAMES=$(( POS - LASTPOS )) - REMAININGFRAMES=$(( FRAMES - POS )) - REMAININGFRAMES=$(( REMAININGFRAMES * 1000 )) # convert to ms - FRAMERATE=$(( ELAPSEDFRAMES / ELAPSEDTIME )) - if (( FRAMERATE != 0 )); then - REMAININGMS=$(( REMAININGFRAMES / FRAMERATE )) - printf "\r%*s\r%s" $(tput cols) " " "Processing for $(mstodate $(( NOW - STARTTIME ))000). Processing at ($((ELAPSEDFRAMES / ELAPSEDTIME ))fps). Now at frame $POS of $FRAMES $(( $(( 100 * POS)) / FRAMES ))%. Estimating $(mstodate ${REMAININGMS}) remaining." - else - printf "\r%*s\r%s" $(tput cols) " " "Processing for $(mstodate $(( NOW - STARTTIME ))000). Processing at ($((ELAPSEDFRAMES / ELAPSEDTIME ))fps). Now at frame $POS of $FRAMES $(( $(( 100 * POS)) / FRAMES ))%. No frames processed in last ${ELAPSEDTIME} seconds." - fi - LASTTIME=${NOW} - LASTPOS=${POS} - fi + -y || fail "ffmpeg failed" 2>&1 | + while read line; do + if [[ "${line}" == "ffmpeg failed" ]]; then + false + break fi + POS=$(echo $line | sed -n 's/^frame=*\(.*\)/\1/p') + if [[ "${POS}" == "" ]]; then + continue + fi + + NOW=$(date +%s) + ELAPSEDTIME=$(( NOW - LASTTIME )) + if (( ELAPSEDTIME <= 5 )); then + continue + fi + + ELAPSEDFRAMES=$(( POS - LASTPOS )) + REMAININGFRAMES=$(( FRAMES - POS )) + REMAININGFRAMES=$(( REMAININGFRAMES * 1000 )) # convert to ms + FRAMERATE=$(( ELAPSEDFRAMES / ELAPSEDTIME )) + if (( FRAMERATE != 0 )); then + REMAININGMS=$(( REMAININGFRAMES / FRAMERATE )) + printf "\r%*s\r%s" $(tput cols) " " "Processing for $(mstodate $(( NOW - STARTTIME ))000). Processing at ($((ELAPSEDFRAMES / ELAPSEDTIME ))fps). Now at frame $POS of $FRAMES $(( $(( 100 * POS)) / FRAMES ))%. Estimating $(mstodate ${REMAININGMS}) remaining." + else + printf "\r%*s\r%s" $(tput cols) " " "Processing for $(mstodate $(( NOW - STARTTIME ))000). Processing at ($((ELAPSEDFRAMES / ELAPSEDTIME ))fps). Now at frame $POS of $FRAMES $(( $(( 100 * POS)) / FRAMES ))%. No frames processed in last ${ELAPSEDTIME} seconds." + fi + LASTTIME=${NOW} + LASTPOS=${POS} done && move && { if [[ "${ORIG}" == "${IN}" ]]; then # If the original file was an '.mkv' then OUT was '.transcoded.mkv'