简体   繁体   中英

AVAssetWriter rotate buffer for video orientation

I'm working on a live recording app in Swift using AVFoundation and I have an issue with the video orientation. I use AVAssetWriter and not AVCaptureMovieFileOutput because I need to record in square format (correct me if I'm wrong).

I tried to use videoInput.transform but I heard that it is not supported in all video player.

I can't use avcaptureconnection.videoOrientation based on the device orientation because there is some "Main UI thread stop".

I read that the best solution is to rotate the CMSampleBuffer in the AVCaptureVideoDataOutputSampleBufferDelegate delegate function captureOutput(...) . It looks a bit complicated, the Apple's doc is not helping a lot and many posts are in Objective-C .

Before going that way, I would like to know if there are some solutions that I could have missed. Thank you

Since you are using AVAssetWriter . Try,

  private let assetWriter: AVAssetWriter
  private var adaptor: AVAssetWriterInputPixelBufferAdaptor

And initialize AVAssetWriter like this,

adaptor = AVAssetWriterInputPixelBufferAdaptor(rotationAngle: AVCaptureDevice.correctOrientation)
assetWriter = AVAssetWriter(input: adaptor.assetWriterInput)

Create an extension for AVCaptureDevice , Change the angles accordingly to rotate.

// The angle by which to rotate captured media, based on the current orientation, so that it looks correctly oriented to the user.
    var correctOrientation: CGFloat {
        let angle: CGFloat
        switch(UIDevice.current.orientation) {
         case .portraitUpsideDown: angle = -CGFloat.pi / 2 // Play around with these values
         case .landscapeLeft: angle = -CGFloat.pi
         case .landscapeRight: angle = 0
         case .portrait: angle = CGFloat.pi / 2
         default: angle = CGFloat.pi / 2
       }
       return angle
    }

Create another extension for AVAssetWriterInputPixelBufferAdaptor

extension AVAssetWriterInputPixelBufferAdaptor {
  convenience init(rotationAngle: CGFloat) {
    let input = AVAssetWriterInput(width: UIDevice.activeFormat.width, height: UIDevice.activeFormat.height)
    input.transform = CGAffineTransform(rotationAngle: rotationAngle)

    self.init(
      assetWriterInput: input,
      sourcePixelBufferAttributes: [
        kCVPixelBufferPixelFormatTypeKey as String: kCVPixelFormatType_32BGRA, // use whatever format you used
        kCVPixelBufferWidthKey as String: UIDevice.activeFormat.width,
        kCVPixelBufferHeightKey as String: UIDevice.activeFormat.height])
  }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM