いろいろなシリーズの複数のラジオドラマがあります。一部はすでにシングルトラック、一部はマルチトラックです。私はすべてがシングルトラックであることを願っています。再エンコードするのは好きではありません。実際にモバイルデバイスにストリーミングし、opus出力を好みます。
これは、個々のオーディオブックフォルダからmp3をopusに変換するトリックを実行するようです。
ffmpeg -i "concat:$(ls *.mp3 | tr '\n' '|')" -acodec opus test.opus
今、変換したいマルチトラックラジオ番組がたくさんあります。使用find
したり結果をリンクしたりできる関数を定義したいと思いますls
。
私はこれのバリエーションを探して迷っています。
function audioconcat { folder=$1; iformat=$2; oformat=$3; echo $folder; echo $iformat; echo $oformat; ffmpeg -i \'concat:$(find "$folder" -name *.$iformat | tr '\n' '|' | tr ' ' '\ ' | head -c -1)\' -acodec $oformat \'$folder.$oformat\'; }
したがって、フォルダ内の特定の入力形式のファイルを見つけてffmpeg接続に入れ、ストリームを指定された出力形式にエンコードしてから、フォルダ名を使用して単一のファイルとして保存するのがアイデアです。
しかし、私は常に空白および/またはネストされた関数呼び出しに問題があるようです。
機能を変更するにはどうすればよいですか?それとも、上記の変換を実行するより良い方法はありますか?
ベストアンサー1
コードで改善できるいくつかのアンチパターンを実演しました。バラよりなぜあなたがしてはいけないls(1) の出力を解析します。。ls
コマンドの出力を解析する必要はなく、tr
コマンドとfind
。
デフォルトのシェルで提供されるglobオプションをよりよく使用することをお勧めします。あなたの場合はシェルでなければなりませんbash
。
$(ls *.mp3 | tr '\n' '|')
このコードは、以下のようにファイルグロービングに提供されているオプションを使用して素敵に書くことができます。bash
shopt -s nullglob
mp3FileList=(*.mp3)
この拡張シェルオプションは、配列を埋めるときに空のglob結果を処理するのではなくスキップするために有効になります。cd
そのフォルダに行き、次のことを行う必要があります。|
配列の後の最後の項目も元のリストに含めたので記録してください。必要ない場合は削除してください。
fileString=$( IFS='|'; echo "${mp3FileList[*]}|" )
|
上記の変数には、個別にフォーマットされたファイルのリストが含まれ、|
最終的にコマンドに渡すことができますffmpeg
。
ffmpeg -i "concat:${fileString}" -acodec opus test.opus
複数のオプションをスクリプトに渡すことに関する 2 番目の要件です。このスクリプトを拡張して、次のことができます。
audioConcat() {
(( "$#" < 3 )) && { printf 'insufficient arguments supplied' >&2; exit 1 ; }
cd "$1" || { printf 'unable to navigate to target\n' >&2; exit 2 ; }
shopt -q nullglob; nullglob_set=$?
((nullglob_set)) && shopt -s nullglob
local fileList
local fileString
fileList=(*."${2}")
if (( ${#fileList[@]} )); then
fileString=$( IFS='|'; echo "${fileList[*]}" )
ffmpeg -i "concat:${fileString}" -acodec "$3" "$1.$3"
else
printf 'unable to find files of extension %s\n' "$2" >&2
exit 3
fi
((nullglob_set)) && shopt -u nullglob
}
関数を呼び出すときは、パラメーターを次のように渡します。
audioConcat '/path/to/mp3files/' 'mp3' 'opus'
ffmpeg
上記の関数の行をコメントアウトし、変数が作成されたことを確認することをお勧めします。〜のように実際のコマンドを呼び出す前に必要です。また、|
ファイルリストに末尾が必要であることを確認してください。
関数で使用される構造の簡単な要約
- パス名拡張中に設定されたオプションは、空の
nullglob
グローブ拡張を防止します。つまり、.mp3
ファイルが見つからない場合は、拡張されていないグローブの代わりに拡張時に配列が空になります。 $(IFS='|'; echo "${mp3FileList[*]})
別の形式で出力を印刷する素晴らしい方法です|
。サブシェル(入力フィールド区切り文字)を変更するため、IFS
グローバルに変更されません。配列拡張は[*]
文字列をIFS
設定された値に関連付けます。
いくつかのその他のアイテム。考慮すべき点: -exit
関数でfromを使用すると、実際には出口関数を実行している現在のシェルです。コマンドラインで使用することはお勧めできませんが、適切なインタプリタシェーバン設定を使用してスクリプトで実行する場合に適しています。この場合、スクリプトを実行するために開始されたサブシェルで終了します。コマンドラインでより頻繁に使用するには、exit
呼び出しをreturn
。