在两台iOS设备之间通过bonjour传输图像
我的目标是通过bonjour将AVCParteInput捕获的图像从一个iOS设备传输到另一个iOS设备 以下是我目前的方法: 1) 从视频输入捕获帧在两台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
- (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;
}
}
}