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)
コマンドを調整して元のファイル拡張子を削除するにはどうすればよいですか?
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
existing構文(おそらくそのままの意味)を維持したい場合は、次のわずかな変更でこの意味を維持する必要があります()必要なファイル名の変更:
find -iname '*.avi' -o -iname '*.mkv' -exec \
bash -c 'ffmpeg -i "{}" -codec copy \
$(echo "{}" | sed -r 's/.{3}$/mp4/')' \;
FFmpegを使用したsimplified your copy
構文もあることに注意してください...