31

ビデオをキャプチャしてiPhoneカメラからリアルタイムフレームを取得するために使用AVCaptureSessionしていますが、フレームとサウンドを多重化してサーバーに送信する方法と、ffmpegを使用してこのタスクを完了する方法を教えてください。ここで共有します。

4

3 に答える 3

27

私がやっている方法は、すべてのフレームで実行されるコールバックを持つデリゲートを持つ AVCaptureSession を実装することです。そのコールバックは、ネットワークを介して各フレームをサーバーに送信します。サーバーには、それを受信するためのカスタム設定があります。

フローは次のとおりです。

http://developer.apple.com/library/ios/#documentation/AudioVideo/Conceptual/AVFoundationPG/Articles/03_MediaCapture.html#//apple_ref/doc/uid/TP40010188-CH5-SW2

そして、ここにいくつかのコードがあります:

// make input device

NSError *deviceError;

AVCaptureDevice *cameraDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];

AVCaptureDeviceInput *inputDevice = [AVCaptureDeviceInput deviceInputWithDevice:cameraDevice error:&deviceError];

// make output device

AVCaptureVideoDataOutput *outputDevice = [[AVCaptureVideoDataOutput alloc] init];

[outputDevice setSampleBufferDelegate:self queue:dispatch_get_main_queue()];

// initialize capture session

AVCaptureSession *captureSession = [[[AVCaptureSession alloc] init] autorelease];

[captureSession addInput:inputDevice];

[captureSession addOutput:outputDevice];

// make preview layer and add so that camera's view is displayed on screen

AVCaptureVideoPreviewLayer *previewLayer = [AVCaptureVideoPreviewLayer    layerWithSession:captureSession];
previewLayer.frame = view.bounds;
[view.layer addSublayer:previewLayer];

// go!

[captureSession startRunning];

次に、出力デバイスのデリゲート (ここでは自己) がコールバックを実装する必要があります。

-(void) captureOutput:(AVCaptureOutput*)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection*)connection

{
CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer( sampleBuffer );

CGSize imageSize = CVImageBufferGetEncodedSize( imageBuffer );

// also in the 'mediaSpecific' dict of the sampleBuffer

   NSLog( @"frame captured at %.fx%.f", imageSize.width, imageSize.height );

    }

生のフレームまたは個々の画像を送信しても、十分に機能することはありません (データ量とフレーム数のため)。また、電話から合理的にサービスを提供することもできません (WWAN ネットワークにはあらゆる種類のファイアウォールがあります)。ビデオをエンコードし、サーバーにストリーミングする必要があります。ほとんどの場合、標準のストリーミング形式 (RTSP、RTMP) を使用します。iPhone >= 3GS には H.264 エンコーダ チップがあります。問題は、ストリーム指向ではないことです。つまり、ビデオを最後に解析するために必要なメタデータを出力します。これにより、いくつかのオプションが残ります。

1) 生データを取得し、FFmpeg を使用して電話でエンコードします (大量の CPU とバッテリーを使用します)。

2) H.264/AAC 出力用の独自のパーサーを作成します (非常に難しい)。

3) チャンクで記録および処理します (チャンクの長さに等しいレイテンシーが追加され、セッションを開始および停止すると、各チャンク間で約 1/4 秒のビデオがドロップされます)。

于 2012-09-13T11:28:15.283 に答える
4

それには長い話と短い話があります。

これは短いものです: https://github.com/OpenWatch/H264-RTSP-Server-iOSを見てください。

これが出発点です。

あなたはそれを手に入れて、彼がどのようにフレームを抽出するかを見ることができます. これは小さくて単純なプロジェクトです。

次に、特定の関数「encodedFrame」を持つキックフリップを確認できます。これは一度コールバックされ、エンコードされたフレームがこの時点から到着し、Websocket 経由で送信することができます。mpeg アトムを読み取ることができる非常にハードなコードがたくさんあります

于 2015-11-01T09:35:30.820 に答える
4

ここと ここ をてください

AV Foundation フレームワークを使用してビデオをキャプチャしてみてください。HTTP ストリーミングでサーバーにアップロードします。

以下のスタック別のスタックオーバーフローの投稿もチェックしてください

(以下の投稿は、このリンクで見つかりました。)

あなたはおそらくすでに知っているでしょう....

 1) How to get compressed frames and audio from iPhone's camera?

これはできません。AVFoundation API は、これをあらゆる角度から防止してきました。名前付きパイプや、その他の卑劣な UNIX foo も試しました。そのような幸運はありません。ファイルに書き込むしかありません。リンクされた投稿では、エンコードされたフレームを配信するようにコールバックを設定することをユーザーが提案しています。私の知る限り、これは H.264 ストリームでは不可能です。キャプチャ デリゲートは、特定のピクセル形式でエンコードされた画像を配信します。エンコードを行うのは Movie Writer と AVAssetWriter です。

 2) Encoding uncompressed frames with ffmpeg's API is fast enough for
 real-time streaming?

はい、そうです。ただし、GPL の領域に入る libx264 を使用する必要があります。それはアプリストアと完全に互換性がありません。

効率的な理由から、AVFoundation と AVAssetWriter を使用することをお勧めします。

于 2012-09-16T23:48:38.150 に答える