it-swarm.com.de

So erhalten Sie die tatsächliche tatsächliche Dauer einer MP3-Datei (VBR oder CBR) serverseitig

Ich habe die Dauer von MP3-Dateien auf der Serverseite mit ffmpeg berechnet - das schien gut zu funktionieren. Heute entdeckte ich, dass einige der Berechnungen falsch waren. Aus irgendeinem Grund wird die Dauer von ffmpeg falsch berechnet, und dies scheint nur bei MP3-Dateien mit variabler Bitrate der Fall zu sein.

Beim lokalen Testen habe ich festgestellt, dass ffmpeg zwei zusätzliche Zeilen in grün gedruckt hat.

Befehl verwendet:

ffmpeg -i song_9747c077aef8.mp3

ffmpeg sagt:

[mp3 @ 0x102052600] max_analyze_duration 5000000 reached at 5015510
[mp3 @ 0x102052600] Estimating duration from bitrate, this may be inaccurate

Nach einer netten, warmen Google-Sitzung entdeckte ich einige Beiträge dazu, aber es wurde keine Lösung gefunden.

Ich habe dann versucht, die maximale Dauer zu erhöhen:

ffmpeg -analyzeduration 999999999 -i song_9747c077aef8.mp3

Danach gab ffmpeg nur die zweite Zeile zurück:

[mp3 @ 0x102052600] Estimating duration from bitrate, this may be inaccurate

In jedem Fall war die berechnete Dauer jedoch einfach falsch. Beim Vergleich mit VLC habe ich festgestellt, dass die Dauer korrekt ist.

Nach mehr Recherche stolperte ich über mp3info - das ich installiert und benutzt habe.

mp3info -p "%S" song_9747c077aef8.mp3

mp3info lieferte dann dieRICHTIGE- Dauer, aber nur als ganze Zahl, die ich nicht verwenden kann, da ich hier eine genauere Zahl brauche. Der Grund dafür wurde in einem Kommentar erklärt, der von Benutzer blahdiblah - mp3info einfach ID3-Informationen aus der Datei zieht und keine Berechnungen durchführt.

Ich habe auch versucht, mit mplayer die Dauer abzurufen, aber genau wie ffmpeg gibt mplayer den falschen Wert zurück.

21
SquareCat

Ich fand endlich eine richtige Lösung für dieses Problem mit Sox - das gibt die richtigen Informationen zurück.

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

Länge (Sekunden): 219.062857

20
SquareCat

Sie können die Datei vollständig entschlüsseln, um die tatsächliche Dauer zu erhalten:

ffmpeg -i input.mp3 -f null -

Die zweite bis letzte Zeile der Konsolenausgabe zeigt etwa Folgendes:

size=N/A time=00:03:49.12 bitrate=N/A

Wobei time die tatsächliche Dauer ist. In diesem Beispiel dauerte der gesamte Vorgang etwa 0,5 Sekunden.

10
llogan

Einfacher ist es, ffmpeg zu verwenden, um die Datei von der mit der fehlerhaften Dauer in ihrem ID3-Tag zu kopieren. Dies führt dazu, dass die richtigen Informationen geschrieben werden.

ffmpeg -i "audio.mp3" -acodec copy "audio_fixed.mp3"

Da für das Kopieren nur ein Bruchteil der Zeit benötigt wird, die für die ursprüngliche Codierung erforderlich ist. Bei einem Lied ist das kaum zu bemerken, aber bei einem 7-Stunden-Hörbuch weiß man es wirklich zu schätzen. Nach der Neucodierung verfügt das ID3-Tag "Duration" nun über die richtigen Informationen.

1
Miriam English

Erweiterungslösung von LordNeckbeard. Um nur Statistiken zu erhalten, können Sie Flag -v quiet -Stats hinzufügen

ffmpeg -v quiet -stats -i input.mp3 -f null - 
1
Mitja Gomboc
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"
0
Luchostein