|
@@ -0,0 +1,133 @@
|
|
|
+//
|
|
|
+// File.swift
|
|
|
+// BFRecordScreenKit
|
|
|
+//
|
|
|
+// Created by ak on 2021/12/2.
|
|
|
+// 功能:录制头像 ,生成多个 MP4 文件。
|
|
|
+
|
|
|
+import Foundation
|
|
|
+import BFFramework
|
|
|
+
|
|
|
+
|
|
|
+//录制完成回调
|
|
|
+typealias recordEndCallBack = (_ material: PQEditVisionTrackMaterialsModel) -> Void
|
|
|
+
|
|
|
+class BFRecordAvatarView: UIView {
|
|
|
+
|
|
|
+ //画布
|
|
|
+ var renderView: RenderView!
|
|
|
+ //摄像机
|
|
|
+ var camera:Camera!
|
|
|
+ //是否是录制状态
|
|
|
+ var isRecording = false
|
|
|
+ //视频输出源
|
|
|
+ var movieOutput:MovieOutput? = nil
|
|
|
+ //录制完成回调
|
|
|
+ var recordEndCallBack: recordEndCallBack?
|
|
|
+
|
|
|
+ //打开摄像头
|
|
|
+ lazy var closedBtn:UIButton = {
|
|
|
+ let btn = UIButton(type: .custom)
|
|
|
+ btn.setImage(imageInRecordScreenKit(by: "CameraClosed"), for: .normal)
|
|
|
+ btn.addTarget(self, action: #selector(cameraClosed), for: .touchUpInside)
|
|
|
+ return btn
|
|
|
+ }()
|
|
|
+
|
|
|
+ //预览时纹理大小&合成视频大小
|
|
|
+ var videoPixelsSize:Size = Size(width: 120 * Float(UIScreen.main.scale), height: 120 * Float(UIScreen.main.scale))
|
|
|
+
|
|
|
+ override init(frame: CGRect) {
|
|
|
+ super.init(frame: frame)
|
|
|
+ self.backgroundColor = .yellow
|
|
|
+
|
|
|
+ renderView = RenderView.init(frame: self.bounds)
|
|
|
+ addSubview(renderView)
|
|
|
+
|
|
|
+ self.addSubview(closedBtn)
|
|
|
+ closedBtn.frame = CGRect.init(x: frame.maxX - 68, y: frame.maxY - 68, width: 68, height: 68)
|
|
|
+ do {
|
|
|
+ camera = try Camera(sessionPreset:.vga640x480,location: .frontFacing)
|
|
|
+ let cropFilter = Crop.init()
|
|
|
+ cropFilter.cropSizeInPixels = videoPixelsSize
|
|
|
+ cropFilter.locationOfCropInPixels = Position.init(0, 0)
|
|
|
+ camera --> cropFilter --> renderView
|
|
|
+ } catch {
|
|
|
+ fatalError("Could not initialize rendering pipeline: \(error)")
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ required init?(coder _: NSCoder) {
|
|
|
+ fatalError("init(coder:) has not been implemented")
|
|
|
+ }
|
|
|
+
|
|
|
+ deinit {
|
|
|
+ BFLog(message: "BFRecordAvatarView deinit")
|
|
|
+ closeCamera()
|
|
|
+ }
|
|
|
+
|
|
|
+ @objc func cameraClosed(){
|
|
|
+ self.isHidden = true
|
|
|
+ closeCamera()
|
|
|
+ }
|
|
|
+
|
|
|
+ //打开摄像头
|
|
|
+ func openCamera() {
|
|
|
+ camera.startCapture()
|
|
|
+ }
|
|
|
+ //关闭摄像头
|
|
|
+ func closeCamera() {
|
|
|
+ camera.stopCapture()
|
|
|
+ }
|
|
|
+
|
|
|
+ //开始录制
|
|
|
+ func beginRecord(startTime:CMTime = .zero) {
|
|
|
+
|
|
|
+ if(!camera.captureSession.isRunning){
|
|
|
+ BFLog(message: "摄像机不可用")
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ do {
|
|
|
+ let documentsDir = try FileManager.default.url(for:.documentDirectory, in:.userDomainMask, appropriateFor:nil, create:true)
|
|
|
+ let fileURL = URL(string:"test.mov", relativeTo:documentsDir)!
|
|
|
+ do {
|
|
|
+ try FileManager.default.removeItem(at:fileURL)
|
|
|
+ } catch {
|
|
|
+ }
|
|
|
+ movieOutput = try MovieOutput(URL:fileURL, size:videoPixelsSize, liveVideo:true)
|
|
|
+ camera.audioEncodingTarget = movieOutput
|
|
|
+ movieOutput!.startRecording()
|
|
|
+
|
|
|
+ } catch {
|
|
|
+ fatalError("Couldn't initialize movie, error: \(error)")
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ //结束录制
|
|
|
+ func endRecord() {
|
|
|
+
|
|
|
+ movieOutput?.finishRecording{
|
|
|
+ self.camera.audioEncodingTarget = nil
|
|
|
+ self.movieOutput = nil
|
|
|
+
|
|
|
+// if(recordEndCallBack != nil){
|
|
|
+//
|
|
|
+// let movieAsset = AVURLAsset(url: URL(fileURLWithPath: fileURL), options: avAssertOptions)
|
|
|
+//
|
|
|
+// let movieInfo: PQEditVisionTrackMaterialsModel = PQEditVisionTrackMaterialsModel()
|
|
|
+// movieInfo.type = StickerType.VIDEO.rawValue
|
|
|
+// movieInfo.locationPath = ""
|
|
|
+// movieInfo.timelineIn = 0
|
|
|
+// movieInfo.timelineOut = CMTimeGetSeconds(movieAsset.duration)
|
|
|
+// movieInfo.model_in = movieInfo.timelineIn
|
|
|
+// movieInfo.out = movieInfo.timelineOut
|
|
|
+// movieInfo.canvasFillType = stickerContentMode.aspectFitStr.rawValue
|
|
|
+// recordEndCallBack!(movieInfo)
|
|
|
+// }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+}
|