Jelajahi Sumber

添加原音频可拼接方法

jsonwang 3 tahun lalu
induk
melakukan
9875d51aa7

+ 3 - 3
BFFramework/Classes/Stuckpoint/ViewModel/PQGPUImagePlayerView.swift

@@ -326,7 +326,7 @@ public class PQGPUImagePlayerView: UIView {
     }
 
     /// XXXX 这里的 URL 使用的是全路径 ,如果不是全的会 crash ,方便复用 (不用处理业务的文件放在哪里)
-   public func updateAsset(_ url: URL, videoComposition: AVVideoComposition? = nil, audioMixModel: PQVoiceModel? = nil, videoStickers: [PQEditVisionTrackMaterialsModel]? = nil) {
+    public func updateAsset(_ url: URL, videoComposition: AVVideoComposition? = nil, audioMixModel: PQVoiceModel? = nil, videoStickers: [PQEditVisionTrackMaterialsModel]? = nil,originMusicDuration:Float = 0,lastPoint:Float = 0,clipAudioRange: CMTimeRange = CMTimeRange.zero ) {
         // 每次初始化的时候设置初始值 为 nIl
         var audioMix: AVMutableAudioMix?
         var composition: AVMutableComposition?
@@ -334,9 +334,9 @@ public class PQGPUImagePlayerView: UIView {
         let asset = AVURLAsset(url: url, options: nil)
         FilterLog(message: "播放器初始化的音频时长\(asset.duration.seconds)  url is \(url)")
         self.asset = asset
-        if (audioMixModel != nil && audioMixModel?.localPath != nil) || (videoStickers != nil && (videoStickers?.count ?? 0) > 0) {
+        if (audioMixModel != nil && audioMixModel?.localPath != nil) || (videoStickers != nil && (videoStickers?.count ?? 0) > 0 || originMusicDuration != 0) {
             FilterLog(message: "有参加混音的数据。")
-            (audioMix, composition) = PQPlayerViewModel.setupAudioMix(originAsset: asset, bgmData: audioMixModel, videoStickers: videoStickers)
+            (audioMix, composition) = PQPlayerViewModel.setupAudioMix(originAsset: asset, bgmData: audioMixModel, videoStickers: videoStickers,clipAudioRange: clipAudioRange)
         } else {
             audioMix = nil
         }

+ 60 - 6
BFFramework/Classes/Stuckpoint/ViewModel/PQPlayerViewModel.swift

@@ -579,16 +579,30 @@ extension PQPlayerViewModel {
     ///   - originAsset: 空音乐文件素材
     ///   - bgmData: 背景音乐
     ///   - videoStickers: 视频素材
-    /// - Returns: <#description#>
-    public class func setupAudioMix(originAsset: AVURLAsset, bgmData: PQVoiceModel?, videoStickers: [PQEditVisionTrackMaterialsModel]?) -> (AVMutableAudioMix, AVMutableComposition) {
+    ///   - originMusicDuration : 要播放的时长
+    ///   - lastSecondPoint : 音频长度不够时,拼接音频文件时的结束时间,推荐卡点的倒数第二位
+    /// - Returns:
+    public class func setupAudioMix(originAsset: AVURLAsset, bgmData: PQVoiceModel?, videoStickers: [PQEditVisionTrackMaterialsModel]?,originMusicDuration:Float = 0,clipAudioRange: CMTimeRange = CMTimeRange.zero ) -> (AVMutableAudioMix, AVMutableComposition) {
         let composition = AVMutableComposition()
         let audioMix = AVMutableAudioMix()
         var tempParameters: [AVMutableAudioMixInputParameters] = [AVMutableAudioMixInputParameters].init()
-        // 处理空素材
-        let parameters = mixAudioTrack(audioAsset: originAsset, trackTimeRange: CMTimeRange(start: .zero, end: originAsset.duration), composition: composition)
-        if parameters != nil {
-            tempParameters.append(parameters!)
+        // 处理选择的主音乐
+        if(originMusicDuration > Float(CMTimeGetSeconds(originAsset.duration))){
+            BFLog(message: "要播放的时间长,比原音频要长进行拼接originMusicDuration:\(originMusicDuration)   originAsset.duration \(CMTimeGetSeconds(originAsset.duration))")
+            let originaParameters =  dealWithOriginAssetTrack(originAsset: originAsset, totalDuration: Float64(originMusicDuration), composition: composition,clipAudioRange: clipAudioRange)
+            
+            if originaParameters.count > 0 {
+                tempParameters = tempParameters + originaParameters
+            }
+            
+        }else{
+            
+            let parameters = mixAudioTrack(audioAsset: originAsset, trackTimeRange: CMTimeRange(start: .zero, end: originAsset.duration), composition: composition)
+            if parameters != nil {
+                tempParameters.append(parameters!)
+            }
         }
+     
         // 处理背景音乐
         if bgmData != nil, bgmData?.localPath != nil {
             let bgmParameters = dealWithBGMTrack(bgmData: bgmData!, totalDuration: originAsset.duration.seconds, composition: composition)
@@ -615,6 +629,46 @@ extension PQPlayerViewModel {
         // exportAudio(comosition: composition)
         return (audioMix, composition)
     }
+    
+    /// 处理原主音乐音轨  e.g. 原音频时长只有30s  要播放 250s 的音频 拼接原音频音轨
+    /// - Parameters:
+    ///   - originAsset: 原音频文件地址
+    ///   - composition:
+    /// - Returns:
+    public class func dealWithOriginAssetTrack(originAsset: AVURLAsset, totalDuration: Float64, composition: AVMutableComposition,clipAudioRange: CMTimeRange = CMTimeRange.zero ) -> [AVMutableAudioMixInputParameters] {
+        var tempParameters: [AVMutableAudioMixInputParameters] = [AVMutableAudioMixInputParameters].init()
+        let volume:Float = 1.0
+        let originaDuration = CMTimeGetSeconds(originAsset.duration)
+        BFLog(message: "处理主音频 原始时长startTime = \(originaDuration) 要显示时长totalDuration = \(totalDuration)")
+        //整倍数
+        var count = Int(totalDuration) / Int(originaDuration)
+        //有余数多 clip 一整段
+        let row = totalDuration - Double(count) * originaDuration
+        count = row > 0 ? count + 1 : count
+        if count > 0 {
+            for index in 0 ..< count {
+               
+                //第一段是0到倒数第二个卡点, 其它段都是从推荐卡点到倒数第二个卡点
+                var startTime = CMTime.zero
+                var trackTimeRange = CMTimeRange.zero
+       
+                if(index == 0){
+                    startTime = CMTime.zero
+                    trackTimeRange =  CMTimeRange(start: CMTime.zero, end: CMTime(value: CMTimeValue(CMTimeGetSeconds(clipAudioRange.end) * Double(playerTimescaleInt)), timescale: playerTimescaleInt))
+                }else{
+                    startTime = CMTime(value: CMTimeValue((CMTimeGetSeconds( clipAudioRange.duration) * Double(index) + CMTimeGetSeconds(clipAudioRange.start)) * Float64(playerTimescaleInt)), timescale: playerTimescaleInt)
+                    trackTimeRange = clipAudioRange
+                }
+                BFLog(message: "原音频时长短:count = \(count),startTime = \(startTime),trackTimeRange = \(trackTimeRange)")
+                let parameters = mixAudioTrack(audioAsset: originAsset, startTime: startTime, trackTimeRange: trackTimeRange, volume: volume, composition: composition)
+                if parameters != nil {
+                    tempParameters.append(parameters!)
+                }
+            }
+        }
+
+        return tempParameters
+    }
 
     /// 处理背景音乐音轨
     /// - Parameters: