|
@@ -6,17 +6,17 @@
|
|
|
// Copyright © 2021 BytesFlow. All rights reserved.
|
|
|
//
|
|
|
|
|
|
+import Alamofire
|
|
|
+import BFCommonKit
|
|
|
+import BFUIKit
|
|
|
+import Kingfisher
|
|
|
+import ObjectMapper
|
|
|
import Photos
|
|
|
import UIKit
|
|
|
-import ObjectMapper
|
|
|
import WechatOpenSDK
|
|
|
-import Kingfisher
|
|
|
-import Alamofire
|
|
|
-import BFUIKit
|
|
|
-import BFCommonKit
|
|
|
|
|
|
-//mdf by ak 按 UI图 下方操作区的高度是固定的, 其它区高度和设备自适应
|
|
|
-public let bottomOprationBgViewHeight:CGFloat = 322.0
|
|
|
+// mdf by ak 按 UI图 下方操作区的高度是固定的, 其它区高度和设备自适应
|
|
|
+public let bottomOprationBgViewHeight: CGFloat = 322.0
|
|
|
class PQStuckPointPublicController: BFBaseViewController {
|
|
|
private var isShared: Bool = false // 是否在分享
|
|
|
private var isExportSuccess: Bool = false // 是否导出完成
|
|
@@ -77,8 +77,8 @@ class PQStuckPointPublicController: BFBaseViewController {
|
|
|
var clipAudioRange: CMTimeRange = CMTimeRange.zero
|
|
|
// 导出的开始的开始和结束时间
|
|
|
var playeTimeRange: CMTimeRange = CMTimeRange()
|
|
|
-
|
|
|
- //---------------------------add by ak 保存系统相册使用的变量
|
|
|
+
|
|
|
+ // ---------------------------add by ak 保存系统相册使用的变量
|
|
|
// 导出有水印的正片
|
|
|
private var watermarkMovieExporter: PQCompositionExporter!
|
|
|
// 带水印 MP4 导出地址
|
|
@@ -89,10 +89,10 @@ class PQStuckPointPublicController: BFBaseViewController {
|
|
|
private var endMovieLocalURL: URL?
|
|
|
// 保存相册的合成视频地址 水印+片尾 MP4 地址
|
|
|
private var saveMovieLocalURL: URL?
|
|
|
-
|
|
|
+
|
|
|
private var isSaveingLocalVideo = false
|
|
|
-
|
|
|
- //----------------------------
|
|
|
+
|
|
|
+ // ----------------------------
|
|
|
|
|
|
// 预览大小
|
|
|
private var preViewSize: CGSize {
|
|
@@ -194,7 +194,7 @@ class PQStuckPointPublicController: BFBaseViewController {
|
|
|
playerHeaderCoverImageView.clipsToBounds = true
|
|
|
|
|
|
let playBtn = UIButton(type: .custom)
|
|
|
- playBtn.setImage(UIImage.moduleImage(named: "icon_video_play", moduleName: "BFFramework",isAssets: false), for: .normal)
|
|
|
+ playBtn.setImage(UIImage.moduleImage(named: "icon_video_play", moduleName: "BFFramework", isAssets: false), for: .normal)
|
|
|
playBtn.tag = 4
|
|
|
playBtn.isUserInteractionEnabled = false
|
|
|
playerHeaderCoverImageView.addSubview(playBtn)
|
|
@@ -242,7 +242,7 @@ class PQStuckPointPublicController: BFBaseViewController {
|
|
|
lazy var playBtn: UIButton = {
|
|
|
let playBtn = UIButton(type: .custom)
|
|
|
playBtn.frame = CGRect(x: (preViewSize.width - cDefaultMargin * 5) / 2, y: (preViewSize.height - cDefaultMargin * 5) / 2, width: cDefaultMargin * 5, height: cDefaultMargin * 5)
|
|
|
- playBtn.setImage(UIImage.moduleImage(named: "icon_video_play", moduleName: "BFFramework",isAssets: false), for: .normal)
|
|
|
+ playBtn.setImage(UIImage.moduleImage(named: "icon_video_play", moduleName: "BFFramework", isAssets: false), for: .normal)
|
|
|
playBtn.tag = 4
|
|
|
playBtn.isHidden = true
|
|
|
playBtn.isUserInteractionEnabled = false
|
|
@@ -297,7 +297,7 @@ class PQStuckPointPublicController: BFBaseViewController {
|
|
|
// 手势提示
|
|
|
lazy var pinView: UIImageView = {
|
|
|
let pinView = UIImageView()
|
|
|
- pinView.kf.setImage(with: URL(fileURLWithPath: (currentBundlePath()!.path(forResource: "editCoverPin", ofType: ".gif")!)))
|
|
|
+ pinView.kf.setImage(with: URL(fileURLWithPath: currentBundlePath()!.path(forResource: "editCoverPin", ofType: ".gif")!))
|
|
|
return pinView
|
|
|
}()
|
|
|
|
|
@@ -343,7 +343,7 @@ class PQStuckPointPublicController: BFBaseViewController {
|
|
|
publicTitleView.isHidden = true
|
|
|
publicTitleView.confirmBtnClock = { [weak self] title in
|
|
|
BFLog(message: "传出的 title is :\(String(describing: title))")
|
|
|
- if title?.count != 0 && title != self?.titleLabel.text {
|
|
|
+ if title?.count != 0, title != self?.titleLabel.text {
|
|
|
self?.changPlayerIsPause(isPause: false)
|
|
|
|
|
|
// 判断文字是否有效
|
|
@@ -378,7 +378,7 @@ class PQStuckPointPublicController: BFBaseViewController {
|
|
|
lazy var shareWechatBtn: UIButton = {
|
|
|
let shareWechatBtn = UIButton(type: .custom)
|
|
|
shareWechatBtn.frame = CGRect(x: 0, y: 0, width: 70, height: 70)
|
|
|
- shareWechatBtn.setImage(UIImage.moduleImage(named: "reCreate_opration_wechat", moduleName: "BFFramework",isAssets: false), for: .normal)
|
|
|
+ shareWechatBtn.setImage(UIImage.moduleImage(named: "reCreate_opration_wechat", moduleName: "BFFramework", isAssets: false), for: .normal)
|
|
|
shareWechatBtn.backgroundColor = BFConfig.shared.styleBackGroundColor
|
|
|
shareWechatBtn.addCorner(corner: 6)
|
|
|
shareWechatBtn.tag = 2
|
|
@@ -390,7 +390,7 @@ class PQStuckPointPublicController: BFBaseViewController {
|
|
|
lazy var shareFriendBtn: UIButton = {
|
|
|
let shareFriendBtn = UIButton(type: .custom)
|
|
|
shareFriendBtn.frame = CGRect(x: 0, y: 0, width: 70, height: 70)
|
|
|
- shareFriendBtn.setImage(UIImage.moduleImage(named: BFConfig.shared.shareFriendBtnImage, moduleName: "BFFramework",isAssets: false), for: .normal)
|
|
|
+ shareFriendBtn.setImage(UIImage.moduleImage(named: BFConfig.shared.shareFriendBtnImage, moduleName: "BFFramework", isAssets: false), for: .normal)
|
|
|
shareFriendBtn.addCorner(corner: 6)
|
|
|
shareFriendBtn.tag = 1
|
|
|
shareFriendBtn.addTarget(self, action: #selector(btnClick(sender:)), for: .touchUpInside)
|
|
@@ -425,15 +425,16 @@ class PQStuckPointPublicController: BFBaseViewController {
|
|
|
bottomOprationBgView.isHidden = true
|
|
|
return bottomOprationBgView
|
|
|
}()
|
|
|
-
|
|
|
- ///保存视频到相册提示
|
|
|
+
|
|
|
+ /// 保存视频到相册提示
|
|
|
lazy var saveVideoTipsBgView: UIView = {
|
|
|
let saveVideoTipsBgView = UIView(frame: CGRect(x: 0, y: cDevice_iPhoneNavBarAndStatusBarHei, width: cScreenWidth, height: 40))
|
|
|
- saveVideoTipsBgView.backgroundColor = UIColor.init(red: 0, green: 0, blue: 0, alpha: 0.4)
|
|
|
+ saveVideoTipsBgView.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.4)
|
|
|
saveVideoTipsBgView.isHidden = true
|
|
|
saveVideoTipsBgView.alpha = 1
|
|
|
return saveVideoTipsBgView
|
|
|
}()
|
|
|
+
|
|
|
lazy var saveVideoTipsLabel: UILabel = {
|
|
|
let saveVideoTipsLabel = UILabel(frame: CGRect(x: 0, y: 0, width: cScreenWidth, height: 40))
|
|
|
saveVideoTipsLabel.textColor = .white
|
|
@@ -443,7 +444,7 @@ class PQStuckPointPublicController: BFBaseViewController {
|
|
|
saveVideoTipsLabel.sizeToFit()
|
|
|
return saveVideoTipsLabel
|
|
|
}()
|
|
|
-
|
|
|
+
|
|
|
// 保存重试
|
|
|
lazy var saveRetryBtn: UIButton = {
|
|
|
let saveRetryBtn = UIButton(type: .custom)
|
|
@@ -529,8 +530,7 @@ class PQStuckPointPublicController: BFBaseViewController {
|
|
|
|
|
|
view.addSubview(publicTitleView)
|
|
|
view.addSubview(publicEditCoverView)
|
|
|
-
|
|
|
-
|
|
|
+
|
|
|
view.addSubview(saveVideoTipsBgView)
|
|
|
saveVideoTipsBgView.addSubview(saveVideoTipsLabel)
|
|
|
saveVideoTipsBgView.addSubview(saveRetryBtn)
|
|
@@ -545,7 +545,6 @@ class PQStuckPointPublicController: BFBaseViewController {
|
|
|
make.width.equalTo(50)
|
|
|
}
|
|
|
|
|
|
-
|
|
|
coverImageTitle.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(settingCoverImage)))
|
|
|
coverImageView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(settingCoverImage)))
|
|
|
|
|
@@ -644,20 +643,19 @@ class PQStuckPointPublicController: BFBaseViewController {
|
|
|
|
|
|
// 取推荐标题
|
|
|
getTitles()
|
|
|
-
|
|
|
+
|
|
|
networkStausListen()
|
|
|
-
|
|
|
}
|
|
|
|
|
|
override func viewWillAppear(_ animated: Bool) {
|
|
|
super.viewWillAppear(animated)
|
|
|
PQNotification.addObserver(self, selector: #selector(enterBackground), name: UIApplication.didEnterBackgroundNotification, object: nil)
|
|
|
PQNotification.addObserver(self, selector: #selector(willEnterForeground), name: UIApplication.willEnterForegroundNotification, object: nil)
|
|
|
-
|
|
|
+
|
|
|
DispatchQueue.main.async {
|
|
|
UIApplication.shared.isIdleTimerDisabled = true
|
|
|
}
|
|
|
- //从相册选择一个照片后回调
|
|
|
+ // 从相册选择一个照片后回调
|
|
|
addNotification(self, selector: #selector(imageSelectedImage(notify:)), name: cSelectedImageSuccessKey, object: nil)
|
|
|
|
|
|
#if swift(>=4.2)
|
|
@@ -694,21 +692,22 @@ class PQStuckPointPublicController: BFBaseViewController {
|
|
|
if exporter != nil {
|
|
|
exporter.cancel()
|
|
|
}
|
|
|
- if watermarkMovieExporter != nil{
|
|
|
+ if watermarkMovieExporter != nil {
|
|
|
watermarkMovieExporter.cancel()
|
|
|
}
|
|
|
- if endMovieExporter != nil{
|
|
|
+ if endMovieExporter != nil {
|
|
|
endMovieExporter.cancel()
|
|
|
}
|
|
|
-
|
|
|
-
|
|
|
+
|
|
|
avPlayer.pause()
|
|
|
avPlayer.replaceCurrentItem(with: nil)
|
|
|
// 点击上报:返回按钮
|
|
|
PQEventTrackViewModel.baseReportUpload(businessType: .bt_buttonClick, objectType: .ot_click_back, pageSource: .sp_stuck_publishSyncedUp, extParams: nil, remindmsg: "卡点视频数据上报-(点击上报:返回按钮)")
|
|
|
}
|
|
|
+
|
|
|
// MARK: - 网络监控
|
|
|
- func networkStausListen(){
|
|
|
+
|
|
|
+ func networkStausListen() {
|
|
|
manager?.startListening(onUpdatePerforming: { status in
|
|
|
if status == .reachable(.cellular) || status == .reachable(.ethernetOrWiFi) {
|
|
|
cHiddenHUB(superView: nil)
|
|
@@ -719,7 +718,6 @@ class PQStuckPointPublicController: BFBaseViewController {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-
|
|
|
// MARK: - 导出/上传/下载及其他方法
|
|
|
|
|
|
/// 导出/上传/下载及其他方法
|
|
@@ -736,8 +734,8 @@ extension PQStuckPointPublicController {
|
|
|
|
|
|
let originaDuration = CMTimeGetSeconds(clipAudioRange.duration)
|
|
|
BFLog(message: "处理主音频 原始时长startTime = \(originaDuration) 要显示时长totalDuration = \(mTotalDuration)")
|
|
|
- //originaDuration = 37.616768 mTotalDuration = 37.616776 TODO 都用 INT 微秒级
|
|
|
- if Float64(String(format: "%.3f",mTotalDuration)) ?? 0.0 <= Float64(String(format: "%.3f",originaDuration)) ?? 0.0 {
|
|
|
+ // originaDuration = 37.616768 mTotalDuration = 37.616776 TODO 都用 INT 微秒级
|
|
|
+ if Float64(String(format: "%.3f", mTotalDuration)) ?? 0.0 <= Float64(String(format: "%.3f", originaDuration)) ?? 0.0 {
|
|
|
BFLog(message: "不用拼接音频文件 \(originAsset.url) 时长is \(CMTimeGetSeconds(originAsset.duration))")
|
|
|
completeHander(originAsset.url)
|
|
|
return
|
|
@@ -757,7 +755,7 @@ extension PQStuckPointPublicController {
|
|
|
if count > 0 {
|
|
|
for index in 0 ..< count {
|
|
|
// 第0段从0开始到推荐的结束,播放器的开始时间不是从0开始的
|
|
|
- duration = CMTime(value: CMTimeValue((CMTimeGetSeconds(clipAudioRange.end)) * Double(playerTimescaleInt)), timescale: playerTimescaleInt)
|
|
|
+ duration = CMTime(value: CMTimeValue(CMTimeGetSeconds(clipAudioRange.end) * Double(playerTimescaleInt)), timescale: playerTimescaleInt)
|
|
|
BFLog(message: "每一个文件的 duration \(CMTimeGetSeconds(duration))")
|
|
|
var timeRange = CMTimeRangeMake(start: .zero, duration: duration)
|
|
|
|
|
@@ -849,7 +847,7 @@ extension PQStuckPointPublicController {
|
|
|
}
|
|
|
|
|
|
func appendAudio() {
|
|
|
- //更新一下假进度
|
|
|
+ // 更新一下假进度
|
|
|
updatePublicCurrentProgress(useProgress: 0.01)
|
|
|
let inputAsset = AVURLAsset(url: URL(fileURLWithPath: documensDirectory + (audioMixModel?.localPath ?? "")), options: nil)
|
|
|
let startMergeTime = CFAbsoluteTimeGetCurrent()
|
|
@@ -858,17 +856,16 @@ extension PQStuckPointPublicController {
|
|
|
if completURL != nil {
|
|
|
let asset = AVURLAsset(url: completURL!, options: nil)
|
|
|
BFLog(message: "拼接后音频时长\(asset.duration.seconds) url is \(String(describing: completURL)) 用时\(CFAbsoluteTimeGetCurrent() - startMergeTime)")
|
|
|
- //导出不带水印的正片
|
|
|
+ // 导出不带水印的正片
|
|
|
self?.beginExport(inputAsset: asset)
|
|
|
-
|
|
|
- if(BFConfig.shared.enableWatermarkMovie){
|
|
|
- //导出带水印的正片
|
|
|
- self?.beginExportWatermarkMovie(inputAsset:asset)
|
|
|
+
|
|
|
+ if BFConfig.shared.enableWatermarkMovie {
|
|
|
+ // 导出带水印的正片
|
|
|
+ self?.beginExportWatermarkMovie(inputAsset: asset)
|
|
|
}
|
|
|
- }else{
|
|
|
+ } else {
|
|
|
cShowHUB(superView: self?.view, msg: "合成失败请重试。")
|
|
|
}
|
|
|
-
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -904,7 +901,7 @@ extension PQStuckPointPublicController {
|
|
|
}
|
|
|
}
|
|
|
BFLog(message: "导出设置的码率为:\(orgeBitRate)")
|
|
|
- let tempBeginExport = Date().timeIntervalSince1970
|
|
|
+ let tempBeginExport = Date().timeIntervalSince1970
|
|
|
exporter.showGaussianBlur = true
|
|
|
if exporter.prepare(videoSize: CGSize(width: editProjectModel?.sData?.videoMetaData?.videoWidth ?? 0, height: editProjectModel?.sData?.videoMetaData?.videoHeight ?? 0), videoAverageBitRate: orgeBitRate) {
|
|
|
BFLog(message: "开始导出 \(String(describing: playeTimeRange.start)) 结束 \(String(describing: playeTimeRange.end))")
|
|
@@ -912,7 +909,7 @@ extension PQStuckPointPublicController {
|
|
|
BFLog(message: "开始导出")
|
|
|
}
|
|
|
exporter.progressClosure = { [weak self] _, _, progress in
|
|
|
- BFLog(message: "正片合成进度 \(progress*100)%")
|
|
|
+ BFLog(message: "正片合成进度 \(progress * 100)%")
|
|
|
let useProgress = progress > 1 ? 1 : progress
|
|
|
if progress > 0, Int(useProgress * 100) > (self?.exportProgrss ?? 0) {
|
|
|
// 更新进度
|
|
@@ -920,12 +917,12 @@ extension PQStuckPointPublicController {
|
|
|
}
|
|
|
}
|
|
|
exporter.completion = { [weak self] url in
|
|
|
-
|
|
|
- //输出视频时长
|
|
|
- let outSeconds = CMTimeGetSeconds(AVAsset(url: (url ?? URL(string: "https://media.w3.org/2010/05/sintel/trailer.mp4")!)).duration)
|
|
|
-
|
|
|
+
|
|
|
+ // 输出视频时长
|
|
|
+ let outSeconds = CMTimeGetSeconds(AVAsset(url: url ?? URL(string: "https://media.w3.org/2010/05/sintel/trailer.mp4")!).duration)
|
|
|
+
|
|
|
BFLog(message: "无水印的视频导出完成: \(String(describing: url)) 生成视频时长为:\(outSeconds)")
|
|
|
- if(outSeconds == 0){
|
|
|
+ if outSeconds == 0 {
|
|
|
cShowHUB(superView: self?.view, msg: "合成失败请重试。")
|
|
|
return
|
|
|
}
|
|
@@ -939,15 +936,14 @@ extension PQStuckPointPublicController {
|
|
|
self?.isExportSuccess = true
|
|
|
self?.exportEndDate = Date().timeIntervalSince1970
|
|
|
BFLog(message: "视频导出完成-开始去发布视频 总时长为\((self?.exportEndDate ?? 0) - (self?.startExportDate ?? 0) * 1000) 总用时\((self?.exportEndDate ?? 0) - tempBeginExport)")
|
|
|
-
|
|
|
+
|
|
|
self?.exportLocalURL = url
|
|
|
-
|
|
|
-
|
|
|
+
|
|
|
// add by ak 不生成水印视频时直接自动保存系统相册,e.g. 乐活圈中会执行
|
|
|
- if(!BFConfig.shared.enableWatermarkMovie){
|
|
|
+ if !BFConfig.shared.enableWatermarkMovie {
|
|
|
self?.authorizationStatus()
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
/// fp2-1-1 - 请求权限
|
|
|
// self?.authorizationStatus()
|
|
|
/// fp2-2 - 保存草稿
|
|
@@ -983,10 +979,9 @@ extension PQStuckPointPublicController {
|
|
|
/// - Parameter localPath: localPath description
|
|
|
/// - Returns: <#description#>
|
|
|
func saveStuckPointVideo() {
|
|
|
-
|
|
|
- let tempSaveMoveiLocal:URL? = BFConfig.shared.enableWatermarkMovie ? saveMovieLocalURL : exportLocalURL
|
|
|
-
|
|
|
- if(tempSaveMoveiLocal == nil){
|
|
|
+ let tempSaveMoveiLocal: URL? = BFConfig.shared.enableWatermarkMovie ? saveMovieLocalURL : exportLocalURL
|
|
|
+
|
|
|
+ if tempSaveMoveiLocal == nil {
|
|
|
BFLog(message: "保存相册的视频导出地址无效!!!")
|
|
|
cShowHUB(superView: nil, msg: "保存相册的视频导出地址无效")
|
|
|
saveVideoTipsLabel.text = "视频保存失败"
|
|
@@ -1013,15 +1008,13 @@ extension PQStuckPointPublicController {
|
|
|
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.8) { [weak self] in
|
|
|
self?.saveVideoTipsBgView.isHidden = true
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
} else {
|
|
|
self?.saveVideoTipsLabel.text = "视频保存失败"
|
|
|
self?.saveRetryBtn.isHidden = false
|
|
|
// DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.8) { [weak self] in
|
|
|
// self?.saveVideoTipsBgView.isHidden = true
|
|
|
// }
|
|
|
-
|
|
|
-
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -1130,7 +1123,7 @@ extension PQStuckPointPublicController {
|
|
|
if isExportSuccess, exportLocalURL != nil {
|
|
|
let size = try! exportLocalURL?.resourceValues(forKeys: [.fileSizeKey])
|
|
|
BFLog(message: "size = \(String(describing: size))")
|
|
|
- if (size?.fileSize ?? 0) > 0 && Float64(size?.fileSize ?? 0) <= maxUploadSize {
|
|
|
+ if (size?.fileSize ?? 0) > 0, Float64(size?.fileSize ?? 0) <= maxUploadSize {
|
|
|
/// fp5 - 上传视频
|
|
|
reUploadVideo()
|
|
|
}
|
|
@@ -1194,10 +1187,10 @@ extension PQStuckPointPublicController {
|
|
|
if code == 6 { // 无网
|
|
|
let uploadRequest: OSSMultipartUploadRequest? = PQAliOssUtil.shared.allTasks[self?.uploadData?.videoBucketKey ?? ""]
|
|
|
if !(uploadRequest != nil && "\(uploadRequest?.callbackParam["code"] ?? "0")" == "1") {
|
|
|
- self?.showUploadRemindView(msg:"aliOss")
|
|
|
+ self?.showUploadRemindView(msg: "aliOss")
|
|
|
}
|
|
|
} else if code == 260 {
|
|
|
- self?.showUploadRemindView(isNetCollected: false, msg:"aliOss")
|
|
|
+ self?.showUploadRemindView(isNetCollected: false, msg: "aliOss")
|
|
|
} else if code != 1 {
|
|
|
// 上传失败-播放视频
|
|
|
self?.publicEnd(isError: true)
|
|
@@ -1235,7 +1228,7 @@ extension PQStuckPointPublicController {
|
|
|
let size = try! URL(string: uploadData?.localPath ?? "")?.resourceValues(forKeys: [.fileSizeKey])
|
|
|
BFLog(message: "size = \(String(describing: size))")
|
|
|
if Float64(size?.fileSize ?? 0) > maxUploadSize {
|
|
|
- cShowHUB(superView: nil, msg:"无法发布大于10G的视频,请重新选择/合成发布")
|
|
|
+ cShowHUB(superView: nil, msg: "无法发布大于10G的视频,请重新选择/合成发布")
|
|
|
// 上传失败-播放视频
|
|
|
publicEnd(isError: true)
|
|
|
return
|
|
@@ -1311,6 +1304,9 @@ extension PQStuckPointPublicController {
|
|
|
reCreateVideo.reProduceVideoFlag = 1
|
|
|
self?.videoData?.reCreateVideoData = reCreateVideo
|
|
|
}
|
|
|
+ if self?.videoData != nil {
|
|
|
+ postNotification(name: cUpdateVideoSuccessKey, userInfo: ["videoData": (self?.videoData)!])
|
|
|
+ }
|
|
|
postNotification(name: cPublishStuckPointSuccessKey, userInfo: ["newVideoData": self?.videoData ?? PQVideoListModel()])
|
|
|
BFLog(message: "发布成功==\(videoData.title ?? ""),uplpadBucketKey = \(videoData.uplpadBucketKey ?? "")")
|
|
|
// cShowHUB(superView: nil, msg: "视频发布成功")
|
|
@@ -1344,21 +1340,20 @@ extension PQStuckPointPublicController {
|
|
|
cShowHUB(superView: nil, msg: "视频发布失败,请重新合成")
|
|
|
} else {
|
|
|
bottomOprationBgView.isHidden = false
|
|
|
- //add by ak 发布成功后如果带片尾的视频还没有生成成功时,出提示
|
|
|
- self.saveRetryBtn.isHidden = true
|
|
|
- self.saveVideoTipsBgView.isHidden = false
|
|
|
- if(self.isSaveingLocalVideo){
|
|
|
+ // add by ak 发布成功后如果带片尾的视频还没有生成成功时,出提示
|
|
|
+ saveRetryBtn.isHidden = true
|
|
|
+ saveVideoTipsBgView.isHidden = false
|
|
|
+ if isSaveingLocalVideo {
|
|
|
saveVideoTipsLabel.text = "视频保存中..."
|
|
|
- }else{
|
|
|
- self.saveVideoTipsLabel.text = "视频已保存到相册"
|
|
|
+ } else {
|
|
|
+ saveVideoTipsLabel.text = "视频已保存到相册"
|
|
|
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.8) { [weak self] in
|
|
|
self?.saveVideoTipsBgView.isHidden = true
|
|
|
}
|
|
|
}
|
|
|
- if self.isSaveingLocalVideo{
|
|
|
+ if isSaveingLocalVideo {
|
|
|
saveVideoTipsBgView.isHidden = false
|
|
|
}
|
|
|
-
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -1467,7 +1462,13 @@ extension PQStuckPointPublicController {
|
|
|
|
|
|
// 点击上报:完成
|
|
|
PQEventTrackViewModel.baseReportUpload(businessType: .bt_buttonClick, objectType: .ot_click_finished, pageSource: .sp_stuck_publishSyncedUp, extParams: ["videoId": videoData?.uniqueId ?? ""], remindmsg: "卡点视频数据上报-(点击上报:完成)")
|
|
|
- navigationController?.viewControllers = [(navigationController?.viewControllers.first)!]
|
|
|
+ bf_getCurrentViewController()?.dismiss(animated: false) {
|
|
|
+ bf_getCurrentViewController()?.navigationController?.viewControllers = [bf_getCurrentViewController()?.navigationController?.viewControllers.first ?? BFBaseViewController()]
|
|
|
+ (bf_getRootViewController() as? UITabBarController)?.selectedIndex = 4
|
|
|
+ DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.5) {
|
|
|
+ postNotification(name: cPublishSuccessKey)
|
|
|
+ }
|
|
|
+ }
|
|
|
// 发送通知
|
|
|
postNotification(name: cFinishedPublishedNotiKey)
|
|
|
case 97:
|
|
@@ -1486,7 +1487,7 @@ extension PQStuckPointPublicController {
|
|
|
/// - msg: <#msg description#>
|
|
|
func showUploadRemindView(isNetCollected _: Bool = true, msg: String? = nil) {
|
|
|
view.endEditing(true)
|
|
|
-
|
|
|
+
|
|
|
let emptyData = BFEmptyModel()
|
|
|
emptyData.isRefreshHidden = false
|
|
|
emptyData.title = "上传失败"
|
|
@@ -1494,26 +1495,26 @@ extension PQStuckPointPublicController {
|
|
|
emptyData.summary = "建议切换 WIFI/移动网络后再重试"
|
|
|
emptyData.summaryColor = UIColor.hexColor(hexadecimal: "#353535")
|
|
|
emptyData.refreshBgColor = UIColor.hexColor(hexadecimal: BFConfig.shared.styleColor.rawValue)
|
|
|
- emptyData.refreshTitle = NSMutableAttributedString(string: "立即重试", attributes: [.foregroundColor:UIColor.white])
|
|
|
- emptyData.emptySoureImage = UIImage.moduleImage(named: "stuckPoint_video_empty", moduleName: "BFMaterialKit",isAssets: false)
|
|
|
+ emptyData.refreshTitle = NSMutableAttributedString(string: "立即重试", attributes: [.foregroundColor: UIColor.white])
|
|
|
+ emptyData.emptySoureImage = UIImage.moduleImage(named: "stuckPoint_video_empty", moduleName: "BFMaterialKit", isAssets: false)
|
|
|
emptyData.netDisRefreshBgColor = UIColor.hexColor(hexadecimal: "#FA6400")
|
|
|
emptyData.netDisTitle = "内容加载失败"
|
|
|
emptyData.netDisTitleColor = UIColor.hexColor(hexadecimal: "#333333")
|
|
|
- emptyData.netemptyDisImage = UIImage.moduleImage(named: "empty_netDis_icon", moduleName: "BFMaterialKit",isAssets: false)
|
|
|
+ emptyData.netemptyDisImage = UIImage.moduleImage(named: "empty_netDis_icon", moduleName: "BFMaterialKit", isAssets: false)
|
|
|
emptyData.netDisRefreshTitle = NSMutableAttributedString(string: "重新加载", attributes: [.font: UIFont.systemFont(ofSize: 16, weight: .medium), .foregroundColor: UIColor.white])
|
|
|
-
|
|
|
+
|
|
|
let emptyRemindView = BFEmptyRemindView(frame: CGRect(x: 0, y: cDevice_iPhoneNavBarAndStatusBarHei, width: view.frame.width, height: view.frame.height - cDevice_iPhoneNavBarAndStatusBarHei))
|
|
|
// emptyRemindView.isHidden = true
|
|
|
emptyRemindView.emptyData = emptyData
|
|
|
emptyRemindView.backgroundColor = BFConfig.shared.styleBackGroundColor
|
|
|
- emptyRemindView.fullRefreshBloc = {[weak self, weak emptyRemindView] _, _ in
|
|
|
+ emptyRemindView.fullRefreshBloc = { [weak self, weak emptyRemindView] _, _ in
|
|
|
if emptyRemindView?.refreshBtn.currentAttributedTitle?.string == "立即重试" {
|
|
|
emptyRemindView?.isHidden = true
|
|
|
// 重试逻辑
|
|
|
- if let message = msg{
|
|
|
+ if let message = msg {
|
|
|
if message.contains("token") {
|
|
|
self?.uploadVideo()
|
|
|
- }else if message.contains("aliOss"){
|
|
|
+ } else if message.contains("aliOss") {
|
|
|
self?.uploadVideo()
|
|
|
}
|
|
|
}
|
|
@@ -1521,7 +1522,7 @@ extension PQStuckPointPublicController {
|
|
|
}
|
|
|
emptyRemindView.refreshBtn.addCorner(corner: 4)
|
|
|
view.addSubview(emptyRemindView)
|
|
|
-
|
|
|
+
|
|
|
// BFRemindView.showUploadRemindView(title: "上传失败", summary: (msg != nil ? msg! : "视频文件已丢失"), confirmTitle: "立即重试") { [weak self] _, _ in
|
|
|
// self?.navigationController?.popToViewController((self?.navigationController?.viewControllers[1])!, animated: true)
|
|
|
// }
|
|
@@ -1594,7 +1595,6 @@ extension PQStuckPointPublicController {
|
|
|
}
|
|
|
|
|
|
PQEventTrackViewModel.baseReportUpload(businessType: .bt_buttonClick, objectType: .ot_shanyinApp_clickButton_changeTitle, pageSource: .sp_stuck_publishSyncedUp, eventData: ["videoId": videoData?.uniqueId ?? "", "rootPageSource": isReCreate ? "shanyinApp-main-syncedUpMusicRecreate" : "shanyinApp-main-syncedUpMusic"], remindmsg: "")
|
|
|
-
|
|
|
}
|
|
|
|
|
|
@objc func settingCoverImage() {
|
|
@@ -1632,15 +1632,11 @@ extension PQStuckPointPublicController {
|
|
|
}
|
|
|
|
|
|
PQEventTrackViewModel.baseReportUpload(businessType: .bt_buttonClick, objectType: .ot_shanyinApp_clickButton_changeCover, pageSource: .sp_stuck_publishSyncedUp, eventData: ["videoId": videoData?.uniqueId ?? "", "rootPageSource": isReCreate ? "shanyinApp-main-syncedUpMusicRecreate" : "shanyinApp-main-syncedUpMusic"], remindmsg: "")
|
|
|
-
|
|
|
}
|
|
|
|
|
|
// 更新标题或封面
|
|
|
func updateCoverImagegOrTitle() {
|
|
|
BFLoadingHUB.shared.showHUB(isMode: true)
|
|
|
- // SanW - 待修改 -
|
|
|
-// BFLoadingHUB.shared.showHUB(isMode: true)
|
|
|
-
|
|
|
PQBaseViewModel.ossTempToken { [weak self] response, msg in
|
|
|
let image: UIImage = (self?.uploadData?.image)!
|
|
|
let data = image.jpegData(compressionQuality: 1)
|
|
@@ -1659,10 +1655,9 @@ extension PQStuckPointPublicController {
|
|
|
)
|
|
|
.uploadObjectAsync(bucketName: bucketName, objectKey: objectKey, data: data!, fileExtensions: "png", imageUploadBlock: { _, code, ossObjectKey, _ in
|
|
|
if code == 1 && ossObjectKey == objectKey && ossObjectKey.count > 0 {
|
|
|
+ // add by ak 这里会在服务器生成分享使用的图片到1-2S 时间
|
|
|
+ PQUploadViewModel.updateVideo(title: self?.videoData?.title ?? "", videoId: self?.videoData?.uniqueId ?? "", coverImgPath: objectKey, descr: "") { _, newVideoData, msg in
|
|
|
|
|
|
- //add by ak 这里会在服务器生成分享使用的图片到1-2S 时间
|
|
|
- PQUploadViewModel.updateVideo(title: self?.videoData?.title ?? "", videoId: self?.videoData?.uniqueId ?? "", coverImgPath: objectKey, descr: "") {_, newVideoData, msg in
|
|
|
-
|
|
|
if newVideoData == nil {
|
|
|
cShowHUB(superView: self?.view, msg: msg)
|
|
|
// 可能有敏感词 要刷一组新标题并自动更新
|
|
@@ -1682,8 +1677,8 @@ extension PQStuckPointPublicController {
|
|
|
BFLoadingHUB.shared.dismissHUB()
|
|
|
}
|
|
|
})
|
|
|
-
|
|
|
- } }
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
func setTitleText(text: String, textColor: UIColor = UIColor.hexColor(hexadecimal: "#ABABAB")) {
|
|
|
selectTitle = text
|
|
@@ -1700,13 +1695,13 @@ extension PQStuckPointPublicController {
|
|
|
PQBaseViewModel.getBaseConfig(completeHander: { [weak self] titles in
|
|
|
|
|
|
if (titles?.count ?? 0) > 0 {
|
|
|
- var temp:Array<String> = titles!
|
|
|
- if((titles?.count ?? 0) <= 13){
|
|
|
- for _ in 0 ... (13 - (titles?.count ?? 0)){
|
|
|
+ var temp: [String] = titles!
|
|
|
+ if (titles?.count ?? 0) <= 13 {
|
|
|
+ for _ in 0 ... (13 - (titles?.count ?? 0)) {
|
|
|
temp.append("")
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
self?.publicTitleView.titles = temp
|
|
|
|
|
|
let numberRandom: UInt32 = UInt32(arc4random_uniform(UInt32(titles!.count)))
|
|
@@ -1732,8 +1727,9 @@ extension PQStuckPointPublicController {
|
|
|
}
|
|
|
|
|
|
// MARK: - 导出带水印+片尾的视频相关方法
|
|
|
+
|
|
|
extension PQStuckPointPublicController {
|
|
|
- //导出有水印的正片子
|
|
|
+ // 导出有水印的正片子
|
|
|
func beginExportWatermarkMovie(inputAsset: AVURLAsset!) {
|
|
|
if !(editProjectModel?.sData?.sections != nil && (editProjectModel?.sData?.sections.count ?? 0) > 0) {
|
|
|
BFLog(message: "项目段落错误❌")
|
|
@@ -1774,7 +1770,6 @@ extension PQStuckPointPublicController {
|
|
|
}
|
|
|
watermarkMovieExporter.progressClosure = { _, _, progress in
|
|
|
BFLog(message: "带水印的合成进度 \(progress) ")
|
|
|
-
|
|
|
}
|
|
|
watermarkMovieExporter.completion = { [weak self] url in
|
|
|
BFLog(message: "有水印的视频导出完成: \(String(describing: url)) 生成视频时长为:\(CMTimeGetSeconds(AVAsset(url: url ?? URL(string: "https://media.w3.org/2010/05/sintel/trailer.mp4")!).duration))")
|
|
@@ -1783,16 +1778,15 @@ extension PQStuckPointPublicController {
|
|
|
if self?.watermarkMovieExporter != nil {
|
|
|
self?.watermarkMovieExporter.cancel()
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
self?.watermarkMovieLocalURL = url
|
|
|
-
|
|
|
- //开始导出片尾 成功后自动保存到相册
|
|
|
+
|
|
|
+ // 开始导出片尾 成功后自动保存到相册
|
|
|
self?.beginExportEndMovie()
|
|
|
-
|
|
|
-
|
|
|
}
|
|
|
}
|
|
|
- //导出片尾视频
|
|
|
+
|
|
|
+ // 导出片尾视频
|
|
|
func beginExportEndMovie() {
|
|
|
if !(editProjectModel?.sData?.sections != nil && (editProjectModel?.sData?.sections.count ?? 0) > 0) {
|
|
|
BFLog(message: "项目段落错误❌")
|
|
@@ -1807,16 +1801,16 @@ extension PQStuckPointPublicController {
|
|
|
outPutMP4Path.append("endMovie_\(String.qe.timestamp()).mp4")
|
|
|
let outPutMP4URL = URL(fileURLWithPath: outPutMP4Path)
|
|
|
BFLog(message: "导出视频地址 \(outPutMP4URL)")
|
|
|
-
|
|
|
+
|
|
|
var orgeBitRate = (editProjectModel?.sData?.videoMetaData?.videoWidth ?? 0) * (editProjectModel?.sData?.videoMetaData?.videoHeight ?? 0) * 3
|
|
|
-
|
|
|
- //片尾的视频素材地址
|
|
|
- let moveResPath = currentBundlePath()!.path(forResource: (editProjectModel?.sData?.videoMetaData?.videoWidth ?? 0) < (editProjectModel?.sData?.videoMetaData?.videoHeight ?? 0) ? "endMovieB" : "endMovieA", ofType: "mp4")
|
|
|
- if(moveResPath?.count ?? 0 == 0){
|
|
|
+
|
|
|
+ // 片尾的视频素材地址
|
|
|
+ let moveResPath = currentBundlePath()!.path(forResource: (editProjectModel?.sData?.videoMetaData?.videoWidth ?? 0) < (editProjectModel?.sData?.videoMetaData?.videoHeight ?? 0) ? "endMovieB" : "endMovieA", ofType: "mp4")
|
|
|
+ if moveResPath?.count ?? 0 == 0 {
|
|
|
BFLog(message: "片尾的视频素材地址无效!!!")
|
|
|
return
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
let movieAsset = AVURLAsset(url: URL(fileURLWithPath: moveResPath!), options: avAssertOptions)
|
|
|
let cbr = movieAsset.tracks(withMediaType: .video).first?.estimatedDataRate
|
|
|
BFLog(message: "cbr is\(cbr ?? 0)")
|
|
@@ -1824,30 +1818,30 @@ extension PQStuckPointPublicController {
|
|
|
orgeBitRate = Int(cbr ?? 0)
|
|
|
}
|
|
|
BFLog(message: "导出设置的码率为:\(orgeBitRate)")
|
|
|
-
|
|
|
- //头像保存沙盒地址
|
|
|
+
|
|
|
+ // 头像保存沙盒地址
|
|
|
BFLog(message: "头像的网络地址\(BFLoginUserInfo.shared.avatarUrl)")
|
|
|
let avatarFilePath = NSHomeDirectory().appending("/Documents/").appending("user_avatar.jpg")
|
|
|
-
|
|
|
+
|
|
|
// warning:给默认头像吧
|
|
|
- ImageDownloader.default.downloadImage(with: URL(string: BFLoginUserInfo.shared.avatarUrl)!, options: nil) {[weak self] result in
|
|
|
- var image : UIImage?
|
|
|
+ ImageDownloader.default.downloadImage(with: URL(string: BFLoginUserInfo.shared.avatarUrl)!, options: nil) { [weak self] result in
|
|
|
+ var image: UIImage?
|
|
|
switch result {
|
|
|
- case let .success(imageResult):
|
|
|
+ case let .success(imageResult):
|
|
|
image = UIImage.nx_circleImage(imageResult.image)
|
|
|
-
|
|
|
+
|
|
|
case let .failure(error):
|
|
|
- image = UIImage.moduleImage(named: "user_avatar_normal", moduleName: "BFFramework", isAssets:false)
|
|
|
+ image = UIImage.moduleImage(named: "user_avatar_normal", moduleName: "BFFramework", isAssets: false)
|
|
|
BFLog(message: "下载头像图片失败:\(error.localizedDescription)")
|
|
|
}
|
|
|
- if(image == nil){
|
|
|
+ if image == nil {
|
|
|
BFLog(message: "image date is error!!")
|
|
|
return
|
|
|
}
|
|
|
UIImage.saveImage(currentImage: image!, outFilePath: avatarFilePath)
|
|
|
-
|
|
|
- //1,背景视频素材
|
|
|
- let bgMovieInfo:PQEditVisionTrackMaterialsModel = PQEditVisionTrackMaterialsModel.init()
|
|
|
+
|
|
|
+ // 1,背景视频素材
|
|
|
+ let bgMovieInfo: PQEditVisionTrackMaterialsModel = PQEditVisionTrackMaterialsModel()
|
|
|
bgMovieInfo.type = StickerType.VIDEO.rawValue
|
|
|
bgMovieInfo.locationPath = moveResPath ?? ""
|
|
|
bgMovieInfo.timelineIn = 0
|
|
@@ -1855,105 +1849,99 @@ extension PQStuckPointPublicController {
|
|
|
bgMovieInfo.model_in = bgMovieInfo.timelineIn
|
|
|
bgMovieInfo.out = bgMovieInfo.timelineOut
|
|
|
bgMovieInfo.canvasFillType = stickerContentMode.aspectFitStr.rawValue
|
|
|
- //2,用户头像素材
|
|
|
+ // 2,用户头像素材
|
|
|
BFLog(message: "头像的沙盒地址:\(avatarFilePath)")
|
|
|
- let avatarSticker:PQEditVisionTrackMaterialsModel = PQEditVisionTrackMaterialsModel.init()
|
|
|
+ let avatarSticker: PQEditVisionTrackMaterialsModel = PQEditVisionTrackMaterialsModel()
|
|
|
avatarSticker.locationPath = avatarFilePath.replacingOccurrences(of: documensDirectory, with: "")
|
|
|
avatarSticker.timelineIn = bgMovieInfo.timelineIn
|
|
|
avatarSticker.timelineOut = bgMovieInfo.timelineOut
|
|
|
avatarSticker.canvasFillType = stickerContentMode.aspectFitStr.rawValue
|
|
|
|
|
|
- //头像绘制大小\位置
|
|
|
- var avatarSize:Float = 0.0
|
|
|
- var avatarTop:Float = 0.0
|
|
|
- if((self?.editProjectModel?.sData?.videoMetaData?.videoHeight ?? 0) > (self?.editProjectModel?.sData?.videoMetaData?.videoWidth ?? 0)){
|
|
|
- //竖屏
|
|
|
+ // 头像绘制大小\位置
|
|
|
+ var avatarSize: Float = 0.0
|
|
|
+ var avatarTop: Float = 0.0
|
|
|
+ if (self?.editProjectModel?.sData?.videoMetaData?.videoHeight ?? 0) > (self?.editProjectModel?.sData?.videoMetaData?.videoWidth ?? 0) {
|
|
|
+ // 竖屏
|
|
|
avatarSize = Float(self?.editProjectModel?.sData?.videoMetaData?.videoWidth ?? 0) * 360.0 / 1080.0
|
|
|
avatarTop = 430
|
|
|
- }else{
|
|
|
- //横屏屏
|
|
|
+ } else {
|
|
|
+ // 横屏屏
|
|
|
avatarSize = Float(self?.editProjectModel?.sData?.videoMetaData?.videoHeight ?? 0) * 300.0 / 1080.0
|
|
|
avatarTop = Float(self?.editProjectModel?.sData?.videoMetaData?.videoHeight ?? 0) * 130.0 / 1080.0
|
|
|
}
|
|
|
|
|
|
- let avatarPostion:PQEditMaterialPositionModel = PQEditMaterialPositionModel.init()
|
|
|
+ let avatarPostion: PQEditMaterialPositionModel = PQEditMaterialPositionModel()
|
|
|
avatarPostion.width = Int(avatarSize)
|
|
|
avatarPostion.height = Int(avatarSize)
|
|
|
avatarPostion.x = ((self?.editProjectModel?.sData?.videoMetaData?.videoWidth ?? 0) - Int(avatarSize)) / 2
|
|
|
avatarPostion.y = Int(avatarTop)
|
|
|
avatarSticker.materialPosition = avatarPostion
|
|
|
-
|
|
|
- //3,用户名素材
|
|
|
- let userNameSticker:PQEditVisionTrackMaterialsModel = PQEditVisionTrackMaterialsModel.init()
|
|
|
+
|
|
|
+ // 3,用户名素材
|
|
|
+ let userNameSticker: PQEditVisionTrackMaterialsModel = PQEditVisionTrackMaterialsModel()
|
|
|
userNameSticker.timelineIn = bgMovieInfo.timelineIn
|
|
|
userNameSticker.timelineOut = bgMovieInfo.timelineOut
|
|
|
userNameSticker.type = StickerType.SUBTITLE.rawValue
|
|
|
-
|
|
|
-
|
|
|
- //用户名绘制用到的参数
|
|
|
- var userNameTop:Float = 0.0
|
|
|
- var userNameFontSize:Float = 0.0
|
|
|
- if((self?.editProjectModel?.sData?.videoMetaData?.videoHeight ?? 0) > (self?.editProjectModel?.sData?.videoMetaData?.videoWidth ?? 0)){
|
|
|
- //竖屏
|
|
|
+
|
|
|
+ // 用户名绘制用到的参数
|
|
|
+ var userNameTop: Float = 0.0
|
|
|
+ var userNameFontSize: Float = 0.0
|
|
|
+ if (self?.editProjectModel?.sData?.videoMetaData?.videoHeight ?? 0) > (self?.editProjectModel?.sData?.videoMetaData?.videoWidth ?? 0) {
|
|
|
+ // 竖屏
|
|
|
userNameTop = 870
|
|
|
userNameFontSize = Float(self?.editProjectModel?.sData?.videoMetaData?.videoWidth ?? 0) * 100.0 / 1080.0
|
|
|
- }else{
|
|
|
- //横屏
|
|
|
+ } else {
|
|
|
+ // 横屏
|
|
|
userNameTop = Float(self?.editProjectModel?.sData?.videoMetaData?.videoHeight ?? 0) * 480 / 1080.0
|
|
|
userNameFontSize = Float(self?.editProjectModel?.sData?.videoMetaData?.videoHeight ?? 0) * 70.0 / 1080.0
|
|
|
}
|
|
|
-
|
|
|
- let subtitleInfo:PQEditSubtitleInfoModel = PQEditSubtitleInfoModel.init()
|
|
|
+
|
|
|
+ let subtitleInfo: PQEditSubtitleInfoModel = PQEditSubtitleInfoModel()
|
|
|
subtitleInfo.fontSize = Int(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
|
|
|
+ let userNamePostion: PQEditMaterialPositionModel = PQEditMaterialPositionModel()
|
|
|
+ userNamePostion.width = Int(userNameFontSize) * 10
|
|
|
+ userNamePostion.height = Int(userNameFontSize) * 3
|
|
|
+ userNamePostion.x = ((self?.editProjectModel?.sData?.videoMetaData?.videoWidth ?? 0) - userNamePostion.width) / 2
|
|
|
userNamePostion.y = Int(userNameTop)
|
|
|
userNameSticker.materialPosition = userNamePostion
|
|
|
|
|
|
- //4,音频
|
|
|
+ // 4,音频
|
|
|
let soundResPath = currentBundlePath()!.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)
|
|
|
+ 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)) != nil) {
|
|
|
-
|
|
|
- self?.endMovieExporter.start(playeTimeRange: CMTimeRange.init(start: CMTime.zero, duration: CMTimeMakeWithSeconds(Float64(bgMovieInfo.out), preferredTimescale: BASE_FILTER_TIMESCALE)))
|
|
|
+ if (self?.endMovieExporter.prepare(videoSize: CGSize(width: self?.editProjectModel?.sData?.videoMetaData?.videoWidth ?? 0, height: self?.editProjectModel?.sData?.videoMetaData?.videoHeight ?? 0), videoAverageBitRate: orgeBitRate)) != nil {
|
|
|
+ self?.endMovieExporter.start(playeTimeRange: CMTimeRange(start: CMTime.zero, duration: CMTimeMakeWithSeconds(Float64(bgMovieInfo.out), preferredTimescale: BASE_FILTER_TIMESCALE)))
|
|
|
BFLog(message: "开始导出")
|
|
|
}
|
|
|
self?.endMovieExporter.progressClosure = { _, _, progress in
|
|
|
BFLog(message: "片尾合成进度 \(progress) ")
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
self?.endMovieExporter.completion = { [weak self] url in
|
|
|
BFLog(message: "片尾的视频导出完成: \(String(describing: url)) 生成视频时长为:\(CMTimeGetSeconds(AVAsset(url: url ?? URL(string: "https://media.w3.org/2010/05/sintel/trailer.mp4")!).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){
|
|
|
+ // 拼接水印正片和片尾
|
|
|
+ if self?.watermarkMovieLocalURL != nil, self?.endMovieLocalURL != nil {
|
|
|
+ let videoMerge: NXVideoMerge = NXVideoMerge()
|
|
|
+ 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 - 请求权限
|
|
|
+ // 保存到相册 fp2-1-1 - 请求权限
|
|
|
self?.authorizationStatus()
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
}
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
}
|