31

我正在使用AVCaptureSession从 iPhone 摄像头捕获视频并获取实时帧,但是如何将其发送到具有帧和声音多路复用的服务器以及如何使用 ffmpeg 来完成此任务,如果有人有任何关于 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];

然后输出设备的委托(这里是 self)必须实现回调:

-(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

看这里这里

尝试使用 AV Foundation 框架捕获视频。使用 HTTP 流将其上传到您的服务器。

另请查看下面的堆栈另一个堆栈溢出帖子

(下面的帖子是在这个链接上找到的)

你很可能已经知道了......

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

你不能做这个。AVFoundation API 从各个角度防止了这种情况。我什至尝试过命名管道和其他一些鬼鬼祟祟的 unix foo。没有这样的运气。您别无选择,只能将其写入文件。在您链接的帖子中,用户建议设置回调以传递编码帧。据我所知,这对于 H.264 流是不可能的。捕获委托将提供以特定像素格式编码的图像。进行编码的是 Movie Writers 和 AVAssetWriter。

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

是的。但是,您必须使用 libx264 才能进入 GPL 领域。这与应用商店不完全兼容。

出于效率原因,我建议使用 AVFoundation 和 AVAssetWriter。

于 2012-09-16T23:48:38.150 回答
4

它有一个长短的故事。

这是简短的:去看看https://github.com/OpenWatch/H264-RTSP-Server-iOS

这是一个起点。

你可以得到它,看看他是如何提取框架的。这是一个小而简单的项目。

然后您可以查看具有特定功能“encodedFrame”的kickflip,它被回调一次,并且编码帧从这一点到达您可以用它做您想做的事情,通过websocket发送。有一堆非常硬的代码可用于读取 mpeg 原子

于 2015-11-01T09:35:30.820 回答