Wie extrahiere ich einen Vorbis-Stream aus einer WAVE-Datei?

2086
H.B.

Ich möchte den Vorbis-Stream in einen ogg-Container verschieben, aber ffmpeg scheint den Stream nicht zu erkennen.

Obwohl MPlayerdiese Ausgabe bei der Wiedergabe ausgegeben wird:

Audio-Decoder öffnen: [acm] Win32 / ACM-Decoder
Laden der Codec-DLL: 'vorbis.acm'
Geladener DLL-Treiber vorbis.acm bei 10000000
Warnung! ACM-Codec-Berichte srcsize = 0
AUDIO: 44100 Hz, 2 Kanal, s16le, 128,0 kbit / 9,07% (Verhältnis: 16000 → 176400)
Ausgewählter Audio-Codec: [Vorbisacm] afm: acm (OggVorbis ACM)

ffmpeg:

ffmpeg -i Source.wav -acodec copy Target.ogg 
Input #0, wav, from 'Source.wav': Duration: 00:02:15.17, bitrate: 128 kb/s Stream #0.0: Audio: qg[0][0] / 0x6771, 44100 Hz, 2 channels, 128 kb/s [ogg @ 00000000003096C0] Unsupported codec id in stream 0 Output #0, ogg, to 'Target.ogg': Metadata: encoder : Lavf53.6.0 Stream #0.0: Audio: qg[0][0] / 0x6771, 44100 Hz, 2 channels, 128 kb/s Stream mapping: Stream #0.0 -> #0.0 Could not write header for output file #0 (incorrect codec parameters ?) 

Natürlich muss dies nicht unbedingt über ffmpeg erfolgen, jede funktionierende Methode wäre in Ordnung ...


Ich habe eine der Dateien auf 512KB reduziert: sample.wav
(Zwei Wellengrößenfelder im Wave-Header wurden geändert, um dies zu berücksichtigen, der eingebettete Stream wird "ohne Benachrichtigung" geschnitten).

