Removed old video-convert script
Signed-off-by: James Ketrenos <jketreno@media.ketrenos.com>
This commit is contained in:
parent
9815116d77
commit
a70b1fc11b
281
video-convert
281
video-convert
@ -1,281 +0,0 @@
|
||||
#!/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/
|
||||
|
||||
log_file=""
|
||||
|
||||
force=0
|
||||
if [[ "$1" == "-f" ]]; then
|
||||
force=1
|
||||
shift
|
||||
fi
|
||||
|
||||
fail() {
|
||||
echo "$*" >&2
|
||||
if [[ -e ${log_file} ]]; then
|
||||
rm ${log_file}
|
||||
fi
|
||||
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 \
|
||||
-select_streams v:0 \
|
||||
-show_entries stream=codec_name:format=format_name \
|
||||
-of default=noprint_wrappers=1:nokey=1 "${file}"))
|
||||
if (( ${#INFO[*]} != 2 )); then
|
||||
echo "${file}|none|none"
|
||||
else
|
||||
echo "${file}|${INFO[0]}|${INFO[1]}"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# mstodate MILLISECONDS
|
||||
#
|
||||
# Given MILLISECONDS, convert to DAYS:HOURS:MINUTES:SECONDS.MS
|
||||
mstodate() {
|
||||
scales=( "86400-d:" "3600-h:-02" "60-m:-02" "1-.-02" )
|
||||
echo $1 | sed -E 's/([[:digit:]]{3})$/ \1/' | while read sec msec; do
|
||||
for scale in ${scales[@]}; do
|
||||
parts=(${scale//-/ })
|
||||
divisor=${parts[0]}
|
||||
suffix=${parts[1]}
|
||||
min=${parts[2]}
|
||||
num_scale=$((sec / divisor))
|
||||
sec=$((sec - (num_scale * divisor)))
|
||||
printf "%${min}d%s" ${num_scale} ${suffix}
|
||||
done
|
||||
echo "${msec}s"
|
||||
done
|
||||
}
|
||||
|
||||
function move_to_backup {
|
||||
IN="$1"
|
||||
base="$(dirname "${IN}")"
|
||||
if [ ! -d "${base}" ]; then
|
||||
continue
|
||||
fi
|
||||
base=/multimedia/backup"${base}"
|
||||
if [ ! -d "${base}" ]; then
|
||||
mkdir -p "${base}" || fail "Unable to mkdir '${base}'"
|
||||
fi
|
||||
if [ -d "${base}" ]; then
|
||||
mv "${IN}" "${base}"/ || fail "Unable to move '$IN'"
|
||||
fi
|
||||
}
|
||||
|
||||
function convert {
|
||||
IN="$1"
|
||||
SRC_CODEC="$2"
|
||||
FORMAT="$3"
|
||||
current="$4"
|
||||
total="$5"
|
||||
IN="$(realpath "${IN}")"
|
||||
OUT="${IN/%.???/.mkv}"
|
||||
ORIG="${OUT}"
|
||||
if [[ "${OUT}" == "${IN}" ]]; then
|
||||
OUT="${OUT/.mkv/.transcoded.mkv}"
|
||||
fi
|
||||
|
||||
width=0
|
||||
eval $(ffprobe -v error -show_entries 'stream=width' -select_streams v "${IN}" | grep width)
|
||||
if (( width == 0 )); then
|
||||
fail "Unable to determine width of ${IN}"
|
||||
fi
|
||||
if (( width > 1920 )); then
|
||||
echo "Limiting width to 1920"
|
||||
width=1920
|
||||
fi
|
||||
|
||||
TITLE="${IN%.*}"
|
||||
TITLE="${TITLE##*/}"
|
||||
if [[ "${SRC_CODEC}" == "h264" ]]; then
|
||||
if (( force == 1 )); then
|
||||
input_flags="
|
||||
-hwaccel qsv
|
||||
"
|
||||
# HW decode here gives a MXF device error. Not sure why.
|
||||
# -c:v h264_qsv
|
||||
output_flags="
|
||||
-c copy
|
||||
-c:v h264_qsv
|
||||
-vf hwupload=extra_hw_frames=64
|
||||
-vf vpp_qsv=format=nv12,scale_qsv=w=${width}
|
||||
-global_quality 20
|
||||
"
|
||||
else
|
||||
echo "${current}/${total}: Content will have format changed from ${FORMAT}/h264 to mkv/h264."
|
||||
# Just change container to matroska
|
||||
input_flags="
|
||||
"
|
||||
output_flags="
|
||||
-c copy
|
||||
"
|
||||
fi
|
||||
else
|
||||
echo "${current}/${total}: Content will be transcoded from ${FORMAT}/${SRC_CODEC} to mkv/h264."
|
||||
# Convert all video streams to h264. Copy all other streams unchanged (audio, subtitle, etc.)
|
||||
# Move headers to start of the file for fast start
|
||||
# Use "reasonable" quality level of 20, slow encode
|
||||
#
|
||||
input_flags="
|
||||
-hwaccel qsv
|
||||
-c:v hevc_qsv
|
||||
"
|
||||
output_flags="
|
||||
-c copy
|
||||
-vf vpp_qsv=format=nv12,scale_qsv=${width}
|
||||
-c:v h264_qsv
|
||||
-global_quality 20
|
||||
"
|
||||
fi
|
||||
|
||||
echo -n "${current}/${total}: 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}") || fail "Unable to count frames"
|
||||
echo "${current}/${total}: ${FRAMES} frames."
|
||||
|
||||
if [[ "${ORIG}" != "${OUT}" ]]; then
|
||||
echo "${current}/${total}: Output file will be $(basename "${OUT}")."
|
||||
fi
|
||||
|
||||
# Use stdbuf to flush stdout/stderr every line
|
||||
STARTTIME=$(date +%s)
|
||||
LASTTIME=${STARTTIME}
|
||||
LASTPOS=0
|
||||
DIN="$(dirname "${IN}")"
|
||||
DOUT="$(dirname "${OUT}")"
|
||||
quiet="
|
||||
-v quiet
|
||||
-loglevel error
|
||||
"
|
||||
# quiet=""
|
||||
|
||||
log_file=$(mktemp)
|
||||
{
|
||||
docker run \
|
||||
--device=/dev/dri \
|
||||
--user=$(id -u) \
|
||||
--rm \
|
||||
${ADD_GROUPS} \
|
||||
-v "${DIN}":"${DIN}" \
|
||||
-v "${DOUT}":"${DOUT}" \
|
||||
intel-media-ffmpeg \
|
||||
ffmpeg \
|
||||
${quiet} \
|
||||
-nostdin \
|
||||
${input_flags} \
|
||||
-i "${IN}" \
|
||||
-progress /dev/stdout \
|
||||
-metadata title="${TITLE/.\//}" \
|
||||
${output_flags} \
|
||||
-movflags +faststart \
|
||||
"${OUT}" \
|
||||
-y || { echo "FFMPEG failed" | tee ${log_file} ; false ; }
|
||||
} | while read line; do
|
||||
if [[ "${line}" == "FFMPEG failed" ]]; then
|
||||
cat ${log_file}
|
||||
fail "Terminating"
|
||||
false
|
||||
break
|
||||
fi
|
||||
POS=$(echo $line | sed -n 's/^frame=*\(.*\)/\1/p')
|
||||
if [[ "${POS}" == "" ]]; then
|
||||
true
|
||||
continue
|
||||
fi
|
||||
|
||||
NOW=$(date +%s)
|
||||
ELAPSEDTIME=$(( NOW - LASTTIME ))
|
||||
if (( ELAPSEDTIME <= 5 )); then
|
||||
true
|
||||
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) " " "${current}/${total}: $(mstodate $(( NOW - STARTTIME ))000). Transcode $((ELAPSEDFRAMES / ELAPSEDTIME ))fps. Frame $POS of $FRAMES $(( $(( 100 * POS)) / FRAMES ))%. ETA $(mstodate ${REMAININGMS}) remaining."
|
||||
else
|
||||
printf "\r%*s\r%s" $(tput cols) " " "${current}/${total}: $(mstodate $(( NOW - STARTTIME ))000). Transcode $((ELAPSEDFRAMES / ELAPSEDTIME ))fps. Frame $POS of $FRAMES $(( $(( 100 * POS)) / FRAMES ))%. No frames processed in last ${ELAPSEDTIME} seconds."
|
||||
fi
|
||||
LASTTIME=${NOW}
|
||||
LASTPOS=${POS}
|
||||
done || fail 'Unable to transcode'
|
||||
|
||||
if grep -q "FFMPEG failed" ${log_file}; then
|
||||
exit -1
|
||||
fi
|
||||
|
||||
move_to_backup "${IN}"
|
||||
|
||||
if [[ "${ORIG}" == "${IN}" ]]; then
|
||||
# If the original file was an '.mkv' then OUT was '.transcoded.mkv'
|
||||
# during transcode. Now that the transcode is complete, set the
|
||||
# file back to the original name.
|
||||
mv "${OUT}" "${IN}" || fail "Unable to mv '${OUT}' -> '${IN}'"
|
||||
fi
|
||||
|
||||
rm ${log_file}
|
||||
NOW=$(date +%s)
|
||||
echo -e "\n${current}/${total}: Completed in $(mstodate $(( NOW - STARTTIME ))000)"
|
||||
}
|
||||
|
||||
function check_and_convert {
|
||||
current="$2"
|
||||
total="$3"
|
||||
video_detect "$1" | while read entry; do
|
||||
# # file:codec:format
|
||||
file="${entry%%|*}" # file
|
||||
entry="${entry#*|}" # codec:format
|
||||
codec="${entry%%|*}" # codec
|
||||
format="${entry##*|}" # format
|
||||
codec="${codec,,}"
|
||||
if [[ "${codec}" == "none" ]]; then
|
||||
continue
|
||||
fi
|
||||
if (( force == 0 )) && [[ "${codec}" == "h264" ]] && [[ "${format}" =~ mkv|matroska ]]; then
|
||||
# If container is not mkv, convert to mkv container
|
||||
echo "${current}/${total}: Skipping ${file} as it is already mkv/h264."
|
||||
else
|
||||
convert "${file}" "${codec}" "${format}" "$current" "$total"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
if [ -z "$1" ]; then
|
||||
find . -name '* *' -type d | while read file; do mv "${file}" "${file// /_}" || fail "Unable to rename dir ${file}"; done
|
||||
find . -name '* *' -type f | while read file; do mv "${file}" "${file// /_}" || fail "Unable to rename file ${file}"; done
|
||||
total=$(find . -type f \
|
||||
-and -not -path "./backup/*" | wc -l)
|
||||
current=0
|
||||
find . -type f \
|
||||
-and -not -path "./backup/*" | sort | while read file; do
|
||||
check_and_convert "${file}" ${current} ${total}
|
||||
current=$((current+1))
|
||||
done
|
||||
else
|
||||
for file in "$*"; do
|
||||
check_and_convert "${file}" 1 1
|
||||
done
|
||||
fi && {
|
||||
cat << EOF
|
||||
To transfer the updated files:
|
||||
|
||||
rsync -avprlP --remove-source-files /multimedia/Downloads/ azurite:/multimedia/
|
||||
find /multimedia/Downloads/ -type d -empty -delete
|
||||
|
||||
EOF
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user