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