2012-04-07 50 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