Загружайте потоковое видео с iPhone как Ustream или Qik - PullRequest
40 голосов
/ 25 декабря 2009

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

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

Ответы [ 2 ]

46 голосов
/ 09 апреля 2011

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

0 голосов
/ 21 февраля 2011

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

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

...