我可以在iOS上用FFmpeg播放RTMP音頻+視頻實時流。當所有東西都通過一個可靠的WiFi連接時,它會很棒FFmpeg + iOS +有損蜂窩連接
當我切換到蜂窩連接(信號強度和LTE/4G)時,av_read_frame()
將間歇性地阻塞一段不可接受的時間。從我所知道的情況來看,並非蜂窩數據連接剛剛掉線,因爲我可以立即重新連接並開始下載更多數據包。在某些情況下,我會在返回下一幀之前計時30秒以上的掛起時間。當下一幀最終進入時,我的實時視頻流會永久延遲av_read_frame()
阻止的時間。
我試圖通過使用AVIOInterruptCB
中斷回調來中止av_read_frame()
如果函數返回時間超過1秒。下面是代碼如下所示:
- (void)readPackets {
// Make sure FFmpeg calls our interrupt periodically
_context->interrupt_callback.callback = interrupt_cb;
_context->interrupt_callback.opaque = self;
dispatch_async(_readPacketQueue, ^(void) {
int err;
while(true) {
_readFrameTimeStamp = [[NSDate date] timeIntervalSince1970];
err = av_read_frame(_context, &packet);
_readFrameTimeStamp = 0;
if(err) {
// Error - Reconnect the entire stream from scratch, taking 5-10 seconds
// And we know when av_read_frame() was aborted
// because its error code is -1414092869 ("EXIT")
}
else {
// Play this audio or video packet
}
}
});
}
/**
* Interrupt
* @return 1 to abort the current operation
*/
static int interrupt_cb(void *decoder) {
if(decoder) {
if(_readFrameTimeStamp != 0) {
if([[NSDate date] timeIntervalSince1970] - _readFrameTimeStamp > 1) {
// Abort av_read_frame(), it's taking longer than 1 second
return 1;
}
}
}
}
這絕對中止av_read_frame()
1秒後,但我這樣做之後不幸的是,未來的嘗試調用av_read_frame()
結果EIO
錯誤(-5),這表明連接已切斷。
因此,我被迫完全重新連接觀看者,需要5-10秒。 (avformat_open_input()
需要3-4秒,然後再找到流信息需要2-3秒,然後開始讀取幀)。
完全重新連接5-10秒的延遲比等待av_read_frame()
超過10秒來解除阻塞要好得多,而且比實時數據流延遲了很多。但它比能夠立即重試av_read_frame()更糟糕。
從蜂窩用戶的角度來看,他們的視頻間歇性鎖定5-10秒,而我們從頭開始重新連接背景中的流,這不是一個好的用戶體驗。
有什麼策略可以更好地管理有損蜂窩連接上的av_read_frame()? (或改善重新連接時間的策略?)
我遇到同樣的問題。 – 2016-05-09 02:27:35