2012-04-07 31 views
0

UPDATE - 我已經修復了下面代碼中的一些錯誤,並且圖像顯示在其他設備上,但是我還有其他問題。當視頻捕捉打開時,「主」設備不斷髮送數據,有時這種捕捉會出現在「從屬」設備上,並且在很短的時間內,圖像會「閃爍」爲空白,並在短時間內重複此操作。對此有何想法?IOS從網絡接收視頻

我正在開發一款應用程序,需要將實時相機捕獲和實時麥克風捕獲發送到網絡中的其他設備。

我已經完成了使用TCP服務器的設備之間的連接並將它與bonjour一起發佈,這就像一個魅力。

最重要的部分是要發送和接收來自「主」設備的視頻和音頻,並將其呈現在「從屬」設備上。

首先,這裏的一段代碼,其中該應用獲得相機樣品緩衝液並在變換的UIImage:

@implementation AVCaptureManager (AVCaptureVideoDataOutputSampleBufferDelegate) 

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection 
{ 
    dispatch_sync(dispatch_get_main_queue(), ^{ 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 

    UIImage *image = [self imageFromSampleBuffer:sampleBuffer]; 
    NSData *data = UIImageJPEGRepresentation(image, 0.2); 

    [self.delegate didReceivedImage:image]; 
    [self.delegate didReceivedFrame:data]; 

    [pool drain]; 
    }); 
} 


- (UIImage *) imageFromSampleBuffer:(CMSampleBufferRef) sampleBuffer 
{ 
    CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); 

    CVPixelBufferLockBaseAddress(imageBuffer, 0); 

    size_t width = CVPixelBufferGetWidth(imageBuffer); 
    size_t height = CVPixelBufferGetHeight(imageBuffer); 
    size_t bytesPerRow = width * 4; 

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 

    void *baseAddress = CVPixelBufferGetBaseAddress(imageBuffer); 

    CGContextRef context = CGBitmapContextCreate(
               baseAddress, 
               width, 
               height, 
               8, 
               bytesPerRow, 
               colorSpace, 
               kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Little 
               ); 

    CGImageRef quartzImage = CGBitmapContextCreateImage(context); 

    UIImage *image = [UIImage imageWithCGImage:quartzImage]; 
    CGImageRelease(quartzImage); 
    CGColorSpaceRelease(colorSpace); 
    CGContextRelease(context); 
    CVPixelBufferUnlockBaseAddress(imageBuffer, 0); 

    return image; 
} 

@end 

消息「[self.delegate didReceivedImage:圖像];」只是爲了測試主設備上的圖像捕捉,並且此圖像適用於捕捉設備。

下一個是關於我如何將其發送到網絡:我使用RunLoop寫入和讀取流

- (void) sendData:(NSData *)data 
{ 
    if(_outputStream && [_outputStream hasSpaceAvailable]) 
    { 
    NSInteger bytesWritten = [_outputStream write:[data bytes] maxLength:[data length]]; 

    if(bytesWritten < 0) 
     NSLog(@"[ APP ] Failed to write message"); 

    } 
} 

看,我認爲這是比開放好,並關閉不斷流。

接着,收到從屬設備上的「NSStreamEventHasBytesAvailable」事件,該件的代碼,其中處理是這樣的:

case NSStreamEventHasBytesAvailable: 
     /*I can't to start a case without a expression, why not?*/ 
     NSLog(@"[ APP ] stream handleEvent NSStreamEventHasBytesAvailable"); 
     NSUInteger bytesRead; 
     uint8_t buffer[BUFFER_SIZE]; 

     while ([_inputStream hasBytesAvailable]) 
     { 
     bytesRead = [_inputStream read:buffer maxLength:BUFFER_SIZE]; 
     NSLog(@"[ APP ] bytes read: %i", bytesRead); 

     if(bytesRead) 
      [data appendBytes:(const void *)buffer length:sizeof(buffer)]; 
     } 


     [_client writeImageWithData:data]; 

     break; 

BUFFER_SIZE的值是32768。 我認爲而塊是沒有必要,但我使用它,因爲如果我在第一次迭代時無法讀取所有可用的字節,我可以在下一個讀取。

所以,這是一點,流來正確,但是序列上的NSData的形象似乎被破壞,在未來,我只是將數據發送到客戶端...

[_client writeImageWithData:data]; 

...創造與客戶端類簡單的這樣的數據一個UIImage ...

[camPreview setImage:[UIImage imageWithData:data]]; 

在camPreview(沒錯是一個UIImageView),我有一個形象只是爲了在屏幕上顯示的佔位符,當我從網絡IMAGEM並傳遞給camPreview,佔位符變爲空白。

其他認爲這是關於輸出,當我開始拍攝,我在那裏接收數據的第一部分,我從系統得到這個消息:

Error: ImageIO: JPEG Corrupt JPEG data: 28 extraneous bytes before marker 0xbf

Error: ImageIO: JPEG Unsupported marker type 0xbf

後好一會兒,我得到這個消息了。

重點是找到圖像的原因沒有顯示在「從」設備上。

謝謝。

+0

@ Jan thsi將通過網絡發送圖像,但音頻怎麼樣?如何用圖像發送音頻? – sajwan 2013-01-15 22:43:20

+0

re:無法在沒有表達式的情況下啓動一個案例。你必須用括號括起你的案例中的陳述,例如案例1:{...}這是一個深奧的C事情。 – 2014-01-12 03:31:20

回答

0

我不確定您發送圖像的頻率如何,但即使不是很常見,我認爲我會掃描JPEG數據中的SOI和EOI標記以確保您擁有所有數據。這是一個post我很快找到了

+0

我在視頻捕捉打開時連續發送數據。 – 2012-04-10 20:04:22

0

我發現answer在渲染前檢查jpeg格式。

這解決了我的問題,現在我可以顯示從「主」ios設備到「從屬」ios設備的視頻捕獲。

+0

我正在做同樣的事情,當我收到圖像時,它似乎已損壞。我像你一樣發送連續的圖像。在我的情況下,我從來沒有從inputStream.hasBytesAvailable {函數。 – 2017-06-13 03:55:10

+0

沒關係,我可以傳輸數據,但速度太慢。 – 2017-06-13 07:08:51