Почему размер рендеринга VideoCompositionInstruction равен размеру экрана, что портит качество? - PullRequest
0 голосов
/ 08 февраля 2019

Я только начинаю изучать фреймворк AVFoundation.При экспорте моего видео я уменьшаю размер рендеринга видеокомпозиции до размера экрана (UIScreen.main.bounds) перед экспортом, так как его естественный размер (я бы предположил) был бы излишне большим.(По крайней мере, этот коэффициент масштабирования также сделан в учебнике Рэя Вендерлиха - https://www.raywenderlich.com/5135-how-to-play-record-and-merge-videos-in-ios-and-swift,, см. Код ниже).Однако я обнаружил, что это масштабирование фактически ухудшает качество экспортируемого видео (по сравнению с размером рендера = естественный размер видео).Почему это так?Я понимаю, как увеличение размера видео ухудшило бы качество, но если мы просто уменьшим его до меньшего размера (размера экрана), почему качество будет хуже?

Есть ли способ сохранитькачество четкое, без необходимости сохранять размер рендера в натуральном размере?

static func videoCompositionInstruction(_ track: AVCompositionTrack, asset: AVAsset) 
  -> AVMutableVideoCompositionLayerInstruction {
  let instruction = AVMutableVideoCompositionLayerInstruction(assetTrack: track)
  let assetTrack = asset.tracks(withMediaType: .video)[0]

  let transform = assetTrack.preferredTransform
  let assetInfo = orientationFromTransform(transform)

  var scaleToFitRatio = UIScreen.main.bounds.width / assetTrack.naturalSize.width
  if assetInfo.isPortrait {
    scaleToFitRatio = UIScreen.main.bounds.width / assetTrack.naturalSize.height
    let scaleFactor = CGAffineTransform(scaleX: scaleToFitRatio, y: scaleToFitRatio)
    instruction.setTransform(assetTrack.preferredTransform.concatenating(scaleFactor), at: kCMTimeZero)
  } else {
    let scaleFactor = CGAffineTransform(scaleX: scaleToFitRatio, y: scaleToFitRatio)
    var concat = assetTrack.preferredTransform.concatenating(scaleFactor)
      .concatenating(CGAffineTransform(translationX: 0, y: UIScreen.main.bounds.width / 2))
    if assetInfo.orientation == .down {
      let fixUpsideDown = CGAffineTransform(rotationAngle: CGFloat(Double.pi))
      let windowBounds = UIScreen.main.bounds
      let yFix = assetTrack.naturalSize.height + windowBounds.height
      let centerFix = CGAffineTransform(translationX: assetTrack.naturalSize.width, y: yFix)
      concat = fixUpsideDown.concatenating(centerFix).concatenating(scaleFactor)
    }
    instruction.setTransform(concat, at: kCMTimeZero)
  }

  return instruction
}
...