2010-09-29 4 views
11


Voici le problème. J'utilise AVCaptureVideoDataOutput pour obtenir des images vidéo de la caméra et créer une vidéo avec AVAssetWriter. Cela fonctionne bien, mais la vidéo que je reçois est à l'envers car l'orientation par défaut de l'appareil pour mon application est le paysage à gauche, pas le paysage à droite, comme indiqué par défaut dans AVCaptureVideoDataOutput. En essayant de changer d'orientation dans la classe AVCaptureConnection, mais isVideoOrientationSupported est toujours faux, est-il possible de le réparer?Comment changer l'orientation vidéo pour AVCaptureVideoDataOutput

Voici un code:

AVCaptureDeviceInput *captureInput = [AVCaptureDeviceInput 
      deviceInputWithDevice:[AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo] 
      error:nil]; 
/*We setupt the output*/ 
AVCaptureVideoDataOutput *captureOutput = [[AVCaptureVideoDataOutput alloc] init]; 
captureOutput.alwaysDiscardsLateVideoFrames = YES; 
captureOutput.minFrameDuration = CMTimeMake(1.0, 24.0); //Uncomment it to specify a minimum duration for each video frame 
[captureOutput setSampleBufferDelegate:self queue:dispatch_get_main_queue()]; 

// Set the video output to store frame in BGRA (It is supposed to be faster) 
NSString* key = (NSString*)kCVPixelBufferPixelFormatTypeKey; 
NSNumber* value = [NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA]; 



NSDictionary* videoSettings = [NSDictionary dictionaryWithObject:value forKey:key]; 
[captureOutput setVideoSettings:videoSettings]; 


/*And we create a capture session*/ 
self.captureSession = [[AVCaptureSession alloc] init]; 
self.captureSession.sessionPreset = AVCaptureSessionPresetLow; 
/*We add input and output*/ 
if ([self.captureSession canAddInput:captureInput]) 
{ 
    [self.captureSession addInput:captureInput]; 
} 
if ([self.captureSession canAddOutput:captureOutput]) 
{ 
    [self.captureSession addOutput:captureOutput]; 
} 

/*We add the preview layer*/ 
self.prevLayer = [AVCaptureVideoPreviewLayer layerWithSession: self.captureSession]; 

if ([self.prevLayer isOrientationSupported]) 
{ 
    [self.prevLayer setOrientation:AVCaptureVideoOrientationLandscapeLeft]; 
} 

self.prevLayer.frame = self.view.bounds; 

self.prevLayer.videoGravity = AVLayerVideoGravityResizeAspectFill; 
[self.view.layer addSublayer: self.prevLayer]; 

AVCaptureConnection *videoConnection = NULL; 

[self.captureSession beginConfiguration]; 

for (AVCaptureConnection *connection in [captureOutput connections]) 
{ 
    for (AVCaptureInputPort *port in [connection inputPorts]) 
    { 
    if ([[port mediaType] isEqual:AVMediaTypeVideo]) 
    { 
    videoConnection = connection; 

    } 
    } 
} 
    if([videoConnection isVideoOrientationSupported]) // **Here it is, its always false** 
    { 
     [videoConnection setVideoOrientation:AVCaptureVideoOrientationLandscapeLeft]; 
    } 

[self.captureSession commitConfiguration]; 

[self.captureSession startRunning]; 

Upd: pensé que lors de l'exportation vidéo, le AVAssetExportSession perd d'info preferredTransform.

+0

Steve, avez-vous eu ce travail? Je voulais savoir comment vous avez utilisé AVAssetWriter avec ceci. Je veux être en mesure de diffuser de la vidéo depuis l'iPhone. – nickfox

+0

J'espère que ça aide. http://pastebin.com/RVEqWnyN – Steve

+0

Lorsque vous utilisez l'URL que vous obtenez: Le "Pastebin" a peut-être expiré ou a été supprimé! –

Répondre

10

J'ai rencontré le même problème et j'ai contourné l'AVCamDemo de la WWDC. Je ne sais pas pourquoi (encore) mais si vous interrogez votre videoConnection juste après avoir créé toutes les entrées/sorties/connexions, isVideoOrientationSupported et supportedVideoOrientation retournent NO.

Cependant, si vous interrogez supportsVideoOrientation ou isVideoOrientationSupported à un moment plus tard (après l'interface graphique est configuré par exemple), il retournera OUI. Par exemple je l'interroge juste après que l'utilisateur clique sur le bouton d'enregistrement juste avant que j'appelle [[self movieFileOutput] startRecordingToOutputFileURL ...]

Fais l'essai, travaille pour moi.

+0

Oh wow, c'est difficile! Mais ça fonctionne. Je pense qu'Apple devrait résoudre ce problème. La propriété isVideoOrientationSupported doit pouvoir être définie sur la même boucle de lancement que AVCaptureOutput est créée. Le faire à un moment ultérieur rend inutilement le code plus compliqué. Même s'il y a une raison derrière, au moins le document devrait en parler. Je dois transformer manuellement mes coordonnées pour lire le pixel avant de trouver ce post! – Hlung

+1

En fait, vous n'avez pas besoin de le faire dans un runloop plus tard. Vous pouvez le faire juste après avoir ajouté addOutput: à AVCaptureSession. – Hlung

+0

Ceci est une réponse de sauvetage. Je ne peux vraiment pas comprendre pourquoi rien dans ces conditions n'est mentionné dans la documentation. – aqs

Questions connexes