【问题标题】:I'm trying to batch convert different video files into mkv using arrays in a bash script using mkvmerge or ffmpeg我正在尝试使用 mkvmerge 或 ffmpeg 在 bash 脚本中使用数组将不同的视频文件批量转换为 mkv
【发布时间】:2021-12-30 05:23:41
【问题描述】:

我有一个脚本,我使用 ffmpeg 或 mkvmerge 将我的视频文件从多个视频格式扩展转换为 bash 脚本。通过使用read extension 输入扩展名,我可以毫无问题地对脚本中的单个扩展名进行批量转换,但我试图弄清楚如何使用一组视频扩展名来做到这一点,所以我不必须输入要转换的每个扩展名。我想我可以根据需要向数组添加更多扩展。

我对在 bash 文件中使用数组完全陌生,所以这对我来说是全新的领域。

我想要做的是制作它,以便我可以将脚本放入包含要转换的视频的目录中,运行脚本,它将从数组列表中找到的所有视频转换为 mkv .我正在尝试使用数组来做到这一点,但它并不完全正确。它适用于列表中的第一项,avi,但是当它到达第二个和数组中的其余扩展名时,它不会将通配符文件名放入脚本中,因此不处理文件名。这是我目前拥有的:

#!/bin/bash

auto_ext=(avi mp4 m4p m4v webm mpg mp2 mpeg mpe mpv ogg wmv mov qt)

menu_option_one() {
    echo ""
    echo ""
    echo -n "  Enter file extension of file to convert: "
    read extension
    for f in *.$extension; do mkvmerge -o "${f%}.mkv" "$f";done
}

menu_option_two() {
        for f in *.${auto_ext[*]}; do mkvmerge -o "${f%}.mkv" "$f";done 
}

menu_option_three() {
    echo ""
    echo ""
    echo -n "  Enter file extension of file to convert: "
    read extension
    for f in *.$extension; do ffmpeg -i "$f" "${f%}.mkv";done 
}

menu_option_four() {
    for f in *.${auto_ext[*]}; do ffmpeg -i "$f" "${f%}.mkv";done
}


press_enter() {
    unset auto_ext
    unset extension
    echo ""
    echo -n "   Press Enter to continue... "
    read
    clear
}

incorrect_selection() {
    echo "Incorrect selection! Try again."
}

until [ "$selection" = "0" ]; do
    clear
    echo ""
    echo "  This file converts video files to mkv in the current directory only... "
    echo ""
    echo "      1  -  Use mkvmerge (fastest, decent quality)"
    echo "      2  -  Autoconvert all files using mkvmerge"
    echo "      3  -  Use ffmpeg (slowest, best quality)"
    echo "      4  -  Autoconvert all files using ffmpeg"
    echo "      0  -  Exit"
    echo ""
    echo -n "  Enter selection: "
    read selection
    echo ""
    case $selection in
        1 ) clear ; menu_option_one ; press_enter ;;
        2 ) clear ; menu_option_two ; press_enter ;;
        3 ) clear ; menu_option_three ; press_enter ;;
        4 ) clear ; menu_option_four ; press_enter ;;
        0 ) clear ; exit ;;
        * ) clear ; incorrect_selection ; press_enter ;;
    esac
done
exit 0

当目录中有 .mp4、.webm 和 .m4p 时,我得到的 mkvmerge 输出是:

mkvmerge v45.0.0 ('Heaven in Pennies') 64-bit
Error: The file '*.avi' could not be opened for reading: open file error.
mkvmerge v45.0.0 ('Heaven in Pennies') 64-bit
Error: The file 'mp4' could not be opened for reading: open file error.
mkvmerge v45.0.0 ('Heaven in Pennies') 64-bit
Error: The file 'm4p' could not be opened for reading: open file error.
mkvmerge v45.0.0 ('Heaven in Pennies') 64-bit
Error: The file 'm4v' could not be opened for reading: open file error.
mkvmerge v45.0.0 ('Heaven in Pennies') 64-bit
Error: The file 'webm' could not be opened for reading: open file error.
mkvmerge v45.0.0 ('Heaven in Pennies') 64-bit
Error: The file 'mpg' could not be opened for reading: open file error.
mkvmerge v45.0.0 ('Heaven in Pennies') 64-bit
Error: The file 'mp2' could not be opened for reading: open file error.
mkvmerge v45.0.0 ('Heaven in Pennies') 64-bit
Error: The file 'mpeg' could not be opened for reading: open file error.
mkvmerge v45.0.0 ('Heaven in Pennies') 64-bit
Error: The file 'mpe' could not be opened for reading: open file error.
mkvmerge v45.0.0 ('Heaven in Pennies') 64-bit
Error: The file 'mpv' could not be opened for reading: open file error.
mkvmerge v45.0.0 ('Heaven in Pennies') 64-bit
Error: The file 'ogg' could not be opened for reading: open file error.
mkvmerge v45.0.0 ('Heaven in Pennies') 64-bit
Error: The file 'wmv' could not be opened for reading: open file error.
mkvmerge v45.0.0 ('Heaven in Pennies') 64-bit
Error: The file 'mov' could not be opened for reading: open file error.
mkvmerge v45.0.0 ('Heaven in Pennies') 64-bit
Error: The file 'qt' could not be opened for reading: open file error.

ffmpeg 只是说*.: No such file or directory

我尝试在 for 循环中同时使用通配符数组 [*] 和数组 [@],但我得到了相同的结果。老实说,我不确定两者之间有什么区别。我在这里和其他论坛上进行了搜索,问题都集中在仅将一种视频类型转换为另一种视频类型上,而不是同时查找和转换多种格式。我想我可能错过了处理数组的步骤,但这只是一个猜测。

由于输出为未找到的扩展添加了错误,我想我也会将错误指向脚本中某处的空值,但我不确定在哪里。

【问题讨论】:

    标签: arrays bash video type-conversion file-extension


    【解决方案1】:

    menu_option_two()函数中,声明

    for f in *.${auto_ext[*]}
    

    扩展为:

    for f in *.avi mp4 m4p m4v webm ...
    

    将 f 分配给 *.avi(如果存在)、mp4、m4p、...的每个全局文件

    您将需要创建双循环:

    for ext in "${auto_ext[@]}"; do
        for f in *."$ext"; do
            if [[ -f $f ]]; then
                mkvmerge -o "${f%$ext}mkv" "$f"
            fi
        done
    done
    

    需要if [[ -f $f ]] 条件来避免变量f 分配给文字 *.avi,例如,当类型 glob 失败时。 (或者您可以设置nullglob shopt 选项。)

    【讨论】:

      【解决方案2】:

      正如 Ishiano 建议的那样,我最终做的是一个双循环,但有一点不同。

      for ext in ${auto_ext_2[@]}; do
          count_file=`ls -1 *.${ext} 2>/dev/null | wc -l`
          if [ $count_file != 0 ]
              then 
                  for f in *.$ext; do
                      ffmpeg -i "$f" "${f%.$ext}.mkv";
                  done
          fi
      

      在运行双循环的第一部分以转换文件后,我想检查扩展名是否真的在目录中。线

      count_file=`ls -1 *.${ext} 2>/dev/null | wc -l
      

      检查目录中是否有任何扩展名大于零的文件,如果 count_file 数量大于零,它将运行双循环的第二部分,如果数量为零,它将跳过完全是第二部分。我的过程有点不同,但它奏效了,所以我很高兴。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-02-07
        • 2022-12-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-06-01
        • 2020-03-10
        相关资源
        最近更新 更多