2015-03-21 2 views
0

Я читаю AudioInputStream и использую его, чтобы сделать chunked POST-запрос на сервер для потоковой передачи звука. Я не понимаю, почему метод read() в потоке всегда возвращает 0, также после того, как он вызвал stop() и close() на TargetDataLine. Я ожидаю, что в какой-то момент будет -1, поскольку поток закрыт, и на нем больше нет данных (EOF). Это вызывает у меня проблемы с вызовом HTTP-клиента Apache, который делает POST, потому что в какой-то момент он ожидает, что -1 прекратит запись выходного потока и таким образом никогда не завершит цикл записи.Почему чтение AudioInputStream никогда не возвращает -1?

Вот фрагмент кода:

public class MicrophoneTest { 

// record duration, in milliseconds 
static final long RECORD_TIME = 5000; 

private static AudioFormat audioFormat = new AudioFormat(48000, 16, 1, true, false); 

public static void main(String[] args) throws URISyntaxException, IOException { 
    final Microphone recorder = new Microphone(audioFormat); 

    recorder.open(); 

    // creates a new thread that waits for a specified 
    // of time before stopping 
    Thread stopper = new Thread(new Runnable() { 
     public void run() { 
      try { 
       Thread.sleep(RECORD_TIME); 
      } catch (InterruptedException ex) { 
       ex.printStackTrace(); 
      } 
      recorder.close(); 
     } 
    }); 

    stopper.start(); 

    // start recording 
    AudioInputStream inputStream = recorder.start(); 

    ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); 

    byte[] buffer = new byte[1000]; 
    int read = -1; 
    while ((read = inputStream.read(buffer)) != -1) { 
     System.out.println(read); 
     outputStream.write(buffer); 
    } 

    // Never gets here! 
} 
} 



public class Microphone { 

private static final Logger LOGGER = LoggerFactory.getLogger(Microphone.class); 

// format of audio file 
private static final AudioFileFormat.Type fileType = AudioFileFormat.Type.WAVE; 

// the line from which audio data is captured 
private TargetDataLine line; 

private AudioFormat audioFormat; 

public Microphone(AudioFormat audioFormat) { 
    this.audioFormat = audioFormat; 
} 

/** 
* Prepare the line for recording 
* 
* @return 
*/ 
public boolean open() { 
    try { 
     Info info = AudioSystem.getMixerInfo()[4]; 
     line = (TargetDataLine) AudioSystem.getTargetDataLine(audioFormat, info); 
     line.open(audioFormat); 

    } catch (LineUnavailableException ex) { 
     LOGGER.error(ex.toString(), ex); 
     return false; 
    } 
    return true; 
} 

/** 
* Captures the sound and return the stream 
*/ 
public AudioInputStream start() { 

    if (line != null) { 

     line.start(); // start capturing 

     LOGGER.info("Start recording..."); 

     return new AudioInputStream(line); 

     // AudioSystem.write(ais, fileType, outputStream); 

    } else { 
     throw new IllegalStateException("Line has not created. Cannot start recording"); 
    } 
} 

/** 
* Stops the recording process 
*/ 
public void stop() { 
    line.stop(); 
    LOGGER.info("Stop recording..."); 
} 

/** 
* Closes the target data line to finish capturing and recording  * 
*/ 
public void close() { 
    line.stop(); 
    line.close(); 
    LOGGER.info("Data line closed"); 
} 
} 
+0

Действительно ли он возвращает ноль? Это должно быть сделано только в том случае, если буфер имеет нулевую длину. – EJP

+0

Он возвращает 0, когда я закрываю TargetDataLine –

+0

Ну, это ошибка. Он должен вернуть -1. Но все, что вам нужно, это то, что вы должны зацикливаться на '> 0' вместо'! = -1'. Или предоставите 'FilterInputStream', который исправляет buf. – EJP

ответ

1

Линия микрофона никогда не достигнет конца файла. Он включен или выключен. Он не читает файл с места на диске или в памяти.

Я думаю, что вам нужно изменить время цикла на что-то вроде следующего:

while(isRecording) 
{ 
    read = inputStream.read(buffer); 
    outputStream.write(buffer, 0, read); 
} 

и ваш стоп() метод включает

isRecording = false; 

и ваш метод запуска() включают

isRecording = true; 

и т.п. Такие вещи.

+0

Что вы предлагаете передать InputStream на ApacheHttp? Он ожидает InputStream, что какая-то точка возвращает -1 (EOF). –

+0

Если код приема не может быть переписан, как предлагается, возможно, используйте входящий поток на основе микрофона в качестве источника для нового InputStream (шаблон адаптера?). Затем, когда вы выключаете втулку, вы можете кодировать в -1 как последний элемент. –

Смежные вопросы