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
後好一會兒,我得到這個消息了。
重點是找到圖像的原因沒有顯示在「從」設備上。
謝謝。
@ Jan thsi將通過網絡發送圖像,但音頻怎麼樣?如何用圖像發送音頻? – sajwan 2013-01-15 22:43:20
re:無法在沒有表達式的情況下啓動一個案例。你必須用括號括起你的案例中的陳述,例如案例1:{...}這是一個深奧的C事情。 – 2014-01-12 03:31:20