2016-10-03 3 views
6

Ich habe einen Code gemacht, der Gerät Videoeingang erfasst und bis jetzt funktioniert es gut. Hier ist, was ichWie kann AVCaptureMovieFileOutput die Videoausrichtung während der laufenden Sitzung ändern?

// add preview layer 
_previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:_session]; 
_previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill; 
[self.videoView.layer addSublayer:_previewLayer]; 

// add movie output 
_movieFileOutput = [[AVCaptureMovieFileOutput alloc] init]; 
[_session addOutput:_movieFileOutput]; 
AVCaptureConnection *movieFileOutputConnection = [_movieFileOutput connectionWithMediaType:AVMediaTypeVideo]; 
movieFileOutputConnection.videoOrientation = [self videoOrientationFromCurrentDeviceOrientation]; 

// start session 
[_session startRunning]; 

gesetzt haben, wo:

- (AVCaptureVideoOrientation) videoOrientationFromCurrentDeviceOrientation { 
    switch ([[UIApplication sharedApplication] statusBarOrientation]) { 
     case UIInterfaceOrientationPortrait: { 
      return AVCaptureVideoOrientationPortrait; 
     } 
     case UIInterfaceOrientationLandscapeLeft: { 
      return AVCaptureVideoOrientationLandscapeLeft; 
     } 
     case UIInterfaceOrientationLandscapeRight: { 
      return AVCaptureVideoOrientationLandscapeRight; 
     } 
     case UIInterfaceOrientationPortraitUpsideDown: { 
      return AVCaptureVideoOrientationPortraitUpsideDown; 
     } 
     case UIInterfaceOrientationUnknown: { 
      return 0; 
     } 
    } 
} 

Nun, wenn Schnittstelle Orientierungsänderungen ich meine Ausgabe wollen auch zu ändern, so habe ich dies:

- (void) updatePreviewLayer { 
    _previewLayer.frame = CGRectMake(0, 0, self.videoView.frame.size.width, self.videoView.frame.size.height); 
    _previewLayer.connection.videoOrientation = [self videoOrientationFromCurrentDeviceOrientation]; 
    [_session beginConfiguration]; 
    AVCaptureConnection *movieFileOutpurConnection = [_movieFileOutput connectionWithMediaType:AVMediaTypeVideo]; 
    movieFileOutpurConnection.videoOrientation = [self videoOrientationFromCurrentDeviceOrientation]; 
    [_session commitConfiguration]; 
} 

Aber leider funktioniert es nicht. Es scheint, sobald ich zuerst die Videoausrichtung auf die Filmausgabe eingestellt habe, bleibt es wie folgt, es kann später nicht mehr geändert werden. Wenn ich also im Querformat und dann im Hochformat filme, ist das Video für den Querformatmodus geeignet, aber der Hochformatmodus wird gedreht. Das gleiche gilt, wenn ich im Hochformat starte, wird die Landschaft gedreht.

Gibt es eine Möglichkeit, dies richtig zu machen?

Antwort

1

Versuchen Sie, diese hinzufügen, bevor Sie Ihre Sitzung starten:

[_movieFileOutput setRecordsVideoOrientationAndMirroringChanges:YES asMetadataTrackForConnection:movieFileOutputConnection]; 

Die Header-Datei Dokumentation für diese Methode macht es sehr viel klingen wie das, was Sie suchen:

Steuert, ob nicht Die Filmdateiausgabe erstellt eine zeitgesteuerte Metadatenspur, die Samples aufnimmt, die Änderungen widerspiegeln, die an den VideoOrientation- und videoMirrored-Eigenschaften der angegebenen Verbindung während der -Aufzeichnung vorgenommen wurden.

Dort gibt es interessantere Informationen, ich würde alles lesen.

Diese Methode rotiert jedoch nicht Ihre Frames, sondern verwendet zeitgesteuerte Metadaten, um Spieler dazu zu bringen, dies bei der Wiedergabe zu tun. Daher ist es möglich, dass nicht alle Player diese Funktion unterstützen. Wenn das ein Deal Breaker ist, dann können Sie AVCaptureMovieFileOutput zugunsten der unteren Ebene verlassen AVCaptureVideoDataOutput + AVAssetWriter Kombination, wo Ihre videoOrientation Änderungen tatsächlich den Rahmen drehen, in Dateien führen, die korrekt in jedem Player wiedergeben werden:

Wenn ein Die videoOrientation- oder videoMirrored-Eigenschaften der AVCaptureVideoDataOutput-Instanzverbindung sind auf Nicht-Standardwerte eingestellt. Der Ausgang wendet die gewünschte Spiegelung und Ausrichtung an, indem er Sample-Buffer während des Durchlaufs physisch dreht und dreht.

p.s. Ich glaube nicht, dass Sie das Paar beginConfiguration/commitConfiguration benötigen, wenn Sie nur eine Eigenschaft ändern, um mehrere Modifikationen in ein atomares Update zu packen.

1

Haben Sie versucht, die Sitzung anzuhalten, bevor Sie die Konfiguration geändert haben?

Verwandte Themen