【问题标题】:Upload live streaming video from iPhone like Ustream or Qik从 iPhone 上传直播视频,如 Ustream 或 Qik
【发布时间】:2010-12-29 23:13:16
【问题描述】:

如何将视频从 iPhone 直播到 Ustream 或 Qik 等服务器?我知道 Apple 有一种叫做 Http Live Streaming 的东西,但我发现的大多数资源只讨论从服务器到 iPhone 的流式视频。

我应该使用 Apple 的 Http Living Streaming 吗?或者是其他东西?谢谢。

【问题讨论】:

  • 他们没有使用 HTTP Live Streaming。所有最近批准的应用程序实际上都在使用私有 API 来捕获屏幕。几乎令人费解的是,Apple 撤销了对这组特定 CoreGraphics 调用的政策并允许这些应用程序进入。期待在未来的 iPhone OS 版本中为该功能提供一个真正的 API - 这些应用程序将需要在可用时使用它。与此同时,这些目前的私人通话还可以。
  • 嗨,我发现我们可能需要一个像 Wowza 这样的媒体服务器来允许 RTSP 流式传输,但你也可以在不使用 HTTP 的 RTSP 的情况下做类似的事情。实际上我现在对这个话题有点无能为力,如果我错了,请纠正我。我知道人们使用私有 API 来捕获屏幕,但这与将它们流式传输到服务器有什么关系?谢谢!

标签: iphone http video streaming live


【解决方案1】:

据我所知,没有内置的方法可以做到这一点。正如您所说,HTTP Live Streaming 用于下载到 iPhone。

我这样做的方式是实现一个 AVCaptureSession,它有一个委托和一个在每一帧上运行的回调。该回调通过网络将每个帧发送到服务器,服务器有一个自定义设置来接收它。

这是流程:https://developer.apple.com/library/content/documentation/AudioVideo/Conceptual/AVFoundationPG/Articles/04_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 );
}

编辑/更新

有几个人问过如何在不将帧一一发送到服务器的情况下做到这一点。答案很复杂……

基本上,在上面的didOutputSampleBuffer 函数中,您将样本添加到AVAssetWriter。实际上,我同时有三个活跃的资产编写者——过去、现在和未来——在不同的线程上进行管理。

过去的作者正在关闭电影文件并上传它。当前写入器正在接收来自相机的样本缓冲区。未来的作家正在打开一个新的电影文件并准备数据。每 5 秒,我设置 past=current; current=future 并重新启动序列。

然后将视频以 5 秒的时间块上传到服务器。如果需要,您可以将视频与ffmpeg 拼接在一起,或者将它们转码为 MPEG-2 传输流以进行 HTTP 实时流传输。视频数据本身是由资产编写器进行 H.264 编码的,因此转码只会更改文件的标题格式。

【讨论】:

  • 我应该补充一点,我不再这样做了,因为逐帧上传对我来说太慢了。但是,如果您正在寻找一种方法来在帧从设备的摄像头进入时对其进行编辑,那就是它。
  • 您能否分享/协助上传视频机制的代码,它并不像您提到的那样慢?请问有什么提示吗?
  • 嗯,为了加快数据传输速度,必须压缩视频。因此,有两种可能性: 1) 即时压缩,需要编解码器库和大量 CPU;或 2) 使用 iPhone 的内置硬件加速 mp4 压缩——但它只支持流式传输到磁盘。我正在流式传输到磁盘,每隔几秒钟更改一次目标文件并上传完成的文件。即使没有针对我发现的几个 Apple 错误的解决方法,它也非常棘手和复杂。您不能轻易地将单个文件用作管道,因为在文件关闭之前不会写入帧索引。
  • @NoMoreWishes 我上面的解决方案列表在this answer中以不同的方式表述。
  • @kashifmehmood 我想你说的是下载(即看视频)?这个问题是关于将视频从 iPhone 传输到服务器的。视频在服务器上后如何处理它们是一个单独的主题。
【解决方案2】:

我找到了一个可以帮助您解决此问题的库。

HaishinKit Streaming Library

Above Library 为您提供通过 RTMP 或 HLS 流式传输的所有选项。

只需按照这个库给定的步骤并仔细阅读所有说明。请不要直接运行此库中给出的示例代码,它有一些错误,而不是获取所需的类和 pod 到您的演示应用程序中。

我刚刚做了这个,你可以录制屏幕、摄像头和音频。

【讨论】:

  • 您在使用这种方法时遇到了什么样的延迟?比如说从图像被捕获到应用程序接收到图像到发送到服务器的那一刻?
  • 我已将其用于屏幕录制并创建 m3u8 文件。@zr0gravity7
【解决方案3】:

我不确定您是否可以使用 HTTP Live Streaming 做到这一点。 HTTP Live Streaming 以 10 秒(大约)长度对视频进行分段,并使用这些分段创建一个播放列表。 所以如果你想让 iPhone 成为 HTTP Live Streaming 的流服务器端,你必须想办法分割视频文件并创建播放列表。

如何做到这一点超出了我的知识范围。对不起。

【讨论】:

  • 流媒体涉及四个步骤:(1)从硬件编码数据,(2)将数据传输到服务器,(3)将数据转码为正确的下游格式,(4)下载,解码和播放数据。问题与第 2 步有关。您的回答与第 3 步有关。
猜你喜欢
  • 2019-11-19
  • 2014-09-27
  • 2012-10-08
  • 2011-10-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多