web-dev-qa-db-ja.com

ffmpegを使用してm4a(alac)をflacに変換すると、出力の品質が低下しますか?

互換性の理由から、インポートした音楽コレクションをflacに変換しようとしています。とにかく、私はこのコマンドを使用して変換しています:
_ffmpeg -i file.m4a file.flac_
技術的には、これは正常に機能し、ファイルをflacに変換しますが、出力を調べると、元のファイル(この1つの例では、実際の数はトラック間で異なります)がオーディオストリームでこれを示していることがわかります。
Audio: alac (alac / 0x63616C61), 44100 Hz, stereo, s16p, 968 kb/s (default)
そして新しいflacバージョンはオーディオストリームについてこれを示しています:
Audio: flac, 44100 Hz, stereo, s16, 128 kb/s (default)
2つのことに気づきました。1つ目は、「s16p」が「s16」に変更されたことです。それが何を意味するのかはわかりませんが、あまり気にしませんが、気になるのは大幅な低下です。ビットレートの! 968から128まで。現在、各トラックのビットレートはわずかに異なりますが、最終的にはすべて128に出力されます。これはflacの制限ですか?そうでない場合は、元のビットレートで出力するようにffmpegに指示するにはどうすればよいですか?

また、それが品質に影響を与える場合、s16とs16pは何を指しているのでしょうか?

編集:私は技術的に私が探していたものを手に入れましたが、s16が何を意味するのかまだわかりません、そして私がしたことが正しく機能したかどうか100%確信がありません、説明のために私の答えをチェックしてください。

1
Matthew

変換中の出力に表示されるビットレートに注意を払わないでください。これは、エンコーダのレート制御方法がビットレートを対象としている場合にのみ密接に関係します。 FLACエンコーダーはそうではありません。生成された後、出力ファイルに対してffprobeを実行します。実際にエンコードされたビットレートが表示されます。

FLACはロスレスコーデックであるため、取得したビットレートに関係なく、ソースと比較してロスレス、つまり同じ品質になります。

_s16_および_s16p_は、これらのフォーマット用にffmpegのデコーダーによって生成されたサンプルフォーマットを参照します。 _s16p_は、デコードされたサンプルが符号付き16ビット整数であり、各チャネルが別々の平面にあることを意味します。つまり、_C1 C1 C1 C1_と_C2 C2 C2 C2_ですが、_s16_では、それらは_C1 C2 C1 C2 C1 C2 C1 C2_。明確にするために、これはデコーダーによって生成された非圧縮出力のレイアウトとフォーマットです。ファイル内の実際のデータはコード化されています(したがって、用語エンコードされた)。

1
Gyan

私は数時間掘り下げてffprobeについて知り、最初はそれを無視しました。私が書いたコマンドが長くなることを知っていたからですが、他に選択肢がないので、最後の、機能するPowerShellを紹介します。コマンド。誰かがこれが問題になる可能性がある方法を見つけたら、教えてください、そして私は保証しませんが、これが私が思いついたものです(これは現在のディレクトリ内のすべてのm4a alacファイルを再帰的に変換します):
Get-ChildItem -Path . -filter *.m4a | ForEach-Object -Process {[System.IO.Path]::GetFileNameWithoutExtension($_)} | ForEach-Object -Process {ffmpeg.exe -i "$($_).m4a" -ab $(ffprobe -v error -i "$($_).m4a" -select_streams a:0 -show_entries stream=bit_rate -of default=noprint_wrappers=1).replace("bit_rate=","") "$($_).flac"}
この文字化けがそれを台無しにするものの説明、それを読む人を助けるために:

  • _Get-ChildItem -Path . -filter *.m4a_これは基本的にdirコマンドに似ていますが、.m4aで終わるファイルのみが表示されます。これはパイプで接続されます:
  • ForEach-Object -Process {[System.IO.Path]::GetFileNameWithoutExtensions($_)}これにより、これらすべてのファイル名が取得され、.m4aが削除されます。次に、パイプで接続されます。
  • ForEach-Object -Process {ffmpeg -i "$($_).m4a"これはffmpegコマンドの開始点であり、ファイル名が渡され、.m4a拡張子が追加されます
  • -ab $(ffprobe -v error -i "$($_).m4a" -select_streams a:0 -show_entries stream=bit_rate -of default=noprint_wrappers=1).replace("bit_rate=","")これはm4aファイルをffprobeに送信し、ffprobeは_bit_rate=aNumber_を出力し、その後 "bit_rate ="が文字列から削除されます
  • "$($_).flac"}そして最後に、ファイル名は再びffmpegに与えられますが、今回は出力ファイルとしてflac拡張子を使用します。
    [。他の可能性の中でも、失われる可能性があります。
0
Matthew