Насколько я знаю, нет встроенного способа сделать это. Как вы говорите, 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 );
}
EDIT / UPDATE
Несколько человек спрашивали, как это сделать, не отправляя кадры на сервер один за другим. Ответ сложный ...
Как правило, в приведенной выше функции didOutputSampleBuffer
вы добавляете сэмплы в AVAssetWriter
. На самом деле у меня было три актива записи активистов одновременно - прошлый, настоящий и будущий - управляемый в разных потоках.
Прошлый писатель находится в процессе закрытия файла фильма и его загрузки. Текущий писатель получает выборочные буферы с камеры. Будущий писатель находится в процессе открытия нового файла фильма и подготовки его к данным. Каждые 5 секунд я устанавливаю past=current; current=future
и перезапускаю последовательность.
Затем он загружает видео в виде 5-секундных блоков на сервер. Вы можете сшить видео вместе с ffmpeg
, если хотите, или перекодировать их в транспортные потоки MPEG-2 для HTTP Live Streaming. Видеоданные сами по себе кодируются H.264 средством записи ресурсов, поэтому транскодирование просто меняет формат заголовка файла.