動画を変換する必要がありますが、どこにあるかわからないので、find
する必要があります。 xargs
で FFmpeg に結果と出力ファイル名を与えるにはどうすればよいですか?
このコマンドで2つのパラメーターを作成できることはすでにわかりました。
find . -iname "*.mov" -printf "%p %f\n"
xargs
マニュアルに関連するものは見つかりません。私はこのようなものが欲しい:
find . -iname "*.mov" -printf "%p %f\n" | xargs ffmpeg -i {param1} -f flv {param2}
これどうやってするの?
このようなものはトリックを行い、フルパスを保持し、スペースを処理し、名前を変更しますfolder/movie.mov
からfolder/movie.flv
など.
find . -name "*.mov" | while read movie;do
ffmpeg -i "$movie" -f flv "${movie%.mov}.flv"
done
そして、私があなたを誤解していて、現在のディレクトリにあるすべての.flvムービーが必要な場合は、代わりにこれを使用してください。
find . -name "*.mov" | while read movie;do
ffmpeg -i "$movie" -f flv "$(basename "${movie%.mov}.flv")"
done
xargs
をfindと組み合わせて使用する理由は、xargs
が起動するすべてのプログラムの同じプログラム呼び出しに複数のファイル名が渡されるためです。たとえば、find
がファイルfoo、bar、およびbazを返す場合、以下はmv
を1回だけ実行します。
find sourceDir [...] -print0 | xargs -0 mv -t destDir
効果的には、次のようにmv
を呼び出します。
mv -t destDir foo bar baz
この動作が必要ない、または必要ない場合は(ここではそうだと思います)、find
の-exec
を使用できます。
この場合、簡単な解決策は、次のような短いシェルスクリプトを記述することです。
#!/usr/bin/env bash
[[ -f "$1" ]] || { echo "$1 not found" ; exit 1 ; }
P="$1"
F="$( basename $P )"
ffmpeg -i "$P" -f flv "$F"
myffmpeg.sh
として保存し、chmod +x myffmpeg.sh
を実行します。次に、以下を実行します。
find . -iname "*.mov" -exec /path/to/myffmpeg.sh {} \;
これにより、ファイルが見つかるたびにシェルスクリプトが呼び出されます。次に、シェルスクリプトはフルパスからファイル名を抽出し、適切な引数を指定してffmpeg
を呼び出します。
期待した解決策が得られなかったので、自分の解決策を見つけました。 @Danielの答えは良いですが、シェルスクリプトが必要です。ワンライナーは速く、私はそれが好きです:)また、スクリプトを書くよりもシンプルなソリューションです。
1つの引数を使用して、basename
で処理し、sh -c
を使用することができます
find . -iname "*.mov" -print0 | xargs -0 -i sh -c 'ffmpeg -i {} -f flv `basename {}`'
-iは、xargsに{}
を現在の引数で置き換えるように指示します。
内のコマンド出力は、標準出力(bash機能)に出力されるため、basename {}
は、ベアファイル名として評価され、出力されます。
-0は、特殊ファイル名を適切に処理するためのものですが、-print0オプションを使用してパラメーターを渡す必要があります。
これまでのすべての回答と同じように行う必要がありますが、xargsの正確な使用法は次のようになります。
echo argument1 argument2 argument3 | xargs -l bash -c 'echo this is first:$0 second:$1 third:$2' | xargs
したがって、あなたの場合は次のようになります:
find . -iname "*.mov" -printf "%p %f\n" | xargs -l bash -c 'echo ffmpeg -i $0 -f flv $1' | xargs
PS:これは、1つのxargs
コマンドで複数のxargs
パラメーターに対する回答を正確に探している人のためのxargsに関する質問に答えます。
名前バインディングを使用して(およびファイル名にスペースが含まれる問題を回避するために別のセパレーターを使用して)Zoredacheの回答の代替案:
IFS="\t" find -iname "*.mov" -printf "%p\t%f\n" | while read path file; do
ffmpeg -i $path -f flv $file
done
もちろん、他の回答が使用したfind -a array
引数でセパレータを使用することもできますが、名前付き引数の方がわかりやすい場合があります。
Xargsを使用してできるかどうか、またその方法はわかりません。
しかし、このようなものがあなたのために働くはずです:
find . -iname "*.mov" -printf "%p %f\n" | while read -a HR ; do echo ffmpeg -i ${HR[0]} -f flv ${HR[1]} ;done
ffmpegのオプションを単純に移動して、findコマンドからの結果のフォーマットに合わせてみませんか?
find . -iname "*.mov" -printf "%p %f\n" | xargs -r -n2 ffmpeg -f flv -i
-rオプションがxargsに追加され、実行されないようにするffmpeg。movファイルがない場合見つかりました。
-n2オプションをxargsに追加して、アイテムの数を制限しましたxargs 一度に2つまで処理します。この場合の項目は、ファイルパスとファイル名です。 -nオプションが設定されていない場合、xargsは1回の実行でできるだけ多くの入力項目を処理します。
次のように、findコマンドから直接ffmpegを実行できます。
find . -iname "*.mov" -exec ffmpeg -i "%p" -f flv "%f" \;
ファイル名にスペースがあり、エスケープされたセミコロンが実行されたコマンドの終わりを示している場合は、ffmpegのパラメーターを囲む引用符に注意してください。