Skip to content

Instantly share code, notes, and snippets.

@aaronbrooks-gh
Created October 31, 2021 02:20
Show Gist options
  • Save aaronbrooks-gh/20e181f2c7d391c3662907fd4b48a468 to your computer and use it in GitHub Desktop.
Save aaronbrooks-gh/20e181f2c7d391c3662907fd4b48a468 to your computer and use it in GitHub Desktop.
Movie Checker - bash scripts to validate and find errors in a video file collection
#!/bin/bash
DIRLIST="/mnt/media"
REPORT_FILE="/home/aaron/moviereport.xml"
avg_read_speed() {
START_SEC=${1}
END_SEC=${2}
SIZE_BYTES=${3}
DURATION=$(expr ${END_SEC} - ${START_SEC})
BYTES_PER_SEC=$(expr ${SIZE_BYTES} / ${DURATION})
if [ -z "${START_SEC}" -o -z "${END_SEC}" -o -z "${SIZE_BYTES}" ]; then
# no op
echo
elif [ "${BYTES_PER_SEC}" -ge 1000000000 ]; then
echo "$(expr ${BYTES_PER_SEC} / 1000000000) GiB/s"
elif [ "${BYTES_PER_SEC}" -ge 1000000 ]; then
echo "$(expr ${BYTES_PER_SEC} / 1000000) MiB/s"
elif [ "${BYTES_PER_SEC}" -ge 1000 ]; then
echo "$(expr ${BYTES_PER_SEC} / 1000) KiB/s"
else
echo "${BYTES_PER_SEC} B/s"
fi
}
FILE_LIST=$(find "${DIRLIST}" -type f)
# echo -e "${FILE_LIST}"
echo "<movieChecker>" > ${REPORT_FILE}
echo "<filelist>" >> ${REPORT_FILE}
while IFS= read -r line; do
echo "<file>$line</file>" >> ${REPORT_FILE}
done < <(echo -e "${FILE_LIST}")
echo "</filelist>" >> ${REPORT_FILE}
echo "<fileReports>" >> ${REPORT_FILE}
set -x
while IFS= read -r line; do
echo "Working on ${line}"
echo "<fileReport>" >> ${REPORT_FILE}
echo "<fileName>$line</fileName>" >> ${REPORT_FILE}
rm /tmp/movieChecker.log
FILE_SIZE_BYTES=$(stat --printf="%s" "${line}")
READ_START_SEC=$(date +"%s")
ffmpeg -nostdin -v error -i "${line}" -f null -max_muxing_queue_size 4096 - 2>/tmp/movieChecker.log
READ_END_SEC=$(date +"%s")
AVG_READ_SPEED=$(avg_read_speed ${READ_START_SEC} ${READ_END_SEC} ${FILE_SIZE_BYTES})
ERROR_COUNT=$(cat /tmp/movieChecker.log | cut -d ' ' -f 1-3 | uniq | wc -l)
echo "<readSpeed>${AVG_READ_SPEED}</readSpeed>" >> ${REPORT_FILE}
echo "<badBlockCount>${ERROR_COUNT}</badBlockCount>" >> ${REPORT_FILE}
echo "<ffmpegLog><![CDATA[$(cat /tmp/movieChecker.log)]]></ffmpegLog>" >> ${REPORT_FILE}
echo "</fileReport>" >> ${REPORT_FILE}
# read -p "Press enter to continue" </dev/tty
done < <(echo -e "${FILE_LIST}")
echo "<fileReports>" >> ${REPORT_FILE}
echo "</movieChecker>" >> ${REPORT_FILE}
#!/bin/bash
cp moviereport.xml moviereport.tmp.xml
sed -i "s/\&/\&amp;/g" moviereport.tmp.xml
echo "</fileReport>" >> moviereport.tmp.xml
echo "</fileReports>" >> moviereport.tmp.xml
echo "</movieChecker>" >> moviereport.tmp.xml
MATCHES=$(xmllint --xpath "//fileReport[badBlockCount/text() != "0"]/fileName" moviereport.tmp.xml | sed "s/<\/fileName>/<\/fileName>\n/g")
echo -e "${MATCHES}"
echo -n "Total bad files: "
echo -e "${MATCHES}" | wc -l
echo -n "Total files scanned: "
xmllint --xpath "count(//fileReport)" moviereport.tmp.xml
echo
echo -n "Total file count: "
xmllint --xpath "count(//file)" moviereport.tmp.xml
echo
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment