J'utilise AVCaptureSession
pour capturer la vidéo et obtenir la trame en temps réel de la caméra de l'iPhone, mais comment puis-je l'envoyer au serveur avec multiplexage de la trame et du son et comment utiliser ffmpeg pour terminer cette tâche, si quelqu'un a un didacticiel à propos de ffmpeg ou de tout autre exemple, veuillez partager ici.
La façon dont je le fais est d'implémenter un AVCaptureSession, qui a un délégué avec un rappel qui s'exécute sur chaque trame. Ce rappel envoie chaque trame sur le réseau au serveur, qui a une configuration personnalisée pour la recevoir.
Voici le flux:
Et voici un peu de code:
// 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];
Ensuite, le délégué du périphérique de sortie (ici, self) doit implémenter le rappel:
-(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 );
}
L'envoi d'images brutes ou d'images individuelles ne fonctionnera jamais assez bien pour vous (en raison de la quantité de données et du nombre d'images). Vous ne pouvez pas non plus servir quoi que ce soit à partir du téléphone (les réseaux WWAN ont toutes sortes de pare-feu). Vous devrez encoder la vidéo et la diffuser sur un serveur, très probablement sur un format de streaming standard (RTSP, RTMP). Il y a une puce d'encodeur H.264 sur l'iPhone> = 3GS. Le problème est qu'il n'est pas orienté flux. Autrement dit, il génère les métadonnées nécessaires pour analyser la vidéo en dernier. Cela vous laisse quelques options.
1) Obtenez les données brutes et utilisez FFmpeg pour encoder sur le téléphone (utilisera une tonne de CPU et de batterie).
2) Écrivez votre propre analyseur pour la sortie H.264/AAC (très difficile).
3) Enregistrez et traitez en morceaux (ajoutera une latence égale à la longueur des morceaux et déposez environ 1/4 de seconde de vidéo entre chaque morceau lorsque vous démarrez et arrêtez les sessions).
Essayez de capturer des vidéos à l'aide du framework AV Foundation. Téléchargez-le sur votre serveur avec le streaming HTTP.
Consultez également une pile un autre message de débordement de pile ci-dessous
(Le post ci-dessous a été trouvé sur ce lien ici)
Vous savez probablement déjà ...
1) How to get compressed frames and audio from iPhone's camera?
Tu ne peux pas faire ça. L'API AVFoundation a empêché cela sous tous les angles. J'ai même essayé des pipes nommées et quelques autres foo unix sournois. Pas de chance. Vous n'avez pas d'autre choix que de l'écrire dans un fichier. Dans votre publication liée, un utilisateur suggère de configurer le rappel pour fournir des images codées. Pour autant que je sache, cela n'est pas possible pour les flux H.264. Le délégué de capture fournira des images encodées dans un format de pixel spécifique. Ce sont les Movie Writers et AVAssetWriter qui font l'encodage.
2) Encoding uncompressed frames with ffmpeg's API is fast enough for
real-time streaming?
Oui, ça l'est. Cependant, vous devrez utiliser libx264 qui vous permet d'accéder au territoire GPL. Ce n'est pas exactement compatible avec l'App Store.
Je suggère d'utiliser AVFoundation et AVAssetWriter pour des raisons d'efficacité.
Il y a une longue et une courte histoire.
C'est le court: allez voir https://github.com/OpenWatch/H264-RTSP-Server-iOS
c'est un point de départ.
vous pouvez l'obtenir et voir comment il extrait le cadre. Il s'agit d'un petit projet simple.
Ensuite, vous pouvez regarder kickflip qui a une fonction spécifique "encodedFrame", ses onces rappelées et la trame encodée arrivent à partir de ce point, vous pouvez faire ce que vous voulez avec, envoyer via websocket. Il y a un tas de code très dur disponible pour lire les atomes MPEG