在两台iOS设备之间通过bonjour传输图像

在两台iOS设备之间通过bonjour传输图像,ios,avfoundation,bonjour,nskeyedarchiver,Ios,Avfoundation,Bonjour,Nskeyedarchiver,我的目标是通过bonjour将AVCParteInput捕获的图像从一个iOS设备传输到另一个iOS设备 以下是我目前的方法: 1) 从视频输入捕获帧 - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection { /*c

我的目标是通过bonjour将AVCParteInput捕获的图像从一个iOS设备传输到另一个iOS设备

以下是我目前的方法:

1) 从视频输入捕获帧

- (void)captureOutput:(AVCaptureOutput *)captureOutput 
didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer 
   fromConnection:(AVCaptureConnection *)connection 
{ 
    /*code to convert sampleBuffer into UIImage */
    NSData * imageData = UIImageJPEGRepresentation(image,1.0);
    [connection sendImage:image];
}
2) 通过TCP连接发送(从)

3) 读取数据并将其转换回要在接收设备的UIImageView上显示的图像

// Read as many bytes from the stream as possible and try to extract meaningful packets
- (void)readFromStreamIntoIncomingBuffer {
// Temporary buffer to read data into
UInt8 buf[1024];

// Try reading while there is data
while( CFReadStreamHasBytesAvailable(readStream) ) {  
   CFIndex len = CFReadStreamRead(readStream, buf, sizeof(buf));
if ( len <= 0 ) {
  // Either stream was closed or error occurred. Close everything up and treat this as "connection terminated"
  [self close];
  [delegate connectionTerminated:self];
  return;
 }

  [incomingDataBuffer appendBytes:buf length:len];
}

// Try to extract packets from the buffer.
//
// Protocol: header + body
//  header: an integer that indicates length of the body
//  body: bytes that represent encoded NSDictionary

// We might have more than one message in the buffer - that's why we'll be reading it inside the while loop
 while( YES ) {
// Did we read the header yet?
if ( packetBodySize == -1 ) {
  // Do we have enough bytes in the buffer to read the header?
  if ( [incomingDataBuffer length] >= sizeof(int) ) {
    // extract length
    memcpy(&packetBodySize, [incomingDataBuffer bytes], sizeof(int));

    // remove that chunk from buffer
    NSRange rangeToDelete = {0, sizeof(int)};
    [incomingDataBuffer replaceBytesInRange:rangeToDelete withBytes:NULL length:0];
  }
  else {
    // We don't have enough yet. Will wait for more data.

      break;

  }
}

// We should now have the header. Time to extract the body.
if ( [incomingDataBuffer length] >= packetBodySize ) {
  // We now have enough data to extract a meaningful packet.
  NSData* raw = [NSData dataWithBytes:[incomingDataBuffer bytes] length:packetBodySize];

  // Tell our delegate about it

            NSData * imageData = [NSKeyedUnarchiver unarchiveObjectWithData:raw];

            UIImage * image = [UIImage imageWithData:imageData];
            [delegate receivedNetworkRawImage:image viaConnection:self];


  // Remove that chunk from buffer
  NSRange rangeToDelete = {0, packetBodySize};
  [incomingDataBuffer replaceBytesInRange:rangeToDelete withBytes:NULL length:0];

  // We have processed the packet. Resetting the state.
  packetBodySize = -1;
}
else {
  // Not enough data yet. Will wait.
  break;
 }
}
}
//从流中读取尽可能多的字节,并尝试提取有意义的数据包
-(无效)从流读入入缓冲区{
//将数据读入的临时缓冲区
uint8buf[1024];
//在有数据时尝试读取
而(CFReadStreamHasBytesAvailable(readStream)){
CFIndex len=CFReadStreamRead(readStream,buf,sizeof(buf));
如果(len=sizeof(int)){
//提取长度
memcpy(&packetBodySize[incomingdatabufferbytes],sizeof(int));
//从缓冲区中删除该块
NSRange rangeToDelete={0,sizeof(int)};
[incomingDataBuffer replaceBytesInRange:rangeToDelete with Bytes:NULL长度:0];
}
否则{
//我们还没有足够的数据。将等待更多数据。
打破
}
}
//我们现在应该有头球了,是时候把尸体取出来了。
如果([incomingDataBuffer length]>=packetBodySize){
//我们现在有足够的数据来提取有意义的数据包。
NSData*raw=[NSData dataWithBytes:[incomingDataBuffer bytes]长度:packetBodySize];
//告诉我们的代表这件事
NSData*imageData=[NSKeyedUnarchiver unarchiveObjectWithData:raw];
UIImage*image=[UIImage imageWithData:imageData];
[代理接收网络rawImage:image viaConnection:self];
//从缓冲区中删除该块
NSRange rangeToDelete={0,packetBodySize};
[incomingDataBuffer replaceBytesInRange:rangeToDelete with Bytes:NULL长度:0];
//我们已处理数据包。正在重置状态。
packetBodySize=-1;
}
否则{
//还没有足够的数据。将等待。
打破
}
}
}
但是,当连接变得断断续续时,UIImage会抛出一个错误,即它无法渲染JPEG

