裁剪视频快速 [英] Crop video swift
问题描述
我正在以方形UIView录制视频,但是当我将视频导出为全屏1080x1920时,我想知道如何将视频从全屏缩小为1:1比例...
I am recording a video in a square UIView but when I export the video is full screen 1080x1920 now I am wondering how I can reduce the video from being full screen to being square ratio 1:1...
这是我设置摄像机的方法:
Here is how I am setting my Video Camera up :
session = AVCaptureSession()
for device in AVCaptureDevice.devices() {
if let device = device as? AVCaptureDevice , device.position == AVCaptureDevicePosition.back {
self.device = device
}
}
for device in AVCaptureDevice.devices(withMediaType: AVMediaTypeAudio) {
let device = device as? AVCaptureDevice
let audioInput = try! AVCaptureDeviceInput(device: device)
session?.addInput(audioInput)
}
do {
if let session = session {
videoInput = try AVCaptureDeviceInput(device: device)
session.addInput(videoInput)
videoOutput = AVCaptureMovieFileOutput()
let totalSeconds = 60.0 //Total Seconds of capture time
let timeScale: Int32 = 30 //FPS
let maxDuration = CMTimeMakeWithSeconds(totalSeconds, timeScale)
videoOutput?.maxRecordedDuration = maxDuration
videoOutput?.minFreeDiskSpaceLimit = 1024 * 1024//SET MIN FREE SPACE IN BYTES FOR RECORDING TO CONTINUE ON A VOLUME
if session.canAddOutput(videoOutput) {
session.addOutput(videoOutput)
}
let videoLayer = AVCaptureVideoPreviewLayer(session: session)
videoLayer?.frame = self.videoPreview.bounds
videoLayer?.videoGravity = AVLayerVideoGravityResizeAspectFill
self.videoPreview.layer.addSublayer(videoLayer!)
session.startRunning()
我看过其他几篇文章,但发现它们不是很有帮助,而且大多数都在Obj C ...
I have seen several other posts but not found them very helpfull, and most of them are in Obj C...
如果有人可以帮助我或向正确的方向发展,我们将不胜感激!
If anyone can help me or put me in the correct direction it's much appreciated!
推荐答案
首先,您需要使用AVCaptureFileOutputRecordingDelegate
.
在视频完成录制后,您专门使用func capture( _ captureOutput: AVCaptureFileOutput!, didFinishRecordingToOutputFileAt outputFileURL: URL!, fromConnections connections: [Any]!, error: Error! )
方法执行裁剪过程.
You specifically use the func capture( _ captureOutput: AVCaptureFileOutput!, didFinishRecordingToOutputFileAt outputFileURL: URL!, fromConnections connections: [Any]!, error: Error! )
method to perform the cropping process, once the video has finished recording.
这里是我曾经实现的裁剪功能的一个示例.您需要传入录制的视频的URL,并传递一个回调,该回调用于在裁剪过程完成后返回裁剪后的视频的新URL.
Here is an example of a cropping function I once implemented. You need to pass in the URL of the video that was recorded and a callback that is used to return the new URL of the cropped video once the cropping process is finished.
func cropVideo( _ outputFileUrl: URL, callback: @escaping ( _ newUrl: URL ) -> () )
{
// Get input clip
let videoAsset: AVAsset = AVAsset( url: outputFileUrl )
let clipVideoTrack = videoAsset.tracks( withMediaType: AVMediaTypeVideo ).first! as AVAssetTrack
// Make video to square
let videoComposition = AVMutableVideoComposition()
videoComposition.renderSize = CGSize( width: clipVideoTrack.naturalSize.height, height: clipVideoTrack.naturalSize.height )
videoComposition.frameDuration = CMTimeMake( 1, self.framesPerSecond )
// Rotate to portrait
let transformer = AVMutableVideoCompositionLayerInstruction( assetTrack: clipVideoTrack )
let transform1 = CGAffineTransform( translationX: clipVideoTrack.naturalSize.height, y: -( clipVideoTrack.naturalSize.width - clipVideoTrack.naturalSize.height ) / 2 )
let transform2 = transform1.rotated(by: CGFloat( M_PI_2 ) )
transformer.setTransform( transform2, at: kCMTimeZero)
let instruction = AVMutableVideoCompositionInstruction()
instruction.timeRange = CMTimeRangeMake(kCMTimeZero, CMTimeMakeWithSeconds( self.intendedVideoLength, self.framesPerSecond ) )
instruction.layerInstructions = [transformer]
videoComposition.instructions = [instruction]
// Export
let croppedOutputFileUrl = URL( fileURLWithPath: FileManager.getOutputPath( String.random() ) )
let exporter = AVAssetExportSession(asset: videoAsset, presetName: AVAssetExportPresetHighestQuality)!
exporter.videoComposition = videoComposition
exporter.outputURL = croppedOutputFileUrl
exporter.outputFileType = AVFileTypeQuickTimeMovie
exporter.exportAsynchronously( completionHandler: { () -> Void in
DispatchQueue.main.async(execute: {
callback( croppedOutputFileUrl )
})
})
}
此外,这是我的getOutputPath
方法的实现:
Also, here is the implementation of my getOutputPath
method:
func getOutputPath( _ name: String ) -> String
{
let documentPath = NSSearchPathForDirectoriesInDomains( .documentDirectory, .userDomainMask, true )[ 0 ] as NSString
let outputPath = "\(documentPath)/\(name).mov"
return outputPath
}
希望这会有所帮助.
这篇关于裁剪视频快速的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!