据我所知,没有内置的方法可以做到这一点。正如您所说,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 编码的,因此转码只会更改文件的标题格式。