2014-11-08 64 views
1

我可以在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()? (或改善重新連接時間的策略?)

+0

我遇到同樣的問題。 – 2016-05-09 02:27:35

回答

0

我想你需要移動到你自己的網絡I/O處理和數據塊格式。