我应该如何通过wifi传递图像

如果某些帧跳过也没关系,我需要一种方法告诉UIImage跳过“一批”坏数据


谢谢

UIImage不符合NSCoding-->NSKeyedArchiver失败


您必须使用UIImagePNGRepresentation()来获取图像的数据。或者对压缩数据使用UIImageJPEGresentation()。

是的,我在发送数据时有这样的问题:
NSData*imageData=UIImageJPEGresentation(image,1.0)
我的问题是接收数据。我错过什么了吗?哦,我现在明白了。我会把那玩意儿完全去掉。您已经有NSData。您应该首先使用简单的NSString对象验证网络代码。这样行吗?是的,我已经删除了NSKeyedArchiver。因此,当UIImage到达另一端时,丢失位的问题会被传递到渲染UIImage中。网络代码适用于字符串、数组、图像和字典。然而,流媒体是一个问题,因为有时会出现漏帧。我通过网络发送图像时没有问题,我不知道错误在哪里。您可以测试它是否适用于Base64编码的图像。您好,出于好奇,您是否成功地从一个设备到另一个设备进行了足够好的实时视频流?
// Read as many bytes from the stream as possible and try to extract meaningful packets
- (void)readFromStreamIntoIncomingBuffer {
// Temporary buffer to read data into
UInt8 buf[1024];

// Try reading while there is data
while( CFReadStreamHasBytesAvailable(readStream) ) {  
   CFIndex len = CFReadStreamRead(readStream, buf, sizeof(buf));
if ( len <= 0 ) {
  // Either stream was closed or error occurred. Close everything up and treat this as "connection terminated"
  [self close];
  [delegate connectionTerminated:self];
  return;
 }

  [incomingDataBuffer appendBytes:buf length:len];
}

// Try to extract packets from the buffer.
//
// Protocol: header + body
//  header: an integer that indicates length of the body
//  body: bytes that represent encoded NSDictionary

// We might have more than one message in the buffer - that's why we'll be reading it inside the while loop
 while( YES ) {
// Did we read the header yet?
if ( packetBodySize == -1 ) {
  // Do we have enough bytes in the buffer to read the header?
  if ( [incomingDataBuffer length] >= sizeof(int) ) {
    // extract length
    memcpy(&packetBodySize, [incomingDataBuffer bytes], sizeof(int));

    // remove that chunk from buffer
    NSRange rangeToDelete = {0, sizeof(int)};
    [incomingDataBuffer replaceBytesInRange:rangeToDelete withBytes:NULL length:0];
  }
  else {
    // We don't have enough yet. Will wait for more data.

      break;

  }
}

// We should now have the header. Time to extract the body.
if ( [incomingDataBuffer length] >= packetBodySize ) {
  // We now have enough data to extract a meaningful packet.
  NSData* raw = [NSData dataWithBytes:[incomingDataBuffer bytes] length:packetBodySize];

  // Tell our delegate about it

            NSData * imageData = [NSKeyedUnarchiver unarchiveObjectWithData:raw];

            UIImage * image = [UIImage imageWithData:imageData];
            [delegate receivedNetworkRawImage:image viaConnection:self];


  // Remove that chunk from buffer
  NSRange rangeToDelete = {0, packetBodySize};
  [incomingDataBuffer replaceBytesInRange:rangeToDelete withBytes:NULL length:0];

  // We have processed the packet. Resetting the state.
  packetBodySize = -1;
}
else {
  // Not enough data yet. Will wait.
  break;
 }
}
}