如何从iphone相机获取实时视频流并将其发送到服务器?

时间:2012-09-03 05:39:38

标签: iphone objective-c ffmpeg

我正在使用AVCaptureSession来捕获视频并从iPhone摄像头获取实时帧但是如何将其发送到具有帧和声音多路复用的服务器以及如何使用ffmpeg来完成此任务,如果任何人有有关ffmpeg的任何教程或任何示例请在这里分享。

3 个答案:

答案 0 :(得分:24)

我这样做的方法是实现一个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上有一个H.264编码器芯片> = 3GS。问题是它不是面向流的。也就是说,它输出最后解析视频所需的元数据。这为您提供了一些选择。

1)获取原始数据并使用FFmpeg在手机上进行编码(将使用大量的CPU和电池)。

2)为H.264 / AAC输出编写自己的解析器(非常难)。

3)以块的形式记录和处理(将增加延迟等于块的长度,并在启动和停止会话时在每个块之间减少大约1/4秒的视频)。

答案 1 :(得分:4)

Look hereand here

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

还检查堆栈下面的另一个堆栈溢出帖子

(The post below was found at this link here)

  

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

 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领土。这与app商店并不完全兼容。

     

我建议使用AVFoundation和AVAssetWriter来提高效率   的原因。

答案 2 :(得分:3)

有一个很长很短的故事。

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

这是一个起点。

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

然后你可以看一下具有特定功能“encodedFrame”的kickflip,它被称为后退,编码帧从这一点到达你可以用它做你想做的事,通过websocket发送。有一堆很难读取mpeg原子的代码