Quellcode durchsuchen

合成片尾保存相册

jsonwang vor 3 Jahren
Ursprung
Commit
3c27f329ca

+ 129 - 39
BFFramework/Classes/Stuckpoint/Controller/PQStuckPointPublicController.swift

@@ -76,6 +76,12 @@ class PQStuckPointPublicController: PQBaseViewController {
     // 导出片尾
     private var endMovieExporter: PQCompositionExporter!
     private var endMovieLocalURL: URL? // 导出的地址
+    // 保存相册的合成视频地址 水印+片尾
+    private var saveMovieLocalURL: URL?
+    //用户名绘制用到的参数
+    private var userNameTop:Int = 0
+    private var userNameFontSize:Int = 0
+    private var userNameSize: CGRect = .zero
     //----------------------------
 
     // 预览大小
@@ -580,6 +586,16 @@ class PQStuckPointPublicController: PQBaseViewController {
 
         // 取推荐标题
         getTitles()
+        
+        //片尾用户名到顶部的高度
+        userNameTop =  Int(870 * (editProjectModel?.sData?.videoMetaData?.videoHeight ?? 0) / 1920)
+        userNameFontSize = Int(100 * (editProjectModel?.sData?.videoMetaData?.videoWidth ?? 0) / 1080)
+        if((editProjectModel?.sData?.videoMetaData?.videoHeight ?? 0) <= (editProjectModel?.sData?.videoMetaData?.videoWidth ?? 0)){
+            userNameTop = 480
+            userNameFontSize = 70
+        }
+        //片尾用户名绘制大小
+        userNameSize = BFLoginUserInfo.shared.nickName.boundingRect(with: CGSize(width: userNameFontSize * 12, height: 0), options: .usesLineFragmentOrigin, attributes: [NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: CGFloat(100 * (editProjectModel?.sData?.videoMetaData?.videoWidth ?? 0) / 1080)), NSAttributedString.Key.kern: 0 ], context: nil)
     }
 
     override func viewWillAppear(_ animated: Bool) {
@@ -873,7 +889,7 @@ extension PQStuckPointPublicController {
     /// - Returns: <#description#>
     func saveStuckPointVideo() {
         
-        if(watermarkMovieLocalURL == nil){
+        if(saveMovieLocalURL == nil){
             BFLog(message: "保存相册的视频导出地址无效!!!")
             return
         }
@@ -881,7 +897,7 @@ extension PQStuckPointPublicController {
         if authStatus == .authorized {
             let photoLibrary = PHPhotoLibrary.shared()
             photoLibrary.performChanges({ [weak self] in
-                PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: (self?.watermarkMovieLocalURL)!)
+                PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: (self?.saveMovieLocalURL)!)
             }) { [weak self] isFinished, _ in
                 DispatchQueue.main.async { [weak self] in
                     if self?.view != nil {
@@ -1211,8 +1227,9 @@ extension PQStuckPointPublicController {
             cShowHUB(superView: nil, msg: "视频发布失败,请重新合成")
         } else {
             bottomOprationBgView.isHidden = false
-            /// fp2-1-1 - 请求权限
-            authorizationStatus()
+            
+            //开始导出片尾 成功后自动保存到相册
+            beginExportEndMovie()
         }
     }
 
@@ -1590,9 +1607,7 @@ extension PQStuckPointPublicController {
             }
  
             self?.watermarkMovieLocalURL = url
-            
-            //开始导出片尾
-            self?.beginExportEndMovie()
+           
  
         }
     }
@@ -1615,7 +1630,7 @@ extension PQStuckPointPublicController {
         var orgeBitRate = (editProjectModel?.sData?.videoMetaData?.videoWidth ?? 0) * (editProjectModel?.sData?.videoMetaData?.videoHeight ?? 0) * 3
         
         //片尾的视频素材地址
-        let moveResPath = Bundle().BF_mainbundle().path(forResource: "endMovieA", ofType: "mp4")
+        let moveResPath = Bundle().BF_mainbundle().path(forResource:  (editProjectModel?.sData?.videoMetaData?.videoWidth ?? 0) <  (editProjectModel?.sData?.videoMetaData?.videoHeight ?? 0) ? "endMovieB" : "endMovieA", ofType: "mp4")
         if(moveResPath?.count ?? 0 == 0){
             BFLog(message: "片尾的视频素材地址无效!!!")
             return
@@ -1628,41 +1643,116 @@ extension PQStuckPointPublicController {
             orgeBitRate = Int(cbr ?? 0)
         }
         BFLog(message: "导出设置的码率为:\(orgeBitRate)")
-        //视频素材
-        let stickerInfo:PQEditVisionTrackMaterialsModel = PQEditVisionTrackMaterialsModel.init()
-        stickerInfo.type = StickerType.VIDEO.rawValue
-        stickerInfo.locationPath = moveResPath ?? ""
-        stickerInfo.timelineIn = 0
-        stickerInfo.timelineOut = CMTimeGetSeconds(movieAsset.duration)
-        stickerInfo.model_in = stickerInfo.timelineIn
-        stickerInfo.out = stickerInfo.timelineOut
-        stickerInfo.canvasFillType = stickerContentMode.aspectFitStr.rawValue
-
-        let soundResPath = Bundle().BF_mainbundle().path(forResource: "endMovieSound", ofType: "mp3")
- 
-        let soundAsset = AVURLAsset(url:  URL(fileURLWithPath: soundResPath ?? ""), options: nil)
-        endMovieExporter = PQCompositionExporter(asset: soundAsset, videoComposition: nil, audioMix: nil, filters: nil, stickers: [stickerInfo], animationTool: nil, exportURL: outPutMP4URL)
+  
+        //头像保存沙盒地址
+        BFLog(message: "头像的网络地址\(BFLoginUserInfo.shared.avatarUrl)")
+        let avatarFilePath = NSHomeDirectory().appending("/Documents/").appending("user_avatar.jpg")
+        coverImageView.kf.setImage(with: URL(string: BFLoginUserInfo.shared.avatarUrl), placeholder: UIImage().BF_Image(named: "user_avatar_normal"), progressBlock: { _, _ in
+
+        }) { [weak self] result in
+            switch result {
+            case let .failure(failure):
+                BFLog(message: "图片请求失败:\(failure.localizedDescription)")
+            case let .success(imageResult):
+             
+                
+                let image = UIImage.nx_circleImage(imageResult.image)
+                if(image == nil){
+                    BFLog(message: "image date is error!!")
+                    return
+                }
+                UIImage.saveImage(currentImage: image!, outFilePath: avatarFilePath)
+                
+                //1,背景视频素材
+                let bgMovieInfo:PQEditVisionTrackMaterialsModel = PQEditVisionTrackMaterialsModel.init()
+                bgMovieInfo.type = StickerType.VIDEO.rawValue
+                bgMovieInfo.locationPath = moveResPath ?? ""
+                bgMovieInfo.timelineIn = 0
+                bgMovieInfo.timelineOut = CMTimeGetSeconds(movieAsset.duration)
+                bgMovieInfo.model_in = bgMovieInfo.timelineIn
+                bgMovieInfo.out = bgMovieInfo.timelineOut
+                bgMovieInfo.canvasFillType = stickerContentMode.aspectFitStr.rawValue
+                //2,用户头像素材
+                BFLog(message: "头像的沙盒地址:\(avatarFilePath)")
+                let avatarSticker:PQEditVisionTrackMaterialsModel = PQEditVisionTrackMaterialsModel.init()
+                avatarSticker.locationPath = avatarFilePath.replacingOccurrences(of: documensDirectory, with: "")
+                avatarSticker.timelineIn = bgMovieInfo.timelineIn
+                avatarSticker.timelineOut = bgMovieInfo.timelineOut
+            
+                //头像绘制大小
+                var avatarSize = Int(360 * (self?.editProjectModel?.sData?.videoMetaData?.videoWidth ?? 0) / 1080)
+                //头像到顶部的高度
+                var avatarTop =   Int(430 * (self?.editProjectModel?.sData?.videoMetaData?.videoHeight ?? 0) / 1920)
+                if((self?.editProjectModel?.sData?.videoMetaData?.videoHeight ?? 0) <= (self?.editProjectModel?.sData?.videoMetaData?.videoWidth ?? 0)){//横屏
+                    avatarSize = 300
+                    avatarTop =  130
+                }
+                let avatarPostion:PQEditMaterialPositionModel = PQEditMaterialPositionModel.init()
+                avatarPostion.width = avatarSize
+                avatarPostion.height = avatarSize
+                avatarPostion.x = ((self?.editProjectModel?.sData?.videoMetaData?.videoWidth ?? 0) - avatarSize) / 2
+                avatarPostion.y = avatarTop
+                avatarSticker.materialPosition = avatarPostion
+                
+                //3,用户名素材
+                let userNameSticker:PQEditVisionTrackMaterialsModel = PQEditVisionTrackMaterialsModel.init()
+                userNameSticker.timelineIn = bgMovieInfo.timelineIn
+                userNameSticker.timelineOut = bgMovieInfo.timelineOut
+                userNameSticker.type = StickerType.SUBTITLE.rawValue
+                let subtitleInfo:PQEditSubtitleInfoModel = PQEditSubtitleInfoModel.init()
+                subtitleInfo.fontSize = self?.userNameFontSize ?? 0
+                subtitleInfo.text = BFLoginUserInfo.shared.nickName
+                userNameSticker.subtitleInfo = subtitleInfo
+                
+             
+                let userNamePostion:PQEditMaterialPositionModel = PQEditMaterialPositionModel.init()
+                userNamePostion.width = Int(self?.userNameSize.width ?? 0)
+                userNamePostion.height = Int(self?.userNameSize.height ?? 0)
+                userNamePostion.x = ((self?.editProjectModel?.sData?.videoMetaData?.videoWidth ?? 0) - Int(self?.userNameSize.width ?? 0)) / 2
+                userNamePostion.y = self?.userNameTop ?? 0
+                userNameSticker.materialPosition = userNamePostion
+
+                //4,音频
+                let soundResPath = Bundle().BF_mainbundle().path(forResource: "endMovieSound", ofType: "mp3")
+                let soundAsset = AVURLAsset(url:  URL(fileURLWithPath: soundResPath ?? ""), options: nil)
+                self?.endMovieExporter = PQCompositionExporter(asset: soundAsset, videoComposition: nil, audioMix: nil, filters: nil, stickers: [bgMovieInfo,avatarSticker,userNameSticker], animationTool: nil, exportURL: outPutMP4URL)
+                self?.endMovieExporter.isEndMovie = true
+                if self?.endMovieExporter.prepare(videoSize: CGSize(width: self?.editProjectModel?.sData?.videoMetaData?.videoWidth ?? 0, height: self?.editProjectModel?.sData?.videoMetaData?.videoHeight ?? 0), videoAverageBitRate: orgeBitRate) ?? false {
+           
+                    self?.endMovieExporter.start(playeTimeRange: CMTimeRange.init(start: CMTime.zero, duration: CMTimeMakeWithSeconds(Float64(bgMovieInfo.out), preferredTimescale: BASE_FILTER_TIMESCALE)))
+                    BFLog(message: "开始导出")
+                }
+                self?.endMovieExporter.progressClosure = { [weak self] _, _, progress in
+                    BFLog(message: "片尾合成进度 \(progress) ")
+                  
+                }
+                self?.endMovieExporter.completion = { [weak self] url in
+                    BFLog(message: "片尾的视频导出完成: \(url) 生成视频时长为:\(CMTimeGetSeconds(AVAsset(url: url).duration))")
 
-        endMovieExporter.showGaussianBlur = true
-        if endMovieExporter.prepare(videoSize: CGSize(width: editProjectModel?.sData?.videoMetaData?.videoWidth ?? 0, height: editProjectModel?.sData?.videoMetaData?.videoHeight ?? 0), videoAverageBitRate: orgeBitRate) {
-   
-            endMovieExporter.start(playeTimeRange: CMTimeRange.init(start: CMTime.zero, duration: CMTimeMakeWithSeconds(Float64(stickerInfo.out), preferredTimescale: BASE_FILTER_TIMESCALE)))
-            BFLog(message: "开始导出")
-        }
-        endMovieExporter.progressClosure = { [weak self] _, _, progress in
-            BFLog(message: "片尾合成进度 \(progress) ")
-          
-        }
-        endMovieExporter.completion = { [weak self] url in
-            BFLog(message: "片尾的视频导出完成: \(url) 生成视频时长为:\(CMTimeGetSeconds(AVAsset(url: url).duration))")
+                    // 导出完成后取消导出
+                    if self?.endMovieExporter != nil {
+                        self?.endMovieExporter.cancel()
+                    }
+                    self?.endMovieLocalURL = url
+                    //拼接水印正片和片尾
+                    if(self?.watermarkMovieLocalURL != nil && self?.endMovieLocalURL != nil){
+                        let videoMerge:NXVideoMerge = NXVideoMerge.init()
+                        videoMerge.mergeAndExportVideos(withFileURLs: [self!.watermarkMovieLocalURL!,self!.endMovieLocalURL!], renderSize:CGSize(width: self?.editProjectModel?.sData?.videoMetaData?.videoWidth ?? 0, height: self?.editProjectModel?.sData?.videoMetaData?.videoHeight ?? 0)) { isSuccess, outFileURL in
+                            if(isSuccess){
+                                BFLog(message: "合并视频成功 outFilePath is \(outFileURL ?? "")")
+                                self?.saveMovieLocalURL = outFileURL as? URL
+                                //保存到相册 fp2-1-1 - 请求权限
+                                self?.authorizationStatus()
+                            }
+                        }
+                    }
+              
+ 
+                }
 
-            // 导出完成后取消导出
-            if self?.endMovieExporter != nil {
-                self?.endMovieExporter.cancel()
             }
-            self?.endMovieLocalURL = url
- 
         }
+       
     }