iOS - 如何修复视频方向和方形中心裁剪?

时间:2016-05-03 13:07:47

标签: ios video avfoundation avassetexportsession

我想从菜单中选择的视频裁剪方形视频,其方向已固定。我搜索了很多stackoverflow帖子和raywenderlich帖子。

我的代码适用于某些视频,但不是全部。例如,我从画廊中选择了分辨率为352x640的肖像视频。在调试过程中,资产的自然尺寸为640x352,使用preferredTransform时,它会被检测为纵向,但裁剪尺寸设置为640x640而不是中心方形裁剪的352x352。

这是我的代码

let asset = AVAsset(URL: url)
let composition = AVMutableComposition()
let compositionVideoTrack = composition.addMutableTrackWithMediaType(AVMediaTypeVideo, preferredTrackID: Int32(kCMPersistentTrackID_Invalid))
let compositionAudioTrack = composition.addMutableTrackWithMediaType(AVMediaTypeAudio, preferredTrackID: Int32(kCMPersistentTrackID_Invalid))
let videoComposition: AVMutableVideoComposition?
let audioMix: AVMutableAudioMix?
let timeRange = self.timeRange(asset)

if let videoAssetTrack = asset.tracksWithMediaType(AVMediaTypeVideo).first {
   videoComposition = AVMutableVideoComposition()

   var error: NSError?
   do {
       try compositionVideoTrack.insertTimeRange(timeRange, ofTrack: videoAssetTrack, atTime: kCMTimeZero)
    } catch var error1 as NSError {
        error = error1
    } catch {
        fatalError()
    }

    let naturalSize = videoAssetTrack.naturalSize
    let videoSize: CGSize
    var transform = videoAssetTrack.preferredTransform
    var isFirstAssetPortrait_  = false
    if(transform.a == 0 && transform.b == 1.0 && transform.c == -1.0 && transform.d == 0)  {
        isFirstAssetPortrait_ = true}
    if(transform.a == 0 && transform.b == -1.0 && transform.c == 1.0 && transform.d == 0)  {
        isFirstAssetPortrait_ = true
    }
    var FirstAssetScaleToFitRatio = naturalSize.height/naturalSize.width
    if(isFirstAssetPortrait_){
        videoSize = CGSizeMake(naturalSize.width, naturalSize.width)
        FirstAssetScaleToFitRatio = naturalSize.width/naturalSize.height
        var FirstAssetScaleFactor = CGAffineTransformMakeScale(FirstAssetScaleToFitRatio,FirstAssetScaleToFitRatio)
        FirstAssetScaleFactor = CGAffineTransformTranslate(FirstAssetScaleFactor, 0, (naturalSize.height - naturalSize.width) / 2.0 )
        transform = CGAffineTransformConcat(transform, FirstAssetScaleFactor)
     }else{
        videoSize = CGSizeMake(naturalSize.height, naturalSize.height)
        if transform.a >= 0 {
          transform = CGAffineTransformTranslate(transform, -(naturalSize.width - naturalSize.height) / 2.0, 0.0)
        } else {
          transform = CGAffineTransformTranslate(transform, (naturalSize.width - naturalSize.height) / 2.0, 0.0)
        }
      }

      let layerInstruction = AVMutableVideoCompositionLayerInstruction(assetTrack: compositionVideoTrack)

      layerInstruction.setTransform(transform, atTime: kCMTimeZero)

      let videoInstructions = AVMutableVideoCompositionInstruction()
      videoInstructions.timeRange = CMTimeRangeMake(kCMTimeZero, asset.duration)
      videoInstructions.layerInstructions = [layerInstruction]

      videoComposition?.renderSize = videoSize
      videoComposition?.frameDuration = CMTimeMake(1, 30)
      videoComposition?.renderScale = 1.0
      videoComposition?.instructions = [videoInstructions]
    } else {
      videoComposition = nil
    }

    if let audioTrack = asset.tracksWithMediaType(AVMediaTypeAudio).first {
      var error: NSError?
      do {
        try compositionAudioTrack.insertTimeRange(timeRange, ofTrack: audioTrack, atTime: kCMTimeZero)
      } catch var error1 as NSError {
        error = error1
      } catch {
        fatalError()
      }

      let mixParameters = AVMutableAudioMixInputParameters(track: compositionAudioTrack)
      mixParameters.setVolume(1.0, atTime: kCMTimeZero)

      audioMix = AVMutableAudioMix()
      audioMix?.inputParameters = [mixParameters]
    } else {
      audioMix = nil
    }

    self.exporter = AVAssetExportSession(asset: composition, presetName: AVAssetExportPresetHighestQuality)
    self.exporter?.videoComposition = videoComposition
    self.exporter?.audioMix = audioMix
    self.exporter?.outputURL = NSURL.tempFileURL("mp4")
    self.exporter?.outputFileType = AVFileTypeQuickTimeMovie

    self.exporter?.exportAsynchronouslyWithCompletionHandler() {
      if let exporter = self.exporter {
        switch exporter.status {
        case .Failed:

          break
        case .Completed:

        default:
          break
        }
      }
    }

我做错了什么。有没有更好的方法来修复视频方向和中心裁剪(使用最小宽度或高度值)?

0 个答案:

没有答案