Загрузите прямое потоковое видео с iPhone, например, Ustream или Qik

Как жить потоковыми видео с iPhone на сервер, например, Ustream или Qik? Я знаю, что что-то называло Http Live Streaming от Apple, но большинство ресурсов, которые я нашел, говорит только о потоковой передаче видео с сервера на iPhone.

Является ли Apple Http Living Streaming чем-то, что я должен использовать? Или что-то другое? Спасибо.

Ответ 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 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, поэтому транскодирование просто изменяет формат заголовка файла.

Ответ 2

Я не уверен, что вы можете сделать это с помощью HTTP Live Streaming. HTTP Live Streaming сегментирует видеоролик длиной 10 секунд (aprox.) И создает список воспроизведения с этими сегментами. Поэтому, если вы хотите, чтобы iPhone был стороной потокового сервера с потоком HTTP Live Streaming, вам придется выяснить способ сегментации видеофайла и создания списка воспроизведения.

Как это сделать, я не знаю. К сожалению.