2017-05-19 2 views
1

Ich habe eine AudioInputStream, die skip() nicht unterstützt. Es wird von jflac unterstützt.AudioInputStream - Suche schneller

Daher verwende ich einen read (byte[]) Aufruf und dumping die Daten, um vorwärts durch die Datei zu springen.

Leider dauert es ungefähr 1 Sekunde, um durch 17MB zu suchen (ungefähr .25 Sekunden, um eine Minute zu suchen), die für meine Zwecke zu langsam ist.

Gibt es etwas, was ich tun kann, um schneller durch eine Datei zu suchen? Ich würde etwas 20-30 mal so schnell brauchen wie das, was ich gerade habe, um eine nette Benutzererfahrung zu haben.

Hier ist mein Code:

private void openStreamsAtRequestedOffset () { 
    encodedInput = AudioSystem.getAudioInputStream(file); 

    AudioFormat baseFormat = encodedInput.getFormat(); 
    AudioFormat decoderFormat = new AudioFormat(
      AudioFormat.Encoding.PCM_SIGNED, baseFormat.getSampleRate(), 
      16, baseFormat.getChannels(), baseFormat.getChannels() * 2, 
      baseFormat.getSampleRate(), false); 

    decodedInput = AudioSystem.getAudioInputStream (decoderFormat, encodedInput); 

    if (seekRequestPercent != NO_SEEK_REQUESTED) { 
     long seekPositionByte = getBytePosition (file, seekRequestPercent); 
     int bytesRead = 0; 

     byte[] skippedData = new byte[ 256 ]; 
     while (bytesRead < seekPositionByte) { 
      int bytesSkipped = decodedInput.read (skippedData); 
      bytesRead += bytesSkipped; 
     } 
    } 

    DataLine.Info info = new DataLine.Info (SourceDataLine.class, decoderFormat); 
    audioOutput = (SourceDataLine) AudioSystem.getLine(info); 
    audioOutput.open(decoderFormat); 
} 

Ich habe versucht, mehr und weniger als 256 Bytes zu lesen, es schien keine sinnvolle Auswirkungen zu haben.

Ich habe auch versucht, die Datei mit einem BufferedInputStream öffnen, skip() darauf aufrufen, und dann übergeben Sie die BufferedInputStream auf AudioSystem.getAudioInputStream() ein paar verschiedene Möglichkeiten, aber auch diese fehlgeschlagen. Immer wenn ich skip anrief, behauptete jflac, der Stream sei geschlossen worden.

Irgendwelche Ideen?

Antwort

0

Zunächst einmal, ich bin nicht überrascht, dass es etwas langsam ist. 17 MB/256 Bytes sind 66406 Schleifeniterationen einer ziemlich langsamen I/O-Operation.


Sie sagte

Ich habe versucht, mehr und weniger als 256 Bytes zu lesen, es schien nicht eine sinnvolle Auswirkungen zu haben.

Aber wenn man sich die Dokumentation ansieht, scheint es, dass sich die Anzahl der Bytes, die man jedes Mal lesen kann, ändern kann.

public int verfügbar() throws IOException

die maximale Anzahl von Bytes zurück, die (oder übersprungen) von diesem Audio-Eingangsstrom gelesen werden können, ohne zu blockieren.

Auch wenn die folgende ist nicht schneller, sollte es zumindest sein richtiger:

long seekPositionByte = getBytePosition (file, seekRequestPercent); 
int bytesRead = 0; 

byte[] skippedData = new byte[ decodedInput.available() ]; 
while (bytesRead < seekPositionByte) { 
    int bytesSkipped = decodedInput.read (skippedData); 
    bytesRead += bytesSkipped; 
} 

Es kann sinnvoll sein, auch zu prüfen, ob es nicht zu weit hinausschießt.

+0

Ja, das habe ich zuerst geschrieben. Es wird möglicherweise für immer mit dieser Bibliothek endlos. Wenn die letzte kleine Anzahl von Bytes gelesen wird, liest die Schleife, wenn die Anforderung klein genug ist, Null und die Schleife wird fortgesetzt. Meine Vermutung ist, dass Musikdateien als Frames ausgedrückt werden.In beiden Fällen ist dieser Code zwar nicht "korrekt", aber er ist genau genug, um einen Musiktitel durchzusuchen (solange ich sicherstelle, dass ich nicht über das Ende hinausgehört, das aussteht.) – JoshuaD

+0

Und jetzt, Ich konzentriere mich auf die großen Probleme. Wenn dieser Code Sekunden dauert, wird er in den Papierkorb verschoben und ich muss eine andere Lösung finden. Ich kann die Ursache dieses Leseproblems später aufspüren und mir einige Möglichkeiten vorstellen, es zu verwalten, aber es ist überhaupt nicht wichtig, bis der Code mehr als ein Prototyp ist. – JoshuaD

+0

"Und jetzt konzentriere ich mich auf die großen Probleme" Nun ja, aber wenn 'decodedInput.available() 'ausreichend groß wäre (und vor allem funktioniert), würde es wahrscheinlich nicht Sekunden dauern. – Michael

0

Sie sollten sicherlich nicht versuchen, Ihre eigenen zu rollen, wenn AudioInputStream.skip() bereits existiert. Wenn Sie eines haben, das es nicht unterstützt, beschweren Sie sich beim Verkäufer. Alles, was zu tun ist, ist `skip() 'für den zugrunde liegenden Stream aufzurufen, der wie ein Datei-Eingabestream momentan sein sollte.

Verwandte Themen