使用前置摄像头时需要镜像video方向和旋转

我不能完全弄清楚如何处理前置摄像头的video捕捉方向。 在拍摄图像时捕捉video和图像以及处理前置相机的所有旋转,以及除正面相机video捕获之外还保存捕获的video和图像以及正确的方向,我都处理后置相机的所有旋转。

第一个问题是,在横向模式下,video没有正确的方向保存。 第二个问题是保存的video是镜像的。 虽然我知道如何处理使用前置摄像头的图片的镜像效果,但我不知道该如何处理video。

我在尝试为这个问题寻找任何东西时遇到了很多麻烦,但是没有做到这一点。 如果有人能够指出我解决这个具体问题的线程,那将是非常棒的。

无论哪种方式,这是调用设备方向更改时处理video方向的方法。 如果使用前置摄像头,我不确定要添加到我的代码中。

/************************************************************************** DEVICE ORIENTATION DID CHANGE **************************************************************************/ func deviceOrientationDidChange() { println("DEVICE ORIENTATION DID CHANGE CALLED") let orientation: UIDeviceOrientation = UIDevice.currentDevice().orientation //------ IGNORE THESE ORIENTATIONS ------ if orientation == UIDeviceOrientation.FaceUp || orientation == UIDeviceOrientation.FaceDown || orientation == UIDeviceOrientation.Unknown || orientation == UIDeviceOrientation.PortraitUpsideDown || self.currentOrientation == orientation { println("device orientation does not need to change --- returning...") return } self.currentOrientation = orientation //------ APPLY A ROTATION USING THE STANDARD ROTATION TRANSFORMATION MATRIX in R3 ------ /* xyz --- --- x | cosø sinø 0 | y | -sinø consø 0 | z | 0 0 1 | --- --- */ //----- PERFORM BUTTON AND VIDEO DATA BUFFER ROTATIONS ------ switch orientation { case UIDeviceOrientation.Portrait: rotateButtons(self.degrees0) if self.usingFrontCamera == true { } else { } println("Device Orientation Portrait") break case UIDeviceOrientation.LandscapeLeft: println("Device Orientation LandScapeLeft") rotateButtons(self.degrees90) if self.usingFrontCamera == true { println("Using front camera, rotation in landscape left") // if let connection = self.captureConnection { // // connection.videoOrientation = AVCaptureVideoOrientation.LandscapeRight // // println("Capture connection Orientation is LandScape Right") // } // else { // // println("Capture connection is nil, could not change video orientation") // } } else { if let connection = self.captureConnection { connection.videoOrientation = AVCaptureVideoOrientation.LandscapeRight println("Capture connection Orientation is LandScape Right") } else { println("Capture connection is nil, could not change video orientation") } } break case UIDeviceOrientation.LandscapeRight: println("Device Orientation LandscapeRight") rotateButtons(-self.degrees90) if self.usingFrontCamera == true { println("Using front camera, rotation in landscape right") // if let connection = self.captureConnection { // // connection.videoOrientation = AVCaptureVideoOrientation.LandscapeRight // // println("Capture connection Orientation is LandScape Left") // } // else { // // println("Capture connection is nil, could not change video orientation") // } } else { if let connection = self.captureConnection { connection.videoOrientation = AVCaptureVideoOrientation.LandscapeLeft println("Capture connection Orientation is LandScape Left") } else { println("Capture connection is nil, could not change video orientation") } } break default: break } } 

基于这个答案: video保存在错误的方向AVCaptureSession

我面临同样的问题,并能够解决这个post后。

     var videoConnection:AVCaptureConnection? 

for connection in self.fileOutput.connections { for port in connection.inputPorts! { if port.mediaType == AVMediaTypeVideo { videoConnection = connection as? AVCaptureConnection if videoConnection!.supportsVideoMirroring { videoConnection!.videoMirrored = true } } } }

请让我知道,如果它可以帮助你詹姆斯

接受的答案只会反映预览中的video。 你需要改变你的video。

  func mirrorVideo(inputURL: URL, completion: @escaping (_ outputURL : URL?) -> ()) { let videoAsset: AVAsset = AVAsset( url: inputURL ) let clipVideoTrack = videoAsset.tracks( withMediaType: AVMediaType.video ).first! as AVAssetTrack let composition = AVMutableComposition() composition.addMutableTrack(withMediaType: AVMediaType.video, preferredTrackID: CMPersistentTrackID()) let videoComposition = AVMutableVideoComposition() videoComposition.renderSize = CGSize(width: clipVideoTrack.naturalSize.height, height: clipVideoTrack.naturalSize.width) videoComposition.frameDuration = CMTimeMake(1, 30) let transformer = AVMutableVideoCompositionLayerInstruction(assetTrack: clipVideoTrack) let instruction = AVMutableVideoCompositionInstruction() instruction.timeRange = CMTimeRangeMake(kCMTimeZero, CMTimeMakeWithSeconds(60, 30)) var transform:CGAffineTransform = CGAffineTransform(scaleX: -1.0, y: 1.0) transform = transform.translatedBy(x: -clipVideoTrack.naturalSize.width, y: 0.0) transform = transform.rotated(by: CGFloat(Double.pi/2)) transform = transform.translatedBy(x: 0.0, y: -clipVideoTrack.naturalSize.width) transformer.setTransform(transform, at: kCMTimeZero) instruction.layerInstructions = [transformer] videoComposition.instructions = [instruction] // Export let exportSession = AVAssetExportSession(asset: videoAsset, presetName: AVAssetExportPreset640x480)! let fileName = UniqueIDGenerator.generate().appending(".mp4") let filePath = documentsURL.appendingPathComponent(fileName) let croppedOutputFileUrl = filePath exportSession.outputURL = croppedOutputFileUrl exportSession.outputFileType = AVFileType.mp4 exportSession.videoComposition = videoComposition exportSession.exportAsynchronously { if exportSession.status == .completed { DispatchQueue.main.async(execute: { completion(croppedOutputFileUrl) }) return } else if exportSession.status == .failed { print("Export failed - \(String(describing: exportSession.error))") } completion(nil) return } } 

在你的AVCaptureFileOutputRecordingDelegate

  func fileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?) { self.mirrorVideo(inputURL: outputFileURL) { (url) in self.delegate!.videoRecordingEnded(videoURL: url!) } }