I'm fairly new to writing bash scripts. I wrote a script with the goal of fixing HEVC encoded MP4 files that are missing the ctts atom. It is based on this script from a Plex forum user. The script accomplishes what I am trying to do, but requires manually checking every file and running it against the script. I have over 450 movies in my library and I want to be able to run the script once and not have to worry about it.
The requirements for my script are as follows:
- Identify ALL HEVC-encoded MP4 files missing the ctts atom
- For each file:
- Mux from MP4 to MKV
- Mux the video stream from the MKV file and the audio stream from the MP4 file into a new file with a .fixed.mp4 extension
- Move the original file into a backup folder in case any of the files get broken
Here is the script that I wrote:
#! /bin/bash
# Variables
MEDIA_DIR="/mnt/driveA/Media/"
TMP_DIR="/mnt/driveA/tmp/"
BACKUP_DIR="/mnt/driveA/backups/"
MKVMERGE_OPTS="-d 0 -A -S"
FFMPEG_OPTS="-map 1 -map 0 -map -0:v:0 -map -1:v:1 -map_metadata 0 -c copy -tag:v:0 hvc1 -movflags +faststart -f mp4"
find $MEDIA_DIR -name "*.mp4" | while read FILE;
do
if AtomicParsley "$FILE" -T 1 | grep -q ctts
then
true
else
BASE_FILE="$(basename "${FILE}" .mp4)"
WORKING_DIR="$(dirname "${FILE}")/"
echo "Missing ctts: ${BASE_FILE}"
echo "Remuxing ${FILE} to ${TMP_DIR}${BASE_FILE}.mkv"
mkvmerge ${MKVMERGE_OPTS} -o "${TMP_DIR}${BASE_FILE}.mkv" "${FILE}"
echo "Combining video stream from ${TMP_DIR}${BASE_FILE}.mkv with audio from ${FILE}"
ffmpeg -i "${FILE}" -i "${TMP_DIR}${BASE_FILE}.mkv" ${FFMPEG_OPTS} "${WORKING_DIR}${BASE_FILE}.fixed.mp4"
echo "Moving ${FILE} to backup folder"
mv -v "${FILE}" "${BACKUP_DIR}"
fi
done
Identifying the files and mux-ing them from MP4 to MKV was simple enough, but I'm running into some strange behavior in step 1.2. The only way I can describe it is that the script tries to keep going while ffmpeg is doing it's thing.
The script does do what it's supposed to do, kind of. It will process some files (which I confirmed have been fixed), then it will keep choking on itself until it stops. In order to continue processing files, I have to keep running it - which defeats the whole purpose of modifying the script from the plex forums to scan my entire media library.
Here is a sample of the output: https://pastebin.com/6btkzAj4
What is also strange is the last movie that it tried to process, Teaching Mrs. Tingle, is NOT one of the affected files and should have been skipped. When I run this script it is not included in the results:
#! /bin/bash
# Variables
MEDIA_DIR="/mnt/driveA/Media/"
find $MEDIA_DIR -name "*.mp4" | while read FILE;
do
if AtomicParsley "$FILE" -T 1 | grep -q ctts
then
true
else
echo "Missing ctts: ${FILE}"
fi
done
How do I force the script to make sure ffmpeg has finished processing the fixed file before moving on?
Am I making any stupid mistakes that would be causing this?? (or are there any easier ways to accomplish what I am trying to do??)
Any help or feedback will be greatly appreciated.
(I am running this on Ubuntu 20.04.3)