2012-04-07 6 views
0

更新 - 私は以下のコードでいくつかの間違いを修正し、他のデバイスに画像を表示していますが、別の問題があります。ビデオキャプチャが開いている間、「マスター」デバイスは連続的にデータを送信します。このキャプチャは「スレーブ」デバイスに表示され、非常に短時間に画像が「点滅」して空白になり、これについてのアイデアは?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:イメージ];」マスターデバイスでイメージキャプチャをテストするだけです。このイメージはキャプチャデバイスで動作します。

は、次は私がネットワークに送信する方法についてです。私はストリームを読み書きするために実行ループを使用してい

- (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 あるIは、一方のブロックが必要ないと思いますしかし、最初の反復で利用可能なバイトをすべて読み取ることができない場合は、次のバイトで読み込むことができるので、私はそれを使用します。

ので、これがポイントです、ストリームが正しく来るが、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

、私はもうこのメッセージを得る:

他思うが、私はキャプチャを起動したとき、私はデータを受け取る最初の部分は、私はシステムからこのメッセージが表示されます、出力についてです。

ポイントは、 "スレーブ"デバイスに表示されていないイメージの原因を見つけることです。

ありがとうございました。

+0

@ Jan thsiはネットワーク経由で画像を送信しますが、音声はどうですか?画像を使ってオーディオを送る方法は? – sajwan

+0

re:式がない場合は開始できません。ケース内のステートメントを中括弧で囲む必要があります。ケース1:{...}それは難解なCのことです。 –

答えて

0

イメージを送信する頻度はわかりませんが、あまり頻繁ではないにしても、JPEGデータのSOIマーカーとEOIマーカーをスキャンして、すべてのデータを確実に取得すると思います。ここにはpostがあります。すぐに見つかりました

+0

ビデオキャプチャが開いている間、データを継続的に送信しています。 –

0

レンダリング前にjpeg形式を確認するためにanswerが見つかりました。

これは私の問題を解決し、 "マスター" iosデバイスから "スレーブ" iosデバイスへのビデオキャプチャを表示できるようになりました。

+0

私は同じことに取り組んでいます。イメージを受け取ったら、それは壊れているようです。私はあなたのような連続的なイメージを送っています。私の場合、私はinputStream.hasBytesAvailable(function)から出ることはありません。 –

+0

私はデータをストリーミングできますが、遅すぎます。 –

関連する問題