업데이트 - 아래 코드에서 몇 가지 실수를 수정했으며 이미지는 다른 장치에 표시되지만 다른 문제가 있습니다. 비디오 캡처가 열려있는 동안 "마스터"장치는 데이터를 계속 보내고, 때로는이 캡처가 "슬레이브"장치에 나타나고 매우 짧은 시간에 이미지가 "깜박"해져 짧은 시간 동안이 모든 시간이 반복됩니다. 이것에 대한 어떤 생각?IOS 네트워크에서 비디오 받기
라이브 카메라 캡처 및 라이브 마이크 캡쳐를 네트워크의 다른 기기로 전송해야하는 앱 개발 중입니다.
나는 TCP 서버를 사용하는 장치들 간의 연결을 봉쥬르와 함께 게시했다. 이것은 매력처럼 작동한다.
가장 중요한 부분은 "마스터"장치에서 비디오 및 오디오를 보내고 "슬레이브"장치에서 렌더링하는 것입니다.
첫째, 앱 카메라 샘플 버퍼를 얻고있는 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");
}
}
봐, 나는이 열려보다 더 지속적으로 스트림을 닫 생각 :
다음
내가 그것을 네트워크 전송 방법에 관한 것입니다.다음에, I는 슬레이브 장치에서 "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];
를 손상 ... 그리고 생성 할 것 같다이다 camPreview에서이 같은 간단한 클라이언트 클래스의 데이터와있는 UIImage ...
[camPreview setImage:[UIImage imageWithData:data]];
(예있는 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
re : 표현식이없는 대소 문자를 시작할 수 없습니다. 당신은 귀하의 경우에 중괄호와 함께 진술을 래핑해야합니다. case 1 : {...} 그것은 밀교적인 C의 것입니다. –