我想播放从互联网服务接收到的流媒体。媒体播放器工作正常,但有时会因下载速度不佳而中断。
在接收媒体数据时,我运行一个执行解码和其他操作的线程,抽象代码如下所示:
private void startConsuming(final InputStream input) {
consumingThread = new Thread() {
public void run() {
runConsumingThread(input);
}
};
consumingThread.start();
}
我的想法是计算防止中断所需的缓冲区大小,并在缓冲区填满后开始媒体播放(或者,当然,如果流结束)。
private void startConsuming(final InputStream input) {
consumingThread = new Thread() {
public void run() {
runConsumingThread(input);
}
};
Thread fillBufferThread = new Thread() {
public void run() {
try {
while(input.available() < RECEIVING_BUFFER_SIZE_BYTES) {
log.debug("available bytes: " + input.available());
sleep(20);
}
} catch (Exception ex) {
// ignore
}
consumingThread.start();
}
};
fillBufferThread.start();
}
在调试中,当流到达并且不会中断 while 循环时,我不断得到“可用字节:0”。我已经认识到,EOFException 不会发生,因为我没有从 InputStream 中读取。
我该如何处理?我认为 input.available() 会在数据到达时增加。
为什么 runConsumingThread(input) 可以以几乎相同的方式正常工作,但我在 fillBufferThread 中的 while 循环却不能?
编辑:下面的代码几乎可以工作(除了它错误地消耗了输入流,然后不会在消耗线程中播放,但这很容易解决),但必须有一个更聪明的解决方案。
[...]
Thread fillBufferThread = new Thread() {
public void run() {
final DataInputStream dataInput = new DataInputStream(input);
try {
int bufferSize = 0;
byte[] localBuffer = new byte[RECEIVING_BUFFER_SIZE_BYTES];
while(bufferSize < RECEIVING_BUFFER_SIZE_BYTES) {
int len = dataInput.readInt();
if(len > localBuffer.length){
if (D) log.debug("increasing buffer length: " + len);
localBuffer = new byte[len];
}
bufferSize += len;
log.debug("available bytes: " + bufferSize);
dataInput.readFully(localBuffer, 0, len);
}
consumingThread.start();
}
};
[...]
在我知道我已经将它填充了许多字节之前,从流中读取它是没有效率的,或者是吗?