在iOS中裁剪视频为正方形 [Swift 3]

8

我在使用Swift 3和iOS 10.x时遇到了将视频裁剪成正方形的问题。在执行裁剪程序后,我将视频保存到照片库中,但它看起来与原始视频相同。

我参考了以下文章:Cropping AVAsset video with AVFoundation not working iOS 8

func suqareCropVideo(inputURL: NSURL, completion: @escaping (_ outputURL : NSURL?) -> ())
{
    let videoAsset: AVAsset = AVAsset( url: inputURL as URL )
    let clipVideoTrack = videoAsset.tracks( withMediaType: AVMediaTypeVideo ).first! as AVAssetTrack

    let composition = AVMutableComposition()
    composition.addMutableTrack(withMediaType: AVMediaTypeVideo, preferredTrackID: CMPersistentTrackID())

    let videoComposition = AVMutableVideoComposition()
    videoComposition.renderSize = CGSize( width: clipVideoTrack.naturalSize.height, height: clipVideoTrack.naturalSize.height )
    videoComposition.frameDuration = CMTimeMake(1, 30)

    let transformer = AVMutableVideoCompositionLayerInstruction(assetTrack: clipVideoTrack)

    let instruction = AVMutableVideoCompositionInstruction()
    instruction.timeRange = CMTimeRangeMake(kCMTimeZero, CMTimeMakeWithSeconds(60, 30))


    let transform1: CGAffineTransform = CGAffineTransform(translationX: clipVideoTrack.naturalSize.height, y: (clipVideoTrack.naturalSize.width - clipVideoTrack.naturalSize.height) / 2)
    let transform2 = transform1.rotated(by: .pi/2)
    let finalTransform = transform2


    transformer.setTransform(finalTransform, at: kCMTimeZero)

    instruction.layerInstructions = [transformer]
    videoComposition.instructions = [instruction]

    // Export
    let exportSession = AVAssetExportSession(asset: videoAsset, presetName: AVAssetExportPresetHighestQuality)!
    print ("random id = \(NSUUID().uuidString)")

    let croppedOutputFileUrl = URL( fileURLWithPath: getOutputPath( NSUUID().uuidString) ) // CREATE RANDOM FILE NAME HERE
    exportSession.outputURL = croppedOutputFileUrl
    exportSession.outputFileType = AVFileTypeQuickTimeMovie

    exportSession.exportAsynchronously() { handler -> Void in
        if exportSession.status == .completed {
            print("Export complete")
            DispatchQueue.main.async(execute: {
                completion(croppedOutputFileUrl as NSURL)
            })
            return
        } else if exportSession.status == .failed {
            print("Export failed - \(String(describing: exportSession.error))")
        }

        completion(nil)
        return
    }
}

以下是使用方法:

    if videoURL != nil {
        print ("crop video")
        suqareCropVideo(inputURL: self.videoURL, completion: { (outputURL) -> () in
            print ("compressed url = \(String(describing: outputURL))")

            // Save video to photo library
            PHPhotoLibrary.shared().performChanges({
                PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL:outputURL! as URL)
            }) { saved, error in
                if saved {
                    print ("save successful")
                }
                else {
                    print ("save failed")
                }
            }
        })
    }

你能够实现这个吗? - Ankit Kumar Gupta
1
@AnkitKumarGupta 是的,在将Agreensh的评论添加到我的上面的代码后,它成功地工作了。 - CTRLALTDELx64
2个回答

6
您实际上没有在导出器上设置视频合成。
因此,请尝试:
exportSession.videoComposition = videoComposition

在开始导出之前。


2
谢谢@Agreensh。我错过了那个! - CTRLALTDELx64

0
presetName: AVAssetExportPresetHighestQuality,

更改当前名称,您可以从多个选择中进行选择。 在我的情况下:- let preferredPreset = AVAssetExportPresetLowQuality 可以工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接