|
@@ -10,6 +10,7 @@ import ObjectMapper
|
|
|
import Photos
|
|
|
import UIKit
|
|
|
import WechatOpenSDK
|
|
|
+import Kingfisher
|
|
|
class PQStuckPointPublicController: PQBaseViewController {
|
|
|
private var isShared: Bool = false // 是否在分享
|
|
|
private var isExportSuccess: Bool = false // 是否导出完成
|
|
@@ -1654,118 +1655,117 @@ extension PQStuckPointPublicController {
|
|
|
//头像保存沙盒地址
|
|
|
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
|
|
|
+
|
|
|
+ ImageDownloader.default.downloadImage(with: URL(string: BFLoginUserInfo.shared.avatarUrl)!, options: nil) { 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
|
|
|
+ case let .success(imageResult): break
|
|
|
|
|
|
- //用户名绘制用到的参数
|
|
|
- var userNameTop = Int(870 * (self?.editProjectModel?.sData?.videoMetaData?.videoHeight ?? 0) / 1920)
|
|
|
- var userNameFontSize = Int(100 * (self?.editProjectModel?.sData?.videoMetaData?.videoWidth ?? 0) / 1080)
|
|
|
- if((self?.editProjectModel?.sData?.videoMetaData?.videoHeight ?? 0) <= (self?.editProjectModel?.sData?.videoMetaData?.videoWidth ?? 0)){
|
|
|
- userNameTop = 480
|
|
|
- userNameFontSize = 70
|
|
|
- }
|
|
|
- let subtitleInfo:PQEditSubtitleInfoModel = PQEditSubtitleInfoModel.init()
|
|
|
- subtitleInfo.fontSize = userNameFontSize
|
|
|
- subtitleInfo.text = BFLoginUserInfo.shared.nickName
|
|
|
- userNameSticker.subtitleInfo = subtitleInfo
|
|
|
-
|
|
|
- let userNamePostion:PQEditMaterialPositionModel = PQEditMaterialPositionModel.init()
|
|
|
- userNamePostion.width = Int(userNameFontSize ) * 10
|
|
|
- userNamePostion.height = Int(userNameFontSize ) * 3
|
|
|
- userNamePostion.x = ((self?.editProjectModel?.sData?.videoMetaData?.videoWidth ?? 0) - userNamePostion.width) / 2
|
|
|
- userNamePostion.y = userNameTop
|
|
|
- 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))")
|
|
|
-
|
|
|
- // 导出完成后取消导出
|
|
|
- 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()
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
+
|
|
|
+ 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
|
|
|
+
|
|
|
+ //用户名绘制用到的参数
|
|
|
+ var userNameTop = Int(870 * (self.editProjectModel?.sData?.videoMetaData?.videoHeight ?? 0) / 1920)
|
|
|
+ var userNameFontSize = Int(100 * (self.editProjectModel?.sData?.videoMetaData?.videoWidth ?? 0) / 1080)
|
|
|
+ if((self.editProjectModel?.sData?.videoMetaData?.videoHeight ?? 0) <= (self.editProjectModel?.sData?.videoMetaData?.videoWidth ?? 0)){
|
|
|
+ userNameTop = 480
|
|
|
+ userNameFontSize = 70
|
|
|
+ }
|
|
|
+ let subtitleInfo:PQEditSubtitleInfoModel = PQEditSubtitleInfoModel.init()
|
|
|
+ subtitleInfo.fontSize = userNameFontSize
|
|
|
+ subtitleInfo.text = BFLoginUserInfo.shared.nickName
|
|
|
+ userNameSticker.subtitleInfo = subtitleInfo
|
|
|
+
|
|
|
+ let userNamePostion:PQEditMaterialPositionModel = PQEditMaterialPositionModel.init()
|
|
|
+ userNamePostion.width = Int(userNameFontSize ) * 10
|
|
|
+ userNamePostion.height = Int(userNameFontSize ) * 3
|
|
|
+ userNamePostion.x = ((self.editProjectModel?.sData?.videoMetaData?.videoWidth ?? 0) - userNamePostion.width) / 2
|
|
|
+ userNamePostion.y = userNameTop
|
|
|
+ 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))")
|
|
|
+
|
|
|
+ // 导出完成后取消导出
|
|
|
+ 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()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+ case let .failure(error):
|
|
|
+ BFLog(message: "下载头像图片失败:\(error.localizedDescription)")
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
|
|
|
}
|
|
|
|