裁剪视频快速 [英] Crop video swift

查看:97
本文介绍了裁剪视频快速的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在以方形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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