Я читаю 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");
}
}
Действительно ли он возвращает ноль? Это должно быть сделано только в том случае, если буфер имеет нулевую длину. – EJP
Он возвращает 0, когда я закрываю TargetDataLine –
Ну, это ошибка. Он должен вернуть -1. Но все, что вам нужно, это то, что вы должны зацикливаться на '> 0' вместо'! = -1'. Или предоставите 'FilterInputStream', который исправляет buf. – EJP