2017-02-21 101 views
1

現在我正在研究通過MultipeerConnectivity框架實現視頻流的可能性。爲此,我使用NSInputStream和NSOutputStream。通過NSInputStream和NSOutputStream進行視頻流傳輸

問題是:到目前爲止我無法收到任何圖片。現在我試圖通過簡單的圖片並在接收器上顯示它。下面是我的一小段代碼:

發送圖片通過NSOutputStream:

- (void)sendMessageToStream 
{ 
    NSData *imgData = UIImagePNGRepresentation(_testImage); 

    int img_length = (int)[imgData length]; 
    NSMutableData *msgData = [[NSMutableData alloc] initWithBytes:&img_length length:sizeof(img_length)]; 
    [msgData appendData:imgData]; 
    int msg_length = (int)[msgData length]; 

    uint8_t *readBytes = (uint8_t *)[msgData bytes]; 

    uint8_t buf[msg_length]; 
    (void)memcpy(buf, readBytes, msg_length); 

    int stream_len = [_stream writeData:(uint8_t*)buf maxLength:msg_length]; 

    //int stream_len = [_stream writeData:(uint8_t *)buf maxLength:data_length]; 
    //NSLog(@"stream_len = %d", stream_len); 

    _tmpCounter++; 
    dispatch_async(dispatch_get_main_queue(), ^{ 

     _lblOperationsCounter.text = [NSString stringWithFormat:@"Sent: %ld", (long)_tmpCounter]; 
    }); 
} 

上面的代碼工作完全正常。寫入後的stream_len參數等於預期值爲29627字節,因爲圖像的大小約爲25-26 kb。

通過NSinputStream接收圖片:

- (void)readDataFromStream 
{ 
    UInt32 length; 
    if (_currentFrameSize == 0) { 

     uint8_t frameSize[4]; 
     length = [_stream readData:frameSize maxLength:sizeof(int)]; 
     unsigned int b = frameSize[3]; 
     b <<= 8; 
     b |= frameSize[2]; 
     b <<= 8; 
     b |= frameSize[1]; 
     b <<= 8; 
     b |= frameSize[0]; 

     _currentFrameSize = b; 
    } 
    uint8_t bytes[1024]; 

    length = [_stream readData:bytes maxLength:1024]; 

    [_frameData appendBytes:bytes length:length]; 
    if ([_frameData length] >= _currentFrameSize) { 
     UIImage *img = [UIImage imageWithData:_frameData]; 

     NSLog(@"SETUP IMAGE!"); 
     _imgView.image = img; 

     _currentFrameSize = 0; 
     [_frameData setLength:0]; 
    } 

    _tmpCounter++; 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     _lblOperationsCounter.text = [NSString stringWithFormat:@"Received: %ld", (long)_tmpCounter]; 
    }); 
} 

正如你可以看到我想要收到幾個步驟的畫面,這裏的原因。當我試圖從流中讀取數據時,無論我在maxLength:參數中輸入了多少個數字,它總是讀取最大1095個字節。但是,當我在第一段代碼中發送圖片時,它的發送完全沒問題(29627字節,順便說一句,圖片的大小約爲29 kb)

這就是問題出現的地方 - 爲什麼是這樣? 29 kb通過NSOutputStream工作完全正常,當接收導致問題?有沒有一種可靠的方法,使視頻流通過NSInputStream和NSOutputStream工作?我只是沒有找到關於這項技術的很多信息,我發現的只是一些簡單的事情,我知道了。

+0

順便說一下,流正在彼此工作。我忘了提到這一點。所以連接不好的問題可以排除在外。我用簡單的字符串測試過流,它絕對正常工作 –

回答

0

我認爲這個問題是在你的假設,即所有的數據將在NSInputStream,而你正在閱讀它所有的時間。從NSURL對象進行NSInputStream具有異步特性,它應使用NSStreamDelegate進行相應訪問。您可以在POSInputStreamLibrary的自述文件中查看示例。

+0

謝謝你的回覆!我正在嚴格通過NSStreamDelegate方法處理我的NSInputStream,我根本沒有做任何解決方法。所以當我閱讀NSInputStream時,它100%有一些數據要給。主要問題是關於傳遞數據的長度。爲什麼我可以在一次調用中傳遞給29kb的NSOutputStream圖片,但是當我讀到它時,我不能和NSInputStream做同樣的事情? –

+0

因爲你不需要。 //// len是一個設置爲非零值的全局變量; //// mdata是一個NSMutableData對象,當創建新輸入 ////流時,該對象將被重置。 //// displayImage是一個塊,它接受圖像數據和一個參考 ////到圖像將被渲染的層 uint8_t * buf [len]; len = [aStream read:(uint8_t *)buf maxLength:len]; (len> 0){mdata appendBytes:(const void *)buf length:len]; } else { displayImage(mdata,wLayer); } break; –

1

這裏有一個程序,我寫的,告訴您如何:

https://app.box.com/s/94dcm9qjk8giuar08305qspdbe0pc784

建立和Xcode 9項目,並在兩個iOS的11設備上運行的應用程序。

要流式傳輸實時視頻,請觸摸兩個設備之一上的攝像頭圖標。

如果您沒有兩個設備,則可以在模擬器中運行一個應用程序;但是,您只能在真實設備上使用相機(模擬器將顯示播放的視頻)。

只是讓你知道:這不是在設備之間傳輸實時視頻的理想方式(它應該是你最後的選擇)。數據包(與數據流相比)更高效,速度更快。

無論如何,我真的很困惑你的NSInputStream相關的代碼。這裏的東西,使一些更有意義,我認爲:

case NSStreamEventHasBytesAvailable: { 
    // len is a global variable set to a non-zero value; 
    // mdata is a NSMutableData object that is reset when a new input 
    // stream is created. 
    // displayImage is a block that accepts the image data and a reference 
    // to the layer on which the image will be rendered 
    uint8_t * buf[len]; 
    len = [aStream read:(uint8_t *)buf maxLength:len]; 
    if (len > 0) { 
     [mdata appendBytes:(const void *)buf length:len]; 
    } else { 
     displayImage(mdata, wLayer); 
    } 
    break; 
} 

輸出流的代碼應該是這個樣子:

// data is an NSData object that contains the image data from the video 
// camera; 
// len is a global variable set to a non-zero value 
// byteIndex is a global variable set to zero each time a new output 
// stream is created 

if (data.length > 0 && len >= 0 && (byteIndex <= data.length)) { 
      len = (data.length - byteIndex) < DATA_LENGTH ? (data.length - byteIndex) : DATA_LENGTH; 
      uint8_t * bytes[len]; 
      [data getBytes:&bytes range:NSMakeRange(byteIndex, len)]; 
      byteIndex += [oStream write:(const uint8_t *)bytes maxLength:len]; 
     } 

還有很多更多的視頻流比正確設置NSStream類-多很多。你會注意到,在我的應用程序中,我爲輸入和輸出流創建了一個緩存。這解決了如果你不這樣做,你可能會遇到的無數問題。

我從來沒有見過任何人成功使用NSStreams進行視頻流...永遠。這是非常複雜的,有一個原因。

有許多不同的(和更好的)方式來流視頻;我不會走這條路。因爲沒有其他人能夠成功地做到這一點,我只是接受了它。

相關問題