Ios 录制裁剪视频方形纵横比AVCaptureSession
如何使用AVCaptureSession录制方形视频?如果录制时无法进行,那么如何在录制后根据委托方法在Ios 录制裁剪视频方形纵横比AVCaptureSession,ios,swift,avfoundation,avcapturesession,avcapturedevice,Ios,Swift,Avfoundation,Avcapturesession,Avcapturedevice,如何使用AVCaptureSession录制方形视频?如果录制时无法进行,那么如何在录制后根据委托方法在didfinishRedingTodelegate方法中进行裁剪 提前谢谢 您可以使用以下演示代码录制square视频: 或 您可以使用以下方法裁剪视频: func manageCroppingToSquare(filePath: URL , completion: @escaping (_ outputURL : URL?) -> ()) { // output fi
didfinishRedingTo
delegate方法中进行裁剪
提前谢谢 您可以使用以下演示代码录制square视频: 或 您可以使用以下方法裁剪视频:
func manageCroppingToSquare(filePath: URL , completion: @escaping (_ outputURL : URL?) -> ()) {
// output file
let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first
let outputPath = documentsURL?.appendingPathComponent("squareVideo.mov")
if FileManager.default.fileExists(atPath: (outputPath?.path)!) {
do {
try FileManager.default.removeItem(atPath: (outputPath?.path)!)
}
catch {
print ("Error deleting file")
}
}
//input file
let asset = AVAsset.init(url: filePath)
print (asset)
let composition = AVMutableComposition.init()
composition.addMutableTrack(withMediaType: AVMediaTypeVideo, preferredTrackID: kCMPersistentTrackID_Invalid)
//input clip
let clipVideoTrack = asset.tracks(withMediaType: AVMediaTypeVideo)[0]
//make it square
let videoComposition = AVMutableVideoComposition()
videoComposition.renderSize = CGSize(width: CGFloat(clipVideoTrack.naturalSize.height), height: CGFloat(clipVideoTrack.naturalSize.height))
videoComposition.frameDuration = CMTimeMake(1, 30)
let instruction = AVMutableVideoCompositionInstruction()
instruction.timeRange = CMTimeRangeMake(kCMTimeZero, CMTimeMakeWithSeconds(60, 30))
//rotate to potrait
let transformer = AVMutableVideoCompositionLayerInstruction(assetTrack: clipVideoTrack)
let t1 = CGAffineTransform(translationX: clipVideoTrack.naturalSize.height, y: -(clipVideoTrack.naturalSize.width - clipVideoTrack.naturalSize.height) / 2)
let t2: CGAffineTransform = t1.rotated(by: .pi/2)
let finalTransform: CGAffineTransform = t2
transformer.setTransform(finalTransform, at: kCMTimeZero)
instruction.layerInstructions = [transformer]
videoComposition.instructions = [instruction]
//exporter
let exporter = AVAssetExportSession.init(asset: asset, presetName: AVAssetExportPresetMediumQuality)
exporter?.outputFileType = AVFileTypeQuickTimeMovie
exporter?.outputURL = outputPath
exporter?.videoComposition = videoComposition
exporter?.exportAsynchronously() { handler -> Void in
if exporter?.status == .completed {
print("Export complete")
DispatchQueue.main.async(execute: {
completion(outputPath)
})
return
} else if exporter?.status == .failed {
print("Export failed - \(String(describing: exporter?.error))")
}
completion(nil)
return
}
}
我希望此代码适用于您。您可以使用此演示代码录制square视频: 或 您可以使用以下方法裁剪视频:
func manageCroppingToSquare(filePath: URL , completion: @escaping (_ outputURL : URL?) -> ()) {
// output file
let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first
let outputPath = documentsURL?.appendingPathComponent("squareVideo.mov")
if FileManager.default.fileExists(atPath: (outputPath?.path)!) {
do {
try FileManager.default.removeItem(atPath: (outputPath?.path)!)
}
catch {
print ("Error deleting file")
}
}
//input file
let asset = AVAsset.init(url: filePath)
print (asset)
let composition = AVMutableComposition.init()
composition.addMutableTrack(withMediaType: AVMediaTypeVideo, preferredTrackID: kCMPersistentTrackID_Invalid)
//input clip
let clipVideoTrack = asset.tracks(withMediaType: AVMediaTypeVideo)[0]
//make it square
let videoComposition = AVMutableVideoComposition()
videoComposition.renderSize = CGSize(width: CGFloat(clipVideoTrack.naturalSize.height), height: CGFloat(clipVideoTrack.naturalSize.height))
videoComposition.frameDuration = CMTimeMake(1, 30)
let instruction = AVMutableVideoCompositionInstruction()
instruction.timeRange = CMTimeRangeMake(kCMTimeZero, CMTimeMakeWithSeconds(60, 30))
//rotate to potrait
let transformer = AVMutableVideoCompositionLayerInstruction(assetTrack: clipVideoTrack)
let t1 = CGAffineTransform(translationX: clipVideoTrack.naturalSize.height, y: -(clipVideoTrack.naturalSize.width - clipVideoTrack.naturalSize.height) / 2)
let t2: CGAffineTransform = t1.rotated(by: .pi/2)
let finalTransform: CGAffineTransform = t2
transformer.setTransform(finalTransform, at: kCMTimeZero)
instruction.layerInstructions = [transformer]
videoComposition.instructions = [instruction]
//exporter
let exporter = AVAssetExportSession.init(asset: asset, presetName: AVAssetExportPresetMediumQuality)
exporter?.outputFileType = AVFileTypeQuickTimeMovie
exporter?.outputURL = outputPath
exporter?.videoComposition = videoComposition
exporter?.exportAsynchronously() { handler -> Void in
if exporter?.status == .completed {
print("Export complete")
DispatchQueue.main.async(execute: {
completion(outputPath)
})
return
} else if exporter?.status == .failed {
print("Export failed - \(String(describing: exporter?.error))")
}
completion(nil)
return
}
}
我希望此代码对您有用。谢谢您的回答!我将测试它,并给出一个答案。当然,但请对我的帖子做同样的操作,因为有人给了我否决票,但不知道为什么。该库是从资源打开视频并修改渲染设置,它不是录制相机lib@famfamfam我已经更新了网址,现在检查。谢谢回答!我将测试它,并给出一个答案。当然,但请对我的帖子做同样的操作,因为有人给了我否决票,但不知道为什么。该库是从资源打开视频并修改渲染设置,它不是录制相机lib@famfamfam我已经更新了URL,现在检查。