我对编写 bash 脚本还很陌生。我编写了一个脚本,目的是修复缺少 ctts 原子的 HEVC 编码 MP4 文件。它基于这个脚本来自 Plex 论坛用户。该脚本实现了我想要做的事情,但需要手动检查每个文件并根据脚本运行。我的库中有超过 450 部电影,我希望能够运行一次脚本而不必担心它。
我的脚本的要求如下:
- 识别所有缺少 ctts 原子的 HEVC 编码 MP4 文件
- 对于每个文件:
- 从 MP4 到 MKV 的 Mux
- 将 MKV 文件的视频流和 MP4 文件的音频流合并为一个扩展名为 .fixed.mp4 的新文件
- 将原始文件移至备份文件夹,以防任何文件损坏
以下是我编写的脚本:
#! /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
识别文件并将它们从 MP4 转换为 MKV 非常简单,但我在步骤 1.2 中遇到了一些奇怪的行为。我唯一能描述的方式是,当 ffmpeg 正在执行其任务时,脚本会尝试继续运行。
脚本确实做了它应该做的事情,有点。它会处理一些文件(我确认已经修复),然后它会一直阻塞直到停止。为了继续处理文件,我必须继续运行它 - 这违背了从 plex 论坛修改脚本以扫描我的整个媒体库的整个目的。
以下是输出示例:https://pastebin.com/6btkzAj4
同样奇怪的是,它尝试处理的最后一部电影《Teaching Mrs. Tingle》不是受影响的文件之一,应该被跳过。当我运行此脚本时,它不包含在结果中:
#! /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
我如何强制脚本确保 ffmpeg 在继续之前已完成对修复文件的处理?
我是不是犯了什么愚蠢的错误导致了这种情况?(或者有没有更简单的方法来完成我想做的事情?)
任何帮助或反馈都将不胜感激。
(我在 Ubuntu 20.04.3 上运行它)