Erkennen Sie abgeschnittene MP3- oder OGG-Dateien

4

Ich hatte kürzlich einen Festplattenfehler und konnte meine Musikdateien nicht retten. Da mir nicht genügend Speicherplatz zur Verfügung stand, um eine vollständige Sicherung der Festplatte zu erstellen, habe ich es versucht cp so viele Titel wie möglich, aber jetzt stehen mir einige Dateien zur Verfügung, die vorzeitig enden.

Habe ich schon gefunden diese Antwort um herauszufinden, "die Liedlänge" und dieses Werkzeug das tut das gleiche. Für eine defekte Datei bekomme ich folgende Ausgabe:

ffmpeg -i broken.mp3 2>&1 | grep Duration
  Duration: 00:04:18.14, start: 0.025057, bitrate: 92 kb/s

mp3_check -a broken.mp3 2>&1| grep SONG
SONG_LENGTH         01:43.05

So ffmpeg scheint auf einige Metadaten angewiesen zu sein (04:18 ist die Dauer, die auch in meinem Media Player angezeigt wird), während mp3_check scheint tatsächlich die ganze Datei zu lesen. Ich könnte damit ein Skript schreiben, das mp3 abdeckt, aber:

Gibt es eine einfachere Lösung als einen Vergleich? ffmpeg und mp3_check Ausgabe, um defekte Dateien zu finden?

Wie würde ich das mit Ogg-Dateien machen, wo nein mp3_check ist verfügbar?

Jasper
quelle
Ich habe bereits ein bash-Skript für die erste Frage geschrieben. Oder passt dieses Thema besser zu Stackoverflow oder Unix + Linux?
Jasper
Ich würde Sie dazu ermutigen, das Skript trotzdem als Antwort zu posten, und wenn jemand eine Lösung hat, dann sei es so. Aber vielleicht findet es auch jemand anderes hilfreich - eine Win-Win-Situation. Die Frage ist hier vollkommen in Ordnung. Wir lehnen Skriptfragen nicht ab, solange sie sich in einem Kontext befinden, der von einem Power-Benutzer ausgeführt wird, jedoch nicht ausschließlich für die Programmierung. Und auch Unix / Linux-Fragen sind hier zum Thema.
slhck
mp3diags scannt und erkennt abgeschnittene Dateien. Wenn Sie sich dafür entscheiden, repariert es sie sogar. Es ist für verfügbar Linux und Windows
nixda

Antworten:

1

Dies ist das Skript, das ich jetzt verwende:

#!/bin/bash

echo "checking $1"

find "$1" -name "*.mp3" | while read filename; do
  echo "checking $(basename "$filename")"
  ffmpeg_dur=$(ffmpeg -i "$filename" 2>&1 | awk -F: '($1 ~ /Duration/) {printf "60*%d+%d\n", $3, $4}' | bc)
  # mp3_check_dur=$(mp3_check -a "$filename" 2>&1 | awk -F'[ :.]+' '($1 ~ /SONG_LENGTH/) {printf "60*%d+%d\n", $2, $3}' | bc )
  mp3info_dur=$(mp3info -x "$filename" 2>&1 | awk -F'[ :.]+' '($1 ~ /Length/) {printf "60*%d+%d\n", $2, $3}' | bc )

  if [[ -z $ffmpeg_dur ]] ; then  # some files are so broken that ffmpeg doesn't print a length
    echo "ERROR (ffmpeg): $filename"
  else
    len_diff=$(( $ffmpeg_dur - $mp3_check_dur ))
    if [[ $len_diff -gt 0 ]] ; then
      echo -e "ERROR (length): $filename\t${len_diff}"
    fi
  fi

done

Die Dauer wird von gemeldet ffmpeg ist immer länger als der von mp3_check und mp3info. Manchmal gibt es auch einen Unterschied von 1 Sekunde. mp3info ist als Paket für einige Linux-Distributionen verfügbar (Ubuntu, Arch, ...?), mp3_check muss aus Quelle erstellt werden.

Jasper
quelle
Funktioniert nicht wie es ist. mp3_check_dur sollte durch ersetzt werden mp3info_dur im $((ffmpeg_dur - mp3_check_dur))
Andrey Regentov