web-dev-qa-db-ja.com

FFmpegを使用した二重ファイル拡張子

FFmpegにコマンドを実行するパスの下にあるすべてのファイルとサブフォルダーを通過させて、代わりにMKVファイルをMP4コンテナーに変換しようとしています。

以下のコマンドは動作していますが、作成された新しいMP4ファイルには、新しいMP4拡張に加えてMKV拡張が残っています。

find ./ -iname '*.avi' -o -iname '*.mkv' -exec bash -c 'ffmpeg -i "{}" -vcodec copy -acodec copy "{}".mp4' \;

例えば ​​:

abcd.mkv (original file)  
abcd.mkv.mp4 (new file)

コマンドを調整して元のファイル拡張子を削除するにはどうすればよいですか?

3
Andy Pittas

ffmpegコマンドをbashスクリプトに入れて、bashツールを使用することにより、これを行う簡単な方法があります。の代わりに:

find ./ -iname '*.avi' -o -iname '*.mkv' -exec \
    bash -c 'ffmpeg -i "{}" -vcodec copy -acodec copy "{}".mp4' \;

findおよびxargsを使用して、ファイル名(スペースを含むファイル名を含む)のリストを、たとえば$HOME/bin/fixthem(read man find;man xargs)に渡します。

find . -type f -iname '*.avi' -o -iname '*.mkv' -print0  |\
    xargs -0 -r $HOME/bin/fixthem

$HOME/bin/fixthemは次のようなものです(およびchmod +x 'd):

注:未テストですが、/usr/bin/shellcheckを実行します。

#!/bin/bash
# convert the *.mkv and *.avi files to .mp4

# determine my name
me=$0
me=${me##*/}

# -h or --help 
help () {
    cat >&2 <<EOF
${me} [-h|--help] [-d|--debug] [-v|--verbose] [-n|--noaction] file file ...
${me}: -h or --help      This message
${me}: -d or --debug     List the commands we execute, as we process
${me}:                   the files.
${me}: -v or --verbose   List the filenames we process, as we process
${me}:                   the files.
${me}: -n or --noaction  Don't actually execute the commands. Used in
${me}:                   connection with --debug for testing.
${me}: -r or --remove    Remove the input file unless --debug is set.
EOF
    exit 2
}

declare -i debug=0 verbose=0 noaction=0 remove=0

# from /usr/share/doc/util-linux/examples/getopt-parse.bash 2015-Sep-06

TEMP=$(getopt -o dhvnr --long debug,help,verbose,noaction,remove \
     -n 'fixthem.bash' -- "$@")

if [[ $? != 0 ]] ; then echo "${me} --help for help." >&2 ; exit 1 ; fi

# Note the quotes around `$TEMP': they are essential!
eval set -- "$TEMP"

while true ; do
    case "$1" in
        -d|--debug) debug=1; shift;;
        -h|--help) help; shift;;
        -v|--verbose) verbose=1; shift;;
        -n|--noaction) noaction=1; shift;;
        -r|--remove) remove=1; shift;;
        --) shift; break;;
        *) echo "Internal error! ${me} --help for help";exit 1;;
    esac
done

# actual processing begins here
while [[ $# -gt 0 ]] ; do
      infile="$1"
      shift
      nameonly="${infile%.*}"
      outfile="${nameonly}.mp4"
      [[ "$verbose" -ne 0 ]] && echo "$infile -> $outfile" >&2
      command="ffmpeg -i \"$infile\" -vcodec copy -acodec copy \"$outfile\""
      [[ "$debug" -ne 0 ]] && echo "command" >&2
      [[ "$noaction" -ne 0 ]] || eval "$command"
      if [[ "$remove" -ne 0 ]] ; then
      v=""
      [[ "$verbose " -ne 0 ]] && v="-v"
      if [[ "$debug" -ne 0 ]] ; then
          echo "rm \"$infile\"" >&2
      else
          rm $v "$infile"
      fi
      fi
done

exit 0
0
waltinator

existing構文(おそらくそのままの意味)を維持したい場合は、次のわずかな変更でこの意味を維持する必要があります()必要なファイル名の変更:

find -iname '*.avi' -o -iname '*.mkv' -exec \
    bash -c 'ffmpeg -i "{}" -codec copy \
    $(echo "{}" | sed -r 's/.{3}$/mp4/')' \;

FFmpegを使用したsimplified your copy構文もあることに注意してください...

2
andrew.46