私はffmpegを使用してサーバー側でMP3ファイルの継続時間を計算していました-これは正常に機能しているようです。今日、私はいくつかの計算が間違っていることを発見しました。どういうわけか、何らかの理由で、ffmpegは期間を誤って計算し、可変ビットレートのmp3ファイルでのみ発生するようです。
これをローカルでテストしたところ、ffmpegが余分な2行を緑色で印刷していることに気付きました。
使用するコマンド:
ffmpeg -i song_9747c077aef8.mp3
ffmpegさんのコメント:
[mp3 @ 0x102052600] max_analyze_duration 5000000 reached at 5015510
[mp3 @ 0x102052600] Estimating duration from bitrate, this may be inaccurate
素敵な温かいGoogleセッションの後で、これに関するいくつかの投稿を見つけましたが、解決策が見つかりませんでした。
次に、最大期間を増やしてみました。
ffmpeg -analyzeduration 999999999 -i song_9747c077aef8.mp3
この後、ffmpegは2行目のみを返しました。
[mp3 @ 0x102052600] Estimating duration from bitrate, this may be inaccurate
しかし、どちらの場合でも、計算された期間は明らかに間違っていました。それをVLCと比較すると、期間が正しいことがわかりました。
さらに調査した後、mp3infoを見つけました。これをインストールして使用しました。
mp3info -p "%S" song_9747c077aef8.mp3
次にmp3infoは[〜#〜] correct [〜#〜]期間を返しましたが、整数としてのみ使用できます。ここではより正確な数値が必要なため使用できません。この理由は、ユーザーblahdiblahによる以下のコメントで説明されています-mp3infoは、単にファイルからID3情報を取得しており、実際には計算を実行していません。
また、mplayerを使用して期間を取得しようとしましたが、ffmpegと同じように、mplayerが間違った値を返しています。
私は最終的に、正しい情報を返すsoxを使用してこの問題の適切な解決策を見つけました。
sox file.mp3 -n stat
Samples read: 19321344
Length (seconds): 219.062857
Scaled by: 2147483647.0
Maximum amplitude: 1.000000
Minimum amplitude: -1.000000
Midline amplitude: -0.000000
Mean norm: 0.141787
Mean amplitude: 0.000060
RMS amplitude: 0.191376
Maximum delta: 0.947598
Minimum delta: 0.000000
Mean delta: 0.086211
RMS delta: 0.115971
Rough frequency: 4253
Volume adjustment: 1.000
長さ(秒):219.062857
ファイルを完全にデコードして、実際の期間を取得できます。
ffmpeg -i input.mp3 -f null -
コンソール出力の2行目から最後の行は、次のように表示されます。
size=N/A time=00:03:49.12 bitrate=N/A
ここで、time
は実際の期間です。この例では、プロセス全体に約0.5秒かかりました。
より簡単な方法は、ffmpegを使用して、ID3タグに無効な期間があるファイルからファイルをコピーすることです。これにより、正しい情報が書き込まれます。
ffmpeg -i "audio.mp3" -acodec copy "audio_fixed.mp3"
コピーを使用するため、元のエンコーディングにかかる時間の数分の1です。これは曲ではほとんど目立ちませんが、7時間のオーディオブックでそれを本当に感謝します。再エンコード後、ID3の「Duration」タグに正しい情報が含まれるようになりました。
LordNeckbeardからの拡張ソリューション。統計のみを取得するには、フラグを追加できます-v quiet -stats
ffmpeg -v quiet -stats -i input.mp3 -f null -
AV_LOG_FORCE_NOCOLOR=y ffmpeg -nostdin -hide_banner -nostats -loglevel info -i audio.mp3 -f null -vn -c:a copy - 2>&1 | tail -n 2
if [[ "$(AV_LOG_FORCE_NOCOLOR=y ffmpeg -nostdin -hide_banner -nostats -loglevel info -i video.mp4 -f null -c copy - 2>&1 | tail -n 2 | head -n 1)" =~ \ time=([0-9]+):([0-9]{2}):([0-9]{2})\.([0-9]+) ]]; then
declare duration=0 us="${BASH_REMATCH[4]}" t
for t in "${BASH_REMATCH[@]:1:3}"; do
((duration *= 60))
((duration += ${t#0} ))
done
while [ ${#us} -lt 6 ]; do us+=0; done
((us >= 500000)) && ((duration++))
((duration)) || ((duration++))
fi
echo -E Duration: "$duration"
ffmpegは、他の引数が指定されていない場合にすべてのファイル情報を出力します。
grepまたはawkを使用して、「期間」のみを返します。
_ffmpeg -i file.mp3 2>&1 | grep Duration
_
ffmpeg -i file.mp3 2>&1 | awk '/Duration/ { print substr($2,0,length($2)-1) }'
Sudo apt install sox
Sudo apt-get install libsox-fmt-mp3
その後:
sox yourfile.mp3 -n stat