3
Wird es in MPlayer tatsächlich korrekt wiedergegeben? Ich glaube nicht, dass * .wav-Dateien Vorbis-Streams unterstützen - sie sollten nur reine PCM-Daten sein. Darth Android vor 11 Jahren 0
@DarthAndroid: Sie unterstützen Rohdaten und Kodierung, siehe [Wikipedia] (http://en.wikipedia.org/wiki/Waveform_Audio_File_Format). H.B. vor 11 Jahren 0
@HB Können Sie eine Beispieldatei für die Eingabe angeben? LordNeckbeard vor 11 Jahren 0
@LordNeckbeard: Ich habe aus einer der Dateien ein kürzeres Beispiel gemacht, falls Sie noch interessiert sind ... H.B. vor 11 Jahren 0

2 Antworten auf die Frage

3
mark4o

Der WAV-Container ist im Grunde nur ein Dateiheader. Es unterstützt keine Frames mit variabler Länge, die von Vorbis benötigt werden. "OggVorbis ACM" ist eigentlich Vorbis innerhalb eines Ogg-Containers (zur Bereitstellung des Frames), so dass es in dem älteren Windows ACM-Audio-Framework verwendet werden kann, das das erforderliche Framing nicht unterstützt. Dies ermöglicht auch die Verwendung in WAV-Dateien. Dies ist jedoch weniger sinnvoll, da Sie stattdessen einfach eine .ogg-Datei speichern können.

ffmpeg implementiert oder erkennt diesen nicht standardmäßigen WAV-Codec "OggVorbis ACM" nicht. Sie können ein Programm verwenden, das dies erkennt, z. B. Audacity . Sie können auch einfach den WAV-Header entfernen, um den darin enthaltenen Ogg Vorbis zu extrahieren.

Gültige Ogg-Streams beginnen mit OggS, was den Anfang jeder Ogg-Seite in der Datei kennzeichnet. In der von Ihnen angegebenen Datei befinden sich 66 Byte vor der ersten OggS. Zumindest unter Mac / Linux / Unix können Sie die ersten 66 Bytes mit dem Befehl entfernen:

tail -c +67 sample.wav > sample.ogg 

In Ihrer Datei enthält der eingebettete Ogg tatsächlich zwei Streams. Dies scheint der Versuch zu sein, ihn mit einer festen Bitrate zu füllen. Der zweite Stream hat einen unbekannten Codec und scheint einige Spieler zu verwirren. Beispielsweise spielt Firefox den ersten Stream ab (den zweiten ignoriert), Chrome wird jedoch angehalten, wenn er auf den zweiten Stream trifft. Es hat auch andere Spezifikationsverletzungen, darunter kein EOS (Ende des Streams) (möglicherweise, weil Sie nicht die vollständige Datei gepostet haben).

Wenn Sie den ersten Bitstream (den vorbis-Bit) extrahieren, scheint er richtig zu spielen. Hier sind einige Tools, mit denen der erste Bitstream extrahiert werden kann:

  • oggsplit (arbeitet entweder mit den wav- oder ogg-Dateien)
  • oggSplit von Ogg Video Tools (arbeitet mit der ogg-Datei)
  • oggz-rip (jedoch mag dieses Programm Ihre Datei nicht, wahrscheinlich aufgrund der anderen Spezifikationsverletzungen)

Es ist möglicherweise besser, die WAV-Datei einfach mit einem Programm wie Audacity zu lesen und neu zu codieren, um sicherzustellen, dass sie keine anderen Verrückungen enthält.

Ich habe schon einmal versucht, den Wave-Header zu entfernen, aber "MPlayer" spielt ihn dann nicht mehr, und andere Spieler haben ebenfalls Probleme. Aus irgendeinem Grund kann der OggS auch an anderen Stellen im Stream gefunden werden, siehe zum Beispiel Offset 2f196 des Samples, obwohl ich nicht viel über die ogg vorbis-Spezifikation weiß ... H.B. vor 11 Jahren 0
"OggS" sollte am Anfang jeder Ogg-Seite stehen. Ich habe meine Antwort erweitert, um das Problem anzusprechen, das Sie sehen. mark4o vor 11 Jahren 0
Die Umcodierung ist genau das, was ich hier zu vermeiden versuche, um keine Qualität zu verlieren. Danke für Ihre Zeit, ich werde mir diesen Ansatz ansehen ... H.B. vor 11 Jahren 0
Die Lösung von @HB mark4o codiert IIRC nicht neu, und zumindest kann ffmpeg das Sample richtig decodieren. LordNeckbeard vor 11 Jahren 0
@LordNeckbeard: Ich weiß, ich habe mich nur auf den letzten Absatz bezogen: * "Vielleicht ist es besser, die WAV-Datei mit einem Programm wie Audacity zu lesen und neu zu codieren" * H.B. vor 11 Jahren 0
Leider gibt es noch einige Probleme, die vermutlich mit der Medienlänge zusammenhängen. Es ist so merkwürdig, wie die Originaldateien perfekt funktionieren. Wenn der Stream extrahiert wird, können meine Player nicht mehr erkennen, wie lange es noch dauert, oder sie werden am Ende der Datei fehlerhaft angezeigt. H.B. vor 11 Jahren 0
@HB Ich habe den hässlichen Perl-Hack in meiner Antwort durch einige Tools ersetzt, die in der Lage sein sollten, einen besseren Job zu machen. mark4o vor 11 Jahren 0
@ mark4o: Ich habe es wieder geschafft, um das nochmal zu probieren, endete mit `moggsplit`, was ziemlich gut funktioniert hat, danke nochmal. H.B. vor 11 Jahren 0
@ mark4o: Übrigens ist 'tail -c + 67' nicht unbedingt korrekt, da die Bytes in einem Wave-Chunk gerade sein müssen, daher könnte am Ende ein Null-Byte vorhanden sein, das berücksichtigt werden muss. H.B. vor 11 Jahren 0
0
Lissanro Rayen

Ich bin auf das gleiche Problem gestoßen, nur mit dem Unterschied, dass ich eine große Anzahl von Ogg Vorbis WAV-Dateien verarbeiten musste. Audacity konnte viele von ihnen nicht öffnen (derzeit hat Audacity keine Unterstützung für Ogg Vorbis WAV-Dateien mit der Codec-ID 6771 ), nicht zu erwähnen, dass Dateien nicht rekursiv verarbeitet werden können (die Apply-Chain-Funktion ist auf Dateien in einem einzigen Verzeichnis beschränkt).

Am Ende schrieb ich das ogg_wav- Skript, um Ogg Vorbis WAV in ein besser nutzbares Format zu konvertieren. Das Skript hat viele Optionen und Fehlerbehandlung. Es kann Ogg Vorbis WAV in unkomprimiertes WAV konvertieren ( -cOption) oder den primären OGG-Stream ( -eOption, die Standardeinstellung, wenn keine Optionen bereitgestellt werden) unter anderem extrahieren . Es werden Dateien ohne Ogg-Streams übersprungen. Mit der -dOption wird die ursprüngliche .wav-Datei gelöscht.

Im einfachsten Fall funktioniert das so: Es prüft, ob die Datei Ogg-Stream mit ogginfo hat, überprüft, ob die erforderlichen Schreibberechtigungen vorhanden sind, sucht nach der ersten "OggS" -Markierung und versucht mit moggsplit, Ogg-Stream (s) zu extrahieren Es gibt mehr als einen. Es wird davon ausgegangen, dass der größte spielbare Ogg-Stream derjenige ist, den wir wollen. Das Skript kann auch einige kompliziertere Fälle verarbeiten und hat viele Optionen, um ogg_wav -halle anzuzeigen.

Hier einige Beispiele zur Verwendung. Zuerst muss das Skript installiert werden: download ogg_wav (es erfordert die Bash-Shell und ich habe es nur unter Linux getestet), mache es ausführbar (mit chmod +x) und stelle es zur Verfügung /usr/local/bin/.

So konvertieren Sie Ogg Vorbis WAV in OGG (es ist möglich, mehr als 1 Datei anzugeben oder Shell-Globbing zu verwenden *.wav):

ogg_wav ogg-vorbis.wav 

Der obige Befehl erstellt ogg-vorbis.ogg, indem der größte spielbare OGG-Stream aus der WAV-Datei extrahiert wird.

Bei einer großen Anzahl von Dateien ist es besser, GNU parallel zu verwenden. Dies ist der Befehl, um Ogg Vorbis WAV rekursiv in unkomprimiertes WAV zu konvertieren ( -dOption remove, wenn Sie die Sicherung der ursprünglichen WAV-Dateien durch Ändern der Erweiterung .wav in .bak beibehalten möchten):

find DIRECTORY -type f -iname '*.wav' | parallel ogg_wav -cd '{}' 

Das Skript überspringt WAV-Dateien ohne Ogg-Stream, sodass Sie auch unkomprimierte WAV- und Ogg-Vorbis-WAV-Dateien im selben Ordner verwenden können.