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
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.