2012-09-03 14 views
29

Estoy usando AVCaptureSession para capturar video y obtener un marco de tiempo real desde la cámara del iPhone pero cómo puedo enviarlo al servidor con multiplexación de fotogramas y sonido y cómo usar ffmpeg para completar esta tarea, si alguien tiene algún tutorial sobre ffmpeg o cualquier ejemplo por favor comparta aquí.¿Cómo obtener la transmisión de video en tiempo real desde la cámara del iPhone y enviarla al servidor?

+1

Supongo que ya está grabando los archivos MOV/MP4 'chunk'. Puede transmitir estos usando un proyecto antiguo que escribí [ffstream] (https://github.com/otmakie/LivuLib) (bifurcado por alguien). Tenga en cuenta que debe mantener un tiempo monótonamente creciente. En otras palabras, su hora de inicio para cada MOV/MP4 debe ser la misma. De esta forma, todos los archivos 1 + N tendrán espacio 'en blanco' al comienzo, y las marcas de tiempo generadas por mov.c en ffmpeg serán correctas. Puede usar RTSP/RTP sobre UDP/TCP o usar el plugin librtmp para ffmpeg para la transmisión. –

+0

@SteveMcFarlin Puede ayudarme a enviar secuencias de local a servidor, significa cómo enviar la transmisión como un fragmento. – Ron

Respuesta

22

La forma en que lo hago es implementar una sesión AVCaptureSession, que tiene un delegado con una devolución de llamada que se ejecuta en cada fotograma. Esa devolución de llamada envía cada fotograma a través de la red al servidor, que tiene una configuración personalizada para recibirlo.

Aquí está el flujo:

http://developer.apple.com/library/ios/#documentation/AudioVideo/Conceptual/AVFoundationPG/Articles/03_MediaCapture.html#//apple_ref/doc/uid/TP40010188-CH5-SW2

Y aquí hay algo de código:

// 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]; 

A continuación, el delegado del dispositivo de salida (en este caso, sí) tiene que implementar la devolución de llamada:

-(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); 

    } 

El envío de marcos sin procesar o imágenes individuales nunca funcionará bien suficiente para ti (debido a la cantidad de datos y cantidad de cuadros). Tampoco puede servir razonablemente nada desde el teléfono (las redes WWAN tienen todo tipo de cortafuegos). Tendrá que codificar el video y transmitirlo a un servidor, muy probablemente a través de un formato de transmisión estándar (RTSP, RTMP). Hay un chip codificador H.264 en el iPhone> = 3GS. El problema es que no está orientado a flujos. Es decir, genera los metadatos necesarios para analizar el último video. Esto te deja con algunas opciones.

1) Obtenga los datos brutos y use FFmpeg para codificar en el teléfono (usará una tonelada de CPU y batería).

2) Escriba su propio analizador para la salida H.264/AAC (muy duro).

3) Grabe y procese en trozos (agregará latencia igual a la longitud de los trozos, y soltará aproximadamente 1/4 de segundo de video entre cada fragmento al comenzar y detener las sesiones).

+0

, Hasta ese momento ya lo hice, gracias por su respuesta. Mi pregunta es, después de eso, cómo envío marcos de audio y video desde el iPhone al servidor. – Ron

+0

Entiendo que esto es antiguo, pero estoy atascado en el lado del servidor de este mismo tema. ¿Cómo configuró su servidor para manejar la secuencia de marcos de imágenes? – Siriss

+0

Página no encontrada por developer.apple.com. – AechoLiu

4

Look here, and here

Trate de captura de vídeo usando marco de la Fundación AV. Suba a su servidor con transmisión HTTP.

También puedes ver una pila otro post desbordamiento de pila por debajo de

(The post below was found at this link here)

Lo más probable es que ya sabe ....

1) How to get compressed frames and audio from iPhone's camera? 

Usted California n no hacer esto. La API AVFoundation lo ha impedido desde en todos los ángulos. Incluso probé tubos con nombre, y algunos otros furtivos unix foo. No hubo suerte. No tienes más remedio que escribirlo en el archivo. En su publicación vinculada , un usuario sugiere configurar la devolución de llamada para entregar marcos codificados. Hasta donde yo sé, esto no es posible para las transmisiones H.264. El delegado de captura entregará las imágenes codificadas en un formato de píxel específico .Son los Movie Writers y AVAssetWriter los que hacen la codificación .

2) Encoding uncompressed frames with ffmpeg's API is fast enough for 
real-time streaming? 

Sí, lo es. Sin embargo, tendrá que usar libx264 que lo lleva al territorio GPL. Eso no es exactamente compatible con la tienda de aplicaciones.

Sugeriría usar AVFoundation y AVAssetWriter por razones de eficiencia .

3

Hay una historia larga y otra corta.

Ésta es la corta: mirada ir en https://github.com/OpenWatch/H264-RTSP-Server-iOS

este es un punto de partida.

puede obtenerlo y ver cómo extrae el marco. Este es un proyecto pequeño y simple.

A continuación, puede ver kickflip que tiene una función específica "encodedFrame", sus funciones llamadas atrás y el marco codificado llega desde este punto puede hacer lo que quiera con él, enviarlo a través de websocket. Hay un montón de código muy difícil disponible para leer los átomos MPEG

Cuestiones relacionadas