비디오 실시간 스트림을 다운로드하는 알고리즘을 작성하려고합니다. 특히 내가 가져 오려고하는 각 스트림은 동적으로 .m3u8 재생 목록 파일을 기반으로하며,이 파일은 새 비디오 파일의 URI를 주기적으로 제공합니다. 주요 목표는 개별 미디어 파일을 하나의 일관된 InputStream으로 결합하는 것입니다.
실제로 작동시키기에 성공했습니다. 정기적으로 재생 목록에 나타나는 새 미디어 파일을 확인하고 HTTP 스트림을 사용자 지정 InputStream 구현 즉, InputStreamChain으로 전달합니다. 라이브 스트림이기 때문에 최소한 무한한이라고 가정합니다. Ergo, 내 InputStreamChain
의 read()
이 -1을 보내지 않기를 바랬다. 불행하게도, 그것은했다. 대기열에있는 모든 미디어 스트림이 소비 될 때마다 InputStreamChain
이 종료되었습니다. 대신 새로운 미디어 파일이 도착할 때까지 I/O를 차단하고 싶었습니다. 그래서 저는 작업 솔루션을 생각해 냈습니다. read()
메서드를 사용하여 새로운 스트림이있을 때까지 루프를 조정했습니다 (TimerTask
은 새 파일을 제공함). 내가이에되어있어 어떻게 그 일을 아니에요 나는 느낌이, 작동하는 것 같다 있지만InputStream의 read() 블록 입출력
public int read() throws IOException {
int bit = current.read();
if (bit == -1 && streams.size() > 0) {
// left out due to lacking relevance
} else if(bit == -1 && streams.size() == 0) {
while(streams.size() == 0) {
Thread.currentThread().sleep(50);
}
return read();
}
return bit;
}
: 루프에서 필자는 CPU의 부하를 줄이기 위해, Thread.sleep()
내장되어 있습니다. 또한 Lock
을 Condition.await()
과 함께 사용해 보았습니다. 그러나 TimerTask
이 Condition.signal()
을 트리거하려고 시도했을 때, 단지 IllegalMonitorStateException
을 던졌습니다.
나는 특히 내 시나리오에서의 InputStream의 read()
방법을 차단/연기해야하는지 방법으로 왜 나는 질문 부탁 해요 것
?
편집
: 완성도를 위해서는, 나도 내 실패 Lock
접근 방식을 제공하겠습니다 :
private ReentrantLock ioLock;
private Condition ioCond;
private boolean waitingForStream = false;
public InputStreamChain() {
ioLock = new ReentrantLock();
ioCond = ioLock.newCondition();
}
public synchronized InputStreamChain addInputStream(final InputStream stream) {
streams.addLast(stream);
if (current == null) {
current = streams.removeFirst();
}
if(waitingForStream) {
ioCond.signal();
}
return this;
}
public int read() throws IOException {
int bit = current.read();
if (bit == -1 && streams.size() > 0) {
// do stuff
} else if(bit == -1) {
waitingForStream = true;
ioLock.lock();
try {
ioCond.await();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
waitingForStream = false;
ioLock.unlock();
}
return read();
}
return bit;
}
상태 신호를 보내고 상태를 기다리는 데는 잠금 장치가 있어야합니다. – Flavio
@Flavio 나는 내 머리 꼭대기에서 나의 '잠금'접근법을 적어 봤다. 나는 어디로 잘못 갔는가? – MCL
'cond.signal()','lock.unlock()'전에 lock.lock()을 호출해야합니다. – Flavio