swift - 如何确保小视频录制窗口与剪裁窗口一致?
本文介绍了swift - 如何确保小视频录制窗口与剪裁窗口一致?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
问 题
先说下整个思路:
(1)预览窗口(AVCaptureVideoPreviewLayer)尺寸设置为正方矩形(长宽均为屏幕宽度),并在整个屏幕垂直居中。
//预览窗口是正方形,在屏幕居中(显示的也是摄像头拍摄的中心区域)
videoLayer?.frame = CGRect.init(x: 0, y: 480, width: 1080, height: 1080)
(2)视频片段录制的时候还是使用完整的分辨率尺寸进行录制。
(3)在将各个视频片段合并输出时,我们通过 AVMutableVideoComposition 实现视频的裁剪,即从视频的中央位置裁出一个正方形的内容并保存文件。
//AVMutableVideoComposition:管理所有视频轨道,可以决定最终视频的尺寸,实现视频的裁剪(矩形,截取正中心区域视频)
let videoComposition = AVMutableVideoComposition()
videoComposition.frameDuration = CMTimeMake(1, framesPerSecond) //30fps
videoComposition.renderSize = CGSize.init(width: 1080, height: 1080) //定义最终生成的视频尺寸(矩形)
//AVMutableVideoCompositionInstruction:一个视频轨道,包含了这个轨道上的所有视频素材
let instruction = AVMutableVideoCompositionInstruction()
instruction.timeRange = CMTimeRangeMake(kCMTimeZero, CMTimeMakeWithSeconds(Float64(totalSeconds), framesPerSecond))
//AVMutableVideoCompositionLayerInstruction:对视频轨道中的一个视频Layer的指令,可以缩放、旋转等
let transformer = AVMutableVideoCompositionLayerInstruction.init(assetTrack: videoTrack)
let t1 = CGAffineTransform(translationX: 1080, y: -420)
let t2 = t1.rotated(by: CGFloat(M_PI_2))
let finalTransform: CGAffineTransform = t2
transformer.setTransform(finalTransform, at: kCMTimeZero)
instruction.layerInstructions = [transformer]
videoComposition.instructions = [instruction]
几个重要值:
视频原始尺寸: (1920.0, 1080.0)
最终渲染尺寸: (1080.0, 1080.0)
预览窗口:(x: 0, y: 480, width: 1080, height: 1080)
剪裁窗口:(x: 0, y: 0, width: 1080, height: 1080)
t1 = CGAffineTransform(translationX: 1080, y: -420)
t2 = t1.rotated(by: CGFloat(M_PI_2))
问题来了:录制下来的视频在(3)中如何经过t1和t2的变换,使得裁剪过后的视频恰好是在(1)中设定的预览窗口?坐标是如何对应的?
解决方案
1、以下两种写法的结果是不一样的,以(1)先平移后旋转的逻辑去理解。
(1)t1 = CGAffineTransform.init(translationX: 1080, y: -420)
t2 = t1.rotated(by: CGFloat(M_PI_2))
(2)t1 = CGAffineTransform.init(rotationAngle: CGFloat.init(M_PI_2))
t2 = t1.translatedBy(x: 1080, y: -420)
2、视频的旋转中心在左上角,所以需要右移 videoTrack.naturalSize.height === 1080
3、视频录制完成后是横向的,左头右尾,居中->所以需要上移 -(videoTrack.naturalSize.width - videoTrack.naturalSize.height)/2 === -420 平移加旋转后,这样录制的视频就和屏幕对应了。
4、(ideoComposition.renderSize)剪裁从(videoLayer.frame)预览窗口的左上角位置开始:
(1)剪裁尺寸>预览尺寸:背景色,以及还有一部分(摄像头拍下的,在屏幕外的)部分来补
(2)剪裁尺寸<预览尺寸:找到对应位置剪裁,拉伸
这篇关于swift - 如何确保小视频录制窗口与剪裁窗口一致?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文