FFMPEG 编码上的 Plex DVR 文件重命名

Plex DVR File Rename on FFMPEG Encoding

我目前正在使用 bash shell 脚本使用 FFMPEG 将我所有的 Plex DVR 记录编码为 H.264。我正在使用我在网上找到的这个小 for 循环来对单个目录中的所有文件进行编码:

for i in *.ts;
    do echo "$i" && ffmpeg -i "$i" -vf yadif -c:v libx264 -preset veryslow -crf 22 -y "/mnt/d/Video/DVR Stash/Seinfeld/${i%.*}.mp4";
done

这很好地达到了它的目的,但在此过程中我想将文件重命名为我喜欢的命名约定,以便原始文件名 Seinfeld (1989) - S01E01 - Pilot.ts 在编码文件中重命名为 Seinfeld S01 E01 Pilot.mp4。虽然我已经在使用正则表达式将 .ts 扩展名更改为 .mp4,但我不是正则表达式专家,尤其是 bash shell,所以任何帮助都会不胜感激。

对于任何对我的 Plex 设置感兴趣的人,我正在使用一台旧机器 运行ning Linux Mint 作为我的专用 DVR,并使用我的日常驱动程序实际通过网络访问它一台游戏机,所以视频编码的处理能力更强。虽然那台机器是 Windows 机器,但我在 WSL2 下使用 Ubuntu bash 来 运行 我的脚本,因为我更喜欢它而不是 Windows 命令prompt 或 Powershell(我的日常工作是在一家发行 Mac 的公司担任 Web 开发人员)。所以这是我的代码示例,供任何可能考虑做类似事情的人使用。

if [[ -d "/mnt/sambashare/Seinfeld (1989)" ]]
then
    cd "/mnt/sambashare/Seinfeld (1989)"
    echo "Seinfeld"
    for dir in */; do
        echo "$dir/"
        cd "$dir"
        for i in *.ts;
            do echo "$i" && ffmpeg -i "$i" -vf yadif -c:v libx264 -preset veryslow -crf 22 -y "/mnt/d/Video/DVR Stash/Seinfeld/${i%.*}.mp4";
        done
        cd ..
    done
fi

虽然我考虑过为所有节目做一个 for 循环,但现在我正在单独做每个节目,因为有一些节目我有自定义编码设置

对您的代码进行的小修改,类似这样,extglob

#!/usr/bin/env bash

if [[ -d "/mnt/sambashare/Seinfeld (1989)" ]]; then
  cd "/mnt/sambashare/Seinfeld (1989)" || exit
  echo "Seinfeld"
  for dir in */; do
    echo "$dir/"
    cd "$dir" || exit
    for i in *.ts; do
      shopt -s extglob
      new_file=${i//@( \(*\)|- )}
      new_file=${new_file/E/ E}
      new_file=${new_file%.*}
      echo "$i" &&
      ffmpeg -i "$i" -vf yadif -c:v libx264 -preset veryslow -crf 22 -y "/mnt/d/Video/DVR Stash/Seinfeld/${new_file}.mp4"
      shopt -u extglob
    done
    cd ..
  done
fi

如果文件名中除剧集之外的某处有 is/are E,string/glob/pattern 切片可能会失败。


With BASH_REMATCH 对扩展正则表达式使用 =~ 运算符。即使文件名中有更多 E,这也会起作用。

#!/usr/bin/env bash

if [[ -d "/mnt/sambashare/Seinfeld (1989)" ]]; then
  cd "/mnt/sambashare/Seinfeld (1989)" || exit
  echo "Seinfeld"
  for dir in */; do
    echo "$dir/"
    cd "$dir" || exit
    for i in *.ts; do
       regex='^(.+) (\(.+\)) - (S[[:digit:]]+)(E[[:digit:]]+) - (.+)([.].+)$'
       [[ $i =~ $regex ]] &&
       new_file="${BASH_REMATCH[1]} ${BASH_REMATCH[3]} ${BASH_REMATCH[4]} ${BASH_REMATCH[5]}"
      echo "$i" &&
      ffmpeg -i "$i" -vf yadif -c:v libx264 -preset veryslow -crf 22 -y "/mnt/d/Video/DVR Stash/Seinfeld/${new_file}.mp4"
    done
    cd ..
  done
fi
  • 添加 cd ... || exit 只是为了确保脚本 stops/exits 在尝试 cd 到某个地方时出现 is/are 错误而不是继续脚本。