Crop video swift

前端 未结 2 840
时光说笑
时光说笑 2021-01-03 06:40

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

2条回答
  •  梦毁少年i
    2021-01-03 07:44

    Firstly you need to make use of the AVCaptureFileOutputRecordingDelegate.

    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.

    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 )
               })
           })
       }
    

    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
    }
    

    Hope this helps.

提交回复
热议问题