我的目标是通过 bonjour 将 AVCpatureInput 捕获的图像从一台 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 连接发送(来自http://mobileorchard.com/tutorial-networking-and-bonjour-on-iphone/)
// Send raw image over network
- (void)sendRawImagePacket:(UIImage *)image {
// Encode packet
NSData * imageData = UIImageJPEGRepresentation(image, 1.0);
NSData * rawPacket = [NSKeyedArchiver archivedDataWithRootObject:imageData];
// Write header: length of raw packet
int packetLength = [rawPacket length];
[outgoingDataBuffer appendBytes:&packetLength length:sizeof(int)];
[outgoingDataBuffer appendData:rawPacket];
// Try to write to stream
[self writeOutgoingBufferToStream];
}
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;
}
}
}
但是,当连接不稳定时,UIImage 会抛出无法呈现 JPEG 的错误。
我应该如何通过wifi传递图像?
如果某些帧跳过也没关系,我需要一种方法来告诉 UIImage 跳过那“一批”坏数据。
谢谢!