AVAssetWriter поворачивает буфер для ориентации видео

#ios #swift #avfoundation #avassetwriter #cmsamplebuffer

#iOS #swift #avfoundation #avassetwriter #cmsamplebuffer

Вопрос:

Я работаю над приложением для записи в реальном времени в Swift использовании AVFoundation , и у меня проблема с ориентацией видео. Я использую AVAssetWriter , а не AVCaptureMovieFileOutput потому что мне нужно записывать в квадратном формате (поправьте меня, если я ошибаюсь).

Я пытался использовать videoInput.transform , но слышал, что это поддерживается не во всех видеопроигрывателях.

Я не могу использовать avcaptureconnection.videoOrientation в зависимости от ориентации устройства, потому что есть какая-то «Остановка основного потока пользовательского интерфейса».

Я читал, что лучшим решением является поворот CMSampleBuffer в AVCaptureVideoDataOutputSampleBufferDelegate функции делегирования captureOutput(...) . Это выглядит немного сложно, документ Apple не очень помогает, и многие сообщения находятся в Objective-C .

Прежде чем идти этим путем, я хотел бы знать, есть ли какие-то решения, которые я мог пропустить. Спасибо

Ответ №1:

Поскольку вы используете AVAssetWriter . Попробуйте,

   private let assetWriter: AVAssetWriter
  private var adaptor: AVAssetWriterInputPixelBufferAdaptor
  

И инициализирует AVAssetWriter следующим образом,

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

Создайте extension для AVCaptureDevice , соответствующим образом измените углы поворота.

 // 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
    }
  

Создайте другой extension для 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])
  }