Java - начать воспроизведение аудио в позиции X - PullRequest
0 голосов
/ 01 октября 2018

Редактировать: Я использую WAV-файл

Я пытаюсь выяснить, как запустить аудио в определенной позиции (например: 10 секунд в аудиофайл, а не в начале).Прочитав документацию для SourceDataLine , я убедился, что это может быть достигнуто с помощью смещения во время:

line.write(byte[] b, int offset, int length)

, но каждый раз, когда япробовал любое значение, кроме 0 (по умолчанию, я считаю), я получаю java.lang.IndexOutOfBoundsException , который, возможно, еще не прочитал позицию байта x, поэтому не может записать позицию байта x?Я не уверен и ушел почесывая голову.

Я подумал, что это будет достаточно распространенным запросом, но не могу найти ничего онлайн, связанного с этим, только приостановка и возобновление звука.Вероятно, я не ищу должным образом.

В случае, если это имеет значение, вот как я сейчас делаю аудио:

     AudioInputStream stream = AudioSystem.getAudioInputStream("...file...");
     AudioFormat format = stream.getFormat();
     SourceDataLine.Info info = new DataLine.Info(SourceDataLine.class, format,((int)stream.getFrameLength()*format.getFrameSize()));
     SourceDataLine line = (SourceDataLine)AudioSystem.getLine(info);
     int bufferSize = line.getBufferSize();
     byte inBuffer[] = new byte[bufferSize];
     byte outBuffer[] = new byte[bufferSize];
     int numRead, numWritten;

     do {
         numRead = audioStream.read(inBuffer, 0, bufferSize);
            if(numRead <= 0) {
                myAudio.flushStream();
            } else {
                myAudio.writeBytesToStream(inBuffer, numRead);
            }
            do {
                numWritten = myAudio.readBytesFromStream(outBuffer, bufferSize);
                if(numWritten > 0) {
                    line.write(outBuffer, 0, numWritten);
                }
            } while(numWritten > 0);
        } while(numRead > 0);

1 Ответ

0 голосов
/ 01 октября 2018

Возникшая у вас проблема, вероятно, связана с тем, что вы настраиваете offset без настройки length.Если ваш массив имеет длину 10 байтов, и вы начинаете читать 10 байтов со смещения 5 вместо 0, вы читаете 5 байтов после его конца.

Я бы рекомендовал сначала пропустить соответствующее количество байтов, используя skip (long) в AudioInputStream и запись в строку.

AudioInputStream stream = AudioSystem.getAudioInputStream("...file...");
AudioFormat format = stream.getFormat();
// find out how many bytes you have to skip, this depends on bytes per frame (a.k.a. frameSize)
int secondsToSkip = 10;
long bytesToSkip = format.getFrameSize() * ((int)format.getFrameRate()) * secondsToSkip;
// now skip until the correct number of bytes have been skipped
int justSkipped = 0;
while (bytesToSkip > 0 && (justSkipped = stream.skip(bytesToSkip)) > 0) {
    bytesToSkip -= justSkipped;
}
// then proceed with writing to your line like you have done before
[...]

Обратите внимание, что это работает только в том случае, если аудиофайл не сжат.Если вы имеете дело с чем-то вроде .mp3, вам сначала нужно преобразовать поток в PCM (см. https://stackoverflow.com/a/41850901/942774)

...