swift - 如何确保小视频录制窗口与剪裁窗口一致?

查看:133
本文介绍了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屋!

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