|
@@ -68,6 +68,12 @@ class PQStuckPointPublicController: PQBaseViewController {
|
|
|
var clipAudioRange: CMTimeRange = CMTimeRange.zero
|
|
|
// 导出的开始的开始和结束时间
|
|
|
var playeTimeRange: CMTimeRange = CMTimeRange()
|
|
|
+
|
|
|
+ //add by ak 保存系统相册使用的变量
|
|
|
+ // 导出保存相册视频工具类
|
|
|
+ private var saveMovieExporter: PQCompositionExporter!
|
|
|
+ private var saveMovieExportLocalURL: URL? // 导出的地址
|
|
|
+ //----------------------------
|
|
|
|
|
|
// 预览大小
|
|
|
private var preViewSize: CGSize {
|
|
@@ -758,7 +764,10 @@ 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)
|
|
|
+ //导出带水印的正片
|
|
|
+ self?.beginExportSaveMovie(inputAsset:asset)
|
|
|
}else{
|
|
|
cShowHUB(superView: self?.view, msg: "合成失败请重试。")
|
|
|
}
|
|
@@ -812,7 +821,7 @@ extension PQStuckPointPublicController {
|
|
|
}
|
|
|
}
|
|
|
exporter.completion = { [weak self] url in
|
|
|
- BFLog(message: "MovieOutput total frames appended:导了完成: \(url) 生成视频时长为:\(CMTimeGetSeconds(AVAsset(url: url).duration))")
|
|
|
+ BFLog(message: "无水印的视频导出完成: \(url) 生成视频时长为:\(CMTimeGetSeconds(AVAsset(url: url).duration))")
|
|
|
|
|
|
// 导出完成后取消导出
|
|
|
if self?.exporter != nil {
|
|
@@ -860,11 +869,16 @@ extension PQStuckPointPublicController {
|
|
|
/// - Parameter localPath: localPath description
|
|
|
/// - Returns: <#description#>
|
|
|
func saveStuckPointVideo() {
|
|
|
+
|
|
|
+ if(saveMovieExportLocalURL == nil){
|
|
|
+ BFLog(message: "保存相册的视频导出地址无效!!!")
|
|
|
+ return
|
|
|
+ }
|
|
|
let authStatus = PHPhotoLibrary.authorizationStatus()
|
|
|
if authStatus == .authorized {
|
|
|
let photoLibrary = PHPhotoLibrary.shared()
|
|
|
photoLibrary.performChanges({ [weak self] in
|
|
|
- PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: (self?.exportLocalURL)!)
|
|
|
+ PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: (self?.saveMovieExportLocalURL)!)
|
|
|
}) { [weak self] isFinished, _ in
|
|
|
DispatchQueue.main.async { [weak self] in
|
|
|
if self?.view != nil {
|
|
@@ -1518,3 +1532,61 @@ extension PQStuckPointPublicController {
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+// MARK: - 导出带水印+片尾的视频相关方法
|
|
|
+extension PQStuckPointPublicController {
|
|
|
+ func beginExportSaveMovie(inputAsset: AVURLAsset!) {
|
|
|
+ if !(editProjectModel?.sData?.sections != nil && (editProjectModel?.sData?.sections.count ?? 0) > 0) {
|
|
|
+ BFLog(message: "项目段落错误❌")
|
|
|
+ return
|
|
|
+ }
|
|
|
+ // 输出视频地址
|
|
|
+ var outPutMP4Path = exportVideosDirectory
|
|
|
+ if !directoryIsExists(dicPath: outPutMP4Path) {
|
|
|
+ BFLog(message: "文件夹不存在")
|
|
|
+ createDirectory(path: outPutMP4Path)
|
|
|
+ }
|
|
|
+ outPutMP4Path.append("saveMovie_\(String.qe.timestamp()).mp4")
|
|
|
+ let outPutMP4URL = URL(fileURLWithPath: outPutMP4Path)
|
|
|
+ BFLog(message: "导出视频地址 \(outPutMP4URL)")
|
|
|
+
|
|
|
+ saveMovieExporter = PQCompositionExporter(asset: inputAsset, videoComposition: nil, audioMix: nil, filters: nil, stickers: mStickers, animationTool: nil, exportURL: outPutMP4URL)
|
|
|
+ saveMovieExporter.isAddWatermark = true
|
|
|
+ var orgeBitRate = (editProjectModel?.sData?.videoMetaData?.videoWidth ?? 0) * (editProjectModel?.sData?.videoMetaData?.videoHeight ?? 0) * 3
|
|
|
+
|
|
|
+ if mStickers != nil {
|
|
|
+ for stick in mStickers! {
|
|
|
+ if stick.type == StickerType.VIDEO.rawValue {
|
|
|
+ let asset = AVURLAsset(url: URL(fileURLWithPath: documensDirectory + stick.locationPath), options: avAssertOptions)
|
|
|
+
|
|
|
+ let cbr = asset.tracks(withMediaType: .video).first?.estimatedDataRate
|
|
|
+ if Int(cbr ?? 0) > orgeBitRate {
|
|
|
+ orgeBitRate = Int(cbr ?? 0)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ BFLog(message: "导出设置的码率为:\(orgeBitRate)")
|
|
|
+ saveMovieExporter.showGaussianBlur = true
|
|
|
+ if saveMovieExporter.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))")
|
|
|
+ saveMovieExporter.start(playeTimeRange: playeTimeRange)
|
|
|
+ BFLog(message: "开始导出")
|
|
|
+ }
|
|
|
+ saveMovieExporter.progressClosure = { [weak self] _, _, progress in
|
|
|
+ BFLog(message: "带水印的合成进度 \(progress) ")
|
|
|
+
|
|
|
+ }
|
|
|
+ saveMovieExporter.completion = { [weak self] url in
|
|
|
+ BFLog(message: "有水印的视频导出完成: \(url) 生成视频时长为:\(CMTimeGetSeconds(AVAsset(url: url).duration))")
|
|
|
+
|
|
|
+ // 导出完成后取消导出
|
|
|
+ if self?.saveMovieExporter != nil {
|
|
|
+ self?.saveMovieExporter.cancel()
|
|
|
+ }
|
|
|
+
|
|
|
+ self?.saveMovieExportLocalURL = url
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|