我想从菜单中选择的视频裁剪方形视频,其方向已固定。我搜索了很多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
}
}
}
我做错了什么。有没有更好的方法来修复视频方向和中心裁剪(使用最小宽度或高度值)?