Jelajahi Sumber

Merge branch 'master' of https://git.yishihui.com/iOS/BFRecordScreenKit

# Conflicts:
#	BFRecordScreenKit/Classes/BFRecordExport.swift
1,合并代码,2 添加音量设置 VIEW
jsonwang 3 tahun lalu
induk
melakukan
6d1b588050

+ 3 - 3
BFRecordScreenKit.podspec

@@ -44,9 +44,9 @@ TODO: Add long description of the pod here.
   # s.public_header_files = 'Pod/Classes/**/*.h'
   # s.frameworks = 'UIKit', 'MapKit'
   s.dependency 'BFCommonKit'
-  s.dependency 'BFFramework'
-  s.dependency 'BFVideoEditKit'
+  s.dependency 'BFNetRequestKit'
+  s.dependency 'BFMaterialKit'
+  s.dependency 'BFMediaKit'
   s.dependency 'BFUIKit'
   s.dependency 'GPUImage'
-
 end

+ 110 - 47
BFRecordScreenKit/Classes/BFRecordExport.swift

@@ -7,10 +7,10 @@
 
 import Foundation
 import AVFoundation
-import BFFramework
-import BFVideoEditKit
 import Photos
 import GPUImage
+import BFCommonKit
+import BFMediaKit
 
 public class BFRecordExport {
     public var progress : ((Float)->Void)?
@@ -46,29 +46,49 @@ public class BFRecordExport {
         if let itemModels = data {
             
             var totalDur = 0.0
-            for (index, itemModel) in itemModels.enumerated() {
+            
+            // 切割视频素材
+            for (_, itemModel) in itemModels.enumerated() {
                 itemModel.videoStickers.removeAll()
-                let asset = itemModel.baseMaterial
-                if let dur = asset?.duration.seconds {
-                    if synthesisAll {
-                        let bgMovieInfo = splitBaseMaterial(timelineIn: totalDur, model_in: 0, duration: dur)
-                        bgMovieInfo.volumeGain = 0
-                        itemModel.videoStickers.append(bgMovieInfo)
-                        totalDur += dur
-                    } else {
-                        var subDur = 0.0
-                        let drangs = itemModel.dealedDurationRanges.filter { ranges in
-                            ranges.isRecord == true
-                        }
-                        for srange in drangs {
-                            let range = srange.range
-                            let sticker = splitBaseMaterial(timelineIn: (totalDur + subDur), model_in: range.start.seconds, duration: range.duration.seconds)
-                            sticker.volumeGain = 0
-                            itemModel.videoStickers.append(sticker)
-                            subDur += range.duration.seconds
+                
+                if synthesisAll {
+                    // 保留全部
+                    //                        let bgMovieInfo = splitBaseMaterial(timelineIn: totalDur, model_in: 0, duration: dur)
+                    //                        bgMovieInfo.volumeGain = 0
+                    //                        itemModel.videoStickers.append(bgMovieInfo)
+                    //                        totalDur += dur
+                    var subDur = 0.0
+                    let drangs = itemModel.dealedDurationRanges
+                    for srange in drangs {
+                        let range = srange.range
+                        let sticker = splitBaseMaterial(timelineIn: (totalDur + subDur), model_in: range.start.seconds, duration: range.duration.seconds)
+                        sticker.volumeGain = srange.isRecord ? 0 : 100
+                        itemModel.videoStickers.append(sticker)
+                        subDur += range.duration.seconds
+                    }
+                    totalDur += subDur
+                    //                        assert(totalDur == dur)
+                } else {
+                    var subDur = 0.0
+                    var drangs = itemModel.dealedDurationRanges.filter { srange in
+                        srange.isRecord == true
+                    }
+                    
+                    // 是否按录音顺序排列
+                    let needSort = false
+                    if needSort {
+                        drangs.sort { range1, range2 in
+                            range1.index < range2.index
                         }
-                        totalDur += subDur
                     }
+                    for srange in drangs {
+                        let range = srange.range
+                        let sticker = splitBaseMaterial(timelineIn: (totalDur + subDur), model_in: range.start.seconds, duration: range.duration.seconds)
+                        sticker.volumeGain = 0
+                        itemModel.videoStickers.append(sticker)
+                        subDur += range.duration.seconds
+                    }
+                    totalDur += subDur
                 }
             }
             beginExport(synthesisAll:synthesisAll)
@@ -79,6 +99,16 @@ public class BFRecordExport {
         self.exporter?.cancel()
     }
     
+    public func clearFileCache(){
+        data?.forEach({ itemModel in
+            itemModel.voiceStickers.forEach { model in
+                if let localPath = model.wavFilePath{
+                    try? FileManager.default.removeItem(atPath: localPath)
+                }
+            }
+        })
+    }
+    
     
     enum DispatchError: Error {
         case timeout
@@ -96,19 +126,19 @@ public class BFRecordExport {
     
     func splitBaseMaterial(timelineIn:Double, model_in:Double, duration:Double) -> PQEditVisionTrackMaterialsModel{
         let bgMovieInfo: PQEditVisionTrackMaterialsModel = PQEditVisionTrackMaterialsModel()
-        if let asset = data?.first?.baseMaterial {
-            bgMovieInfo.type = StickerType.VIDEO.rawValue
-            bgMovieInfo.locationPath = ((asset.url.absoluteString).removingPercentEncoding ?? "").replacingOccurrences(of: "file://", with: "")
-            bgMovieInfo.timelineIn = timelineIn
-            bgMovieInfo.timelineOut = timelineIn + duration
-            bgMovieInfo.model_in = model_in
-            bgMovieInfo.out = model_in + duration
-            bgMovieInfo.canvasFillType = stickerContentMode.aspectFitStr.rawValue
-            bgMovieInfo.volumeGain = 1
-            bgMovieInfo.aptDuration = bgMovieInfo.timelineOut
-            bgMovieInfo.duration = bgMovieInfo.timelineOut
-            BFLog(1, message: "hhh- timIn:\(timelineIn), modIn:\(model_in), dur:\(duration)")
+        bgMovieInfo.type = StickerType.VIDEO.rawValue
+        bgMovieInfo.timelineIn = timelineIn
+        bgMovieInfo.timelineOut = timelineIn + duration
+        bgMovieInfo.model_in = model_in
+        bgMovieInfo.out = model_in + duration
+        bgMovieInfo.canvasFillType = stickerContentMode.aspectFitStr.rawValue
+        bgMovieInfo.volumeGain = 1
+        bgMovieInfo.aptDuration = bgMovieInfo.timelineOut
+        bgMovieInfo.duration = bgMovieInfo.timelineOut
+        if let localPath = data?.first?.localPath {
+            bgMovieInfo.locationPath = localPath
         }
+        BFLog(1, message: "hhh- timIn:\(timelineIn), modIn:\(model_in), dur:\(duration)")
         
         return bgMovieInfo
     }
@@ -125,19 +155,49 @@ public class BFRecordExport {
         let outPutMP4URL = URL(fileURLWithPath: outPutMP4Path)
         BFLog(1, message: "导出视频地址 \(outPutMP4URL)")
         
-        guard let itemModel = data?.first else {
+        guard let itemData = data else {
+            let error = NSError(domain: "err", code: -1, userInfo: ["msg":"voiceStickers count += nil"])
+            self.exportCompletion?(error as Error, nil)
             return
         }
+        
         // 处理导出
-        let voiceList = itemModel.voiceStickers
-        let videoStickers = itemModel.videoStickers
-        if voiceList.count > 0 || videoStickers.count > 1 {
+        var voiceList = [PQVoiceModel]()
+        var videoStickers = [PQEditVisionTrackMaterialsModel]()
+        var titleStickers = [PQEditSubTitleModel]()
+        for itemModel in itemData {
+            voiceList.append(contentsOf: itemModel.voiceStickers)
+            videoStickers.append(contentsOf: itemModel.videoStickers)
+            titleStickers.append(contentsOf: itemModel.titleStickers)
+        }
+        
+        
+        guard let voiceCount = data?.reduce(0, { partialResult, itemModell in
+            itemModell.voiceStickers.count + partialResult
+        }) else {
+            BFLog(1, message: "voiceStickers count += nil")
+            let error = NSError(domain: "err", code: -1, userInfo: ["msg":"voiceStickers count += nil"])
+            self.exportCompletion?(error as Error, nil)
+            return
+        }
+        
+        guard let totalDuration = data?.reduce(0, { partialResult, itemModell in
+            (itemModell.materialDuraion ) + partialResult
+        }) else {
+            let error = NSError(domain: "err", code: -1, userInfo: ["msg":"时长计算出错"])
+            self.exportCompletion?(error as Error, nil)
+            return
+        }
+        
+        // 有录音操作或者多个视频,就会进入合成步骤,否则就是一个没有处理的素材,直接导出就行了
+        if voiceCount > 0 || videoStickers.count > 1 {
 
             let (audioMix, composition) = mergeAudio(videoStickers: videoStickers, audios: voiceList,synthesisAll:synthesisAll)
 //
             let filters = videoStickers.map { sticker in
                 PQMovieFilter(movieSticker: sticker)
             }
+//<<<<<<< HEAD
             //add by ak 如果有字幕创建字幕 filter
 //            var filters:[PQBaseFilter] = Array.init()
 //            for sticker in videoStickers {
@@ -163,10 +223,12 @@ public class BFRecordExport {
 //                }
 //            }
             exporter = PQCompositionExporter(asset: composition, videoComposition: nil, audioMix: audioMix, filters: filters, animationTool: nil, exportURL: outPutMP4URL)
+ 
+
             
-            let asset = data?.first?.baseMaterial
+//            let asset = data?.first?.baseMaterial // 可能为空
 
-            let size = getVideoSize(asset: asset!)
+            let size = UIScreen.main.bounds.size //getVideoSize(asset: asset!)
             var orgeBitRate = Int(size.width * size.height * 3)
             
             for stick in videoStickers {
@@ -181,8 +243,9 @@ public class BFRecordExport {
             }
             
             BFLog(message: "导出设置的码率为:\(orgeBitRate)")
+ 
             if exporter!.prepare(videoSize: size, videoAverageBitRate: orgeBitRate) {
-                exporter!.start(playeTimeRange: CMTimeRange(start: CMTime.zero, end: synthesisAll ? asset?.duration as! CMTime : composition.duration))
+                exporter!.start(playeTimeRange: CMTimeRange(start: CMTime.zero, end: synthesisAll ? CMTime(seconds: totalDuration, preferredTimescale: 100) : composition.duration))
             }
             exporter?.progressClosure = { [weak self] _, _, progress in
                 //            BFLog(message: "正片合成进度 \(progress * 100)%")
@@ -200,7 +263,7 @@ public class BFRecordExport {
                     cShowHUB(superView: nil, msg: ( outSeconds == 0) ? "合成失败请重试。" : "合成成功")
                     self?.exportCompletion?(nil, url)
 
-                }else{
+                } else {
                     let error = NSError(domain: "err", code: -1, userInfo: nil)
                     self?.exportCompletion?(error as Error, nil)
                     cShowHUB(superView: nil, msg: "导出失败")
@@ -211,8 +274,8 @@ public class BFRecordExport {
             }
         } else {
             // 没有处理,直接copy原文件
-            if let ass = data?.first?.baseMaterial{
-                self.exportCompletion?(nil, ass.url)
+            if let localPath = data?.first?.localPath{
+                self.exportCompletion?(nil, URL(fileURLWithPath: localPath))
             }
         }
 
@@ -254,7 +317,7 @@ extension BFRecordExport {
             }
             sticker.volumeGain = 50
             totalDuration = max(totalDuration, sticker.duration)
-            tempParameters += PQVideoEditViewModel.dealWithMaterialTrack(stickerModel: sticker, composition: composition)
+            tempParameters += PQPlayerViewModel.dealWithMaterialTrack(stickerModel: sticker, composition: composition)
         }
         if let voices = audios {
             if synthesisAll {
@@ -286,7 +349,7 @@ extension BFRecordExport {
             sticker.duration = duration
             sticker.locationPath = model.wavFilePath
             sticker.volumeGain = 100 //Float64(model.volume)
-            tempParameters += PQVideoEditViewModel.dealWithMaterialTrack(stickerModel: sticker, composition: composition)
+            tempParameters += PQPlayerViewModel.dealWithMaterialTrack(stickerModel: sticker, composition: composition)
             totalDur += duration
         }
 
@@ -309,7 +372,7 @@ extension BFRecordExport {
             sticker.duration = sticker.aptDuration
             sticker.locationPath = model.wavFilePath
             sticker.volumeGain = 100 //Float64(model.volume)
-            tempParameters += PQVideoEditViewModel.dealWithMaterialTrack(stickerModel: sticker, composition: composition)
+            tempParameters += PQPlayerViewModel.dealWithMaterialTrack(stickerModel: sticker, composition: composition)
         }
         
         return tempParameters

+ 91 - 15
BFRecordScreenKit/Classes/BFRecordItemModel.swift

@@ -6,44 +6,120 @@
 //
 
 import Foundation
-
-import BFFramework
+import Photos
+import BFMediaKit
+import BFCommonKit
 
 struct SplitRecordRange {
     var isRecord:Bool = false
     var range:CMTimeRange
+    var index:Int
 }
 
 public class BFRecordItemModel: NSObject {
-    var baseMaterial : AVURLAsset?
-    var dealedDurationRanges = [SplitRecordRange]()
-    public var voiceStickers = [PQVoiceModel]()
-    public var videoStickers = [PQEditVisionTrackMaterialsModel]()
-    public var imageStickers = [PQEditVisionTrackMaterialsModel]()
-    public var titleStickers = [PQEditSubTitleModel]()
+//    var baseMaterial : AVURLAsset?
+    var localPath : String?
+    var materialDuraion: Double = 0.0
+    var fetchCoverImg : ((UIImage)->Void)?
+    var fetchAVUrlAsset : ((AVURLAsset)->Void)?
+    var fetchPlayItem : ((AVPlayerItem)->Void)?
+    var dealedDurationRanges = [SplitRecordRange]()                     // 录音切割的时间区间,合成导出时计算
+    public var voiceStickers = [PQVoiceModel]()                         //
+    public var videoStickers = [PQEditVisionTrackMaterialsModel]()      // 合成导出时计算
+    public var imageStickers = [PQEditVisionTrackMaterialsModel]()      //
+    public var titleStickers = [PQEditSubTitleModel]()                  // 字幕贴纸
+    public var coverImg : UIImage?
     public var index = 0
     public var width = 0
     public var height = 0
     
-    func generationTimeRanges() {
+    func initOriginData(phasset:PHAsset){
+        width = phasset.pixelWidth
+        height = phasset.pixelHeight
+        
+        fetchCoverImage(phasset)
+        fetchPlayItem(phasset)
+        fetchAVUrlAsset(phasset)
+        
+    }
+    
+    func fetchCoverImage(_ phasset:PHAsset) {
+        let option = PHImageRequestOptions()
+        option.isNetworkAccessAllowed = true //允许下载iCloud的图片
+        option.resizeMode = .fast
+        option.deliveryMode = .highQualityFormat
+        PHImageManager.default().requestImage(for: phasset,
+                                       targetSize: CGSize(width: width, height: height),
+                                      contentMode: .aspectFit,
+                                          options: option)
+        { [weak self] (image, nil) in
+             // 设置首帧/封面
+            if image != nil {
+                self?.fetchCoverImg?(image!)
+                self?.coverImg = image
+            }
+        }
+    }
+
+    func fetchPlayItem(_ phasset:PHAsset) {
+        let options = PHVideoRequestOptions()
+        options.isNetworkAccessAllowed = true
+        options.deliveryMode = .automatic
+        if phasset.mediaType == .image {
+            
+        }else if phasset.mediaType == .video{
+            PHImageManager.default().requestPlayerItem(forVideo:phasset, options: options, resultHandler: { [weak self] playerItem, info in
+                
+                guard let item = playerItem else {
+                    cShowHUB(superView: nil, msg: "视频获取失败:\(self?.index ?? 0)")
+                    return
+                }
+                self?.fetchPlayItem?(item)
+            })
+        }
+    }
+    
+    func fetchAVUrlAsset(_ phasset:PHAsset){
+        let options = PHVideoRequestOptions()
+        options.isNetworkAccessAllowed = true
+        options.deliveryMode = .automatic
+
+        PHCachingImageManager().requestAVAsset(forVideo: phasset, options: options, resultHandler: {[weak self] (asset: AVAsset?, audioMix: AVAudioMix?, info) in
+            if let urlAsset = asset as? AVURLAsset {
+                self?.materialDuraion = urlAsset.duration.seconds
+                self?.localPath = ((urlAsset.url.absoluteString).removingPercentEncoding)?.replacingOccurrences(of: "file://", with: "")
+                self?.fetchAVUrlAsset?(urlAsset)
+            }
+        })
+    }
+    
+    func generationTimeRanges(needSort:Bool = false) {
         
         dealedDurationRanges.removeAll()
         
         var start : Double = 0
-        for model in voiceStickers {
+        
+        var list: [PQVoiceModel]
+        list = voiceStickers.sorted { model1, model2 in
+            model1.startTime < model2.startTime
+        }
+        
+        for model in list {
+            
             if model.startTime > start{
                 //
                 let range = CMTimeRange(start: CMTime(seconds: start, preferredTimescale: 100), duration: CMTime(seconds: model.startTime - start, preferredTimescale: 100))
-                dealedDurationRanges.append(SplitRecordRange(isRecord: false, range: range))
+                dealedDurationRanges.append(SplitRecordRange(isRecord: false, range: range, index: -1))
             }
 
+            let ind = voiceStickers.firstIndex(of: model)
             let range = CMTimeRange(start: CMTime(seconds: model.startTime, preferredTimescale: 100), end: CMTime(seconds: model.endTime, preferredTimescale: 100))
-            dealedDurationRanges.append(SplitRecordRange(isRecord: true, range: range))
+            dealedDurationRanges.append(SplitRecordRange(isRecord: true, range: range, index: ind ?? -1))
             start = model.endTime
         }
-        if start < baseMaterial?.duration.seconds ?? 0 {
-            let range = CMTimeRange(start: CMTime(seconds: start, preferredTimescale: 100), end: CMTime(seconds: baseMaterial?.duration.seconds ?? 0, preferredTimescale: 100))
-            dealedDurationRanges.append(SplitRecordRange(isRecord: false, range: range))
+        if start < materialDuraion {
+            let range = CMTimeRange(start: CMTime(seconds: start, preferredTimescale: 100), end: CMTime(seconds: materialDuraion, preferredTimescale: 100))
+            dealedDurationRanges.append(SplitRecordRange(isRecord: false, range: range, index: -1))
         }
         
     }

+ 3 - 3
BFRecordScreenKit/Classes/BFVoiceRecordManager.swift

@@ -7,8 +7,7 @@
 
 import Foundation
 import BFCommonKit
-import BFFramework
-import BFVideoEditKit
+import BFMediaKit
 
 class BFVoiceRecordManager {
     
@@ -22,7 +21,8 @@ class BFVoiceRecordManager {
     var beginRecordTime:Date = Date()
     var voiceModel : PQVoiceModel?
     
-    /// 录制音频
+    /// 录制音频。 index初衷是记录录音顺序,废弃了
+    ///
     func startRecord(index:Int){
         
         recorderFilePath = exportAudiosDirectory

+ 65 - 82
BFRecordScreenKit/Classes/RecordScreen/Controller/BFRecordScreenController.swift

@@ -7,13 +7,13 @@
 //
 
 import Foundation
-import BFUIKit
 import GPUImage
 import Photos
-import BFCommonKit
-import BFFramework
 import UIKit
-
+import BFCommonKit
+import BFMediaKit
+import BFCommonKit
+import BFUIKit
 
 struct WithDrawModel {
     var type:Int   // 0:拖动; 1:预览播放暂停 2: 录音结束
@@ -53,8 +53,7 @@ public class BFRecordScreenController: BFBaseViewController {
         }
     }
     var currentAssetProgress : CMTime = .zero   // 当前素材播放的进度
-    // 视频素材
-    public var avasset:AVURLAsset?
+
     
     //    public var recordList:[PQVoiceModel] = [PQVoiceModel]()
     
@@ -91,19 +90,10 @@ public class BFRecordScreenController: BFBaseViewController {
             if let sself = self, let model = model, FileManager.default.fileExists(atPath: model.wavFilePath ?? ""){
                 // 加入到语音数组里
                 // TODO: 原逻辑要删除新录音后边的数据, 新逻辑是覆盖则删除
-                var index = sself.itemModels[sself.currItemModelIndex].voiceStickers.count - 1
-                while index >= 0{
-                    let m = sself.itemModels[sself.currItemModelIndex].voiceStickers[index]
-                    
-                    // 找到比新录的早的录音,跳出判断
-                    if model.startTime >= m.endTime {
-                        break
-                    }
-                    
-                    index -= 1
+                for (i, m) in sself.itemModels[sself.currItemModelIndex].voiceStickers.enumerated(){
                     if model.endTime > m.startTime && model.endTime <= m.endTime
                         || model.startTime <= m.startTime && model.startTime > m.endTime{
-                        sself.itemModels[sself.currItemModelIndex].voiceStickers.remove(at: index+1)
+                        sself.itemModels[sself.currItemModelIndex].voiceStickers.remove(at: i)
                         continue
                     }
                 }
@@ -282,6 +272,13 @@ public class BFRecordScreenController: BFBaseViewController {
         return subtitleLabel
         
     }()
+    //音量设置
+    lazy var audioSettingView:BFAudioSettingView = {
+        let audioSettingView = BFAudioSettingView.init(frame: CGRect.init(x: 0, y: 0, width: cScreenWidth, height: cScreenHeigth))
+        audioSettingView.isHidden = true
+        return audioSettingView
+    }()
+    
     
     //录音识别文字
     var speechTranscriberUtil:PQSpeechTranscriberUtil?
@@ -302,7 +299,7 @@ public class BFRecordScreenController: BFBaseViewController {
                 }
                 sself.isDragingProgressSlder = true
 
-                BFLog(1, message: "drag 进行中")
+//                BFLog(1, message: "drag 进行中")
  
                 sself.changeProgress(progress: process)
             }
@@ -370,6 +367,7 @@ public class BFRecordScreenController: BFBaseViewController {
         view.addSubview(soundSettingBtn)
         view.addSubview(subtitleSettingView)
         view.addSubview(subtitleLabel)
+        view.addSubview(audioSettingView)
         
         
         bottomeView.addSubview(progreddL)
@@ -388,6 +386,11 @@ public class BFRecordScreenController: BFBaseViewController {
             BFLog(message: "新录制完成::::\(materialsModel?.locationPath ?? "")")
         }
         
+        audioSettingView.callBack = {[weak self] haveSpeak,  noHaveSpeak in
+            
+            BFLog(message: "haveSpeak is\(haveSpeak),noHaveSpeak is\(noHaveSpeak)")
+        }
+        
         
         //字幕设置回调
         //设置默认值
@@ -599,6 +602,7 @@ public class BFRecordScreenController: BFBaseViewController {
     //声音设置
     @objc func soundSetting(){
         BFLog(message: "设置声音")
+        audioSettingView.isHidden = false
         
     }
     
@@ -607,19 +611,11 @@ public class BFRecordScreenController: BFBaseViewController {
         BFLog(1, message: "start \(UIControl.Event.touchDown)")
         
         let point = progressThumV.progressView.contentOffset
-        progressThumV.progressView .setContentOffset(point, animated: false)
+        progressThumV.progressView.setContentOffset(point, animated: false)
         
         isRecording = true
         pause()
-        
-        events.append(WithDrawModel(type: 2, timestamp: self.currentAssetProgress.seconds))
-        
-        let model = PQVoiceModel()
-        model.startTime = self.currentAssetProgress.seconds
-        model.volume = 100
-        
-        //        recorderManager.voiceModel = model
-        //        recorderManager.startRecord(index: recordList.count)
+
         movie?.startProcessing()
         assetPlayer?.volume = 0
         assetPlayer?.play()
@@ -628,19 +624,29 @@ public class BFRecordScreenController: BFBaseViewController {
         if(!avatarView.isHidden){
             avatarView.beginRecord()
         }
-        
+                
+        let model = PQVoiceModel()
+        model.startTime = self.currentAssetProgress.seconds
+        model.volume = 100
         recorderManager.voiceModel = model
         recorderManager.startRecord(index: 1)
+        
+        // 添加撤销记录点
+        events.append(WithDrawModel(type: 2, timestamp: model.startTime))
  
 //        movie?.startProcessing()
 //        assetPlayer?.volume = 0
  
         assetPlayer?.play()
         
-        DispatchQueue.global().async {
-            self.speechTranscriberUtil?.delegate = self
-            self.speechTranscriberUtil?.startTranscriber()
-            self.speechTranscriberUtil?.currItemModelIndex = Int32(self.currItemModelIndex)
+
+        DispatchQueue.global().async {[weak self] in
+            guard let sself = self else {
+                return
+            }
+            sself.speechTranscriberUtil?.delegate = sself
+            sself.speechTranscriberUtil?.startTranscriber()
+            sself.speechTranscriberUtil?.currItemModelIndex = Int32(sself.currItemModelIndex)
         }
  
     }
@@ -688,7 +694,8 @@ public class BFRecordScreenController: BFBaseViewController {
             }else {
             }
             events.removeLast()
-            if let dur = itemModels[currItemModelIndex].baseMaterial?.duration.seconds,dur > 0 {
+            let dur = itemModels[currItemModelIndex].materialDuraion
+            if dur > 0 {
                 changeProgress(progress: Float(jumpTime / dur))
                 isDragingProgressSlder = false
                 currentPlayRecordIndex = -1
@@ -929,62 +936,38 @@ public class BFRecordScreenController: BFBaseViewController {
             for (index, asset) in self.assets.enumerated() {
                 let itemModel = BFRecordItemModel()
                 itemModel.index = 0
-                itemModel.width = asset.pixelWidth
-                itemModel.height = asset.pixelHeight
-                
-                itemModels.append(itemModel)
-                
-                let options = PHVideoRequestOptions()
-                options.isNetworkAccessAllowed = true
-                options.deliveryMode = .automatic
-                
-                PHImageManager.default().requestPlayerItem(forVideo:asset, options: options, resultHandler: { [weak self] playerItem, info in
-                    
-                    guard let item = playerItem else {
-                        cShowHUB(superView: nil, msg: "视频获取失败")
-                        return
+                itemModel.initOriginData(phasset: asset)
+                if index == 0 {
+                    itemModel.fetchCoverImg = {[weak self] img in
+                        self?.setCoverImage(img: img)
                     }
-                    if index == 0 {
+                    itemModel.fetchAVUrlAsset = { [weak self] urlAsset in
+                        DispatchQueue.main.async {[weak self] in
+                            self?.progressThumV.videoAsset = urlAsset
+                            self?.progressThumV.isHidden = false
+                        }
+                    }
+                    itemModel.fetchPlayItem = { [weak self] item in
                         self?.setAudioPlay(item: item)
                         self?.setVideoPlay(item: item)
                     }
-                })
- 
-                let option = PHImageRequestOptions()
-                option.isNetworkAccessAllowed = true //允许下载iCloud的图片
-                option.resizeMode = .fast
-                option.deliveryMode = .highQualityFormat
-                PHImageManager.default().requestImage(for: asset,
-                                               targetSize: self.view.bounds.size,
-                                              contentMode: .aspectFit,
-                                                  options: option)
-                { (image, nil) in
-                     // 设置首帧/封面
-                    if image != nil {
-                        let pic = GPUImagePicture(image: image)
-                        let filet = GPUImageFilter()
-                        pic?.addTarget(filet)
-                        filet.addTarget(self.playView)
-                        pic?.processImage()
-                    }
                 }
-
+                itemModels.append(itemModel)
                 
-                PHCachingImageManager().requestAVAsset(forVideo: asset, options: options, resultHandler: {[weak self] (asset: AVAsset?, audioMix: AVAudioMix?, info) in
-                    if let urlasset = asset as? AVURLAsset {
-                        self?.avasset = urlasset
-                        itemModel.baseMaterial = urlasset
-                        DispatchQueue.main.async {[weak self] in
-                            self?.progressThumV.videoAsset = urlasset
-                            self?.progressThumV.isHidden = false
-                        }
-                    }
-                })
             }
         }
         
     }
     
+    func setCoverImage(img:UIImage) {
+        if let pic = GPUImagePicture(image: img) {
+            let filter = GPUImageFilter()
+            pic.addTarget(filter)
+            filter.addTarget(self.playView)
+            pic.processImage()
+        }
+    }
+    
     func setVideoPlay(item:AVPlayerItem){
         if movie != nil {
             cleanMovieTarget()
@@ -1016,7 +999,7 @@ public class BFRecordScreenController: BFBaseViewController {
                 if CMTimeGetSeconds(item.duration) > 0 {
                     DispatchQueue.main.async { [weak self] in
                         self?.progreddL.text = String(format: "%@", CMTimeGetSeconds(time).formatDurationToHMS())
-                        let su = !(self?.isDragingProgressSlder ?? false) || !(self?.isRecording ?? false && self?.isNormalPlaying ?? false)
+                        let su = !(self?.isDragingProgressSlder ?? false) || (self?.isRecording ?? false && self?.isNormalPlaying ?? false)
                         if su{
                             self?.progressThumV.progress = time.seconds
                         }
@@ -1086,8 +1069,8 @@ public class BFRecordScreenController: BFBaseViewController {
                 vv.removeFromSuperview()
             }
             
-            
-            if let totalDur = sself.itemModels[sself.currItemModelIndex].baseMaterial?.duration.seconds, totalDur > 0, sself.itemModels[sself.currItemModelIndex].voiceStickers.count > 0 {
+            let totalDur = sself.itemModels[sself.currItemModelIndex].materialDuraion
+            if  totalDur > 0, sself.itemModels[sself.currItemModelIndex].voiceStickers.count > 0 {
                 let width = sself.progressThumV.progessIndicateBackV.width
                 let height = sself.progressThumV.progessIndicateBackV.height
                 sself.itemModels[sself.currItemModelIndex].voiceStickers.forEach { model in

+ 15 - 0
BFRecordScreenKit/Classes/RecordScreen/Controller/BFRecordScreenImageController.swift

@@ -0,0 +1,15 @@
+//
+//  BFRecordScreenImageController.swift
+//  BFRecordScreenKit
+//
+//  Created by 胡志强 on 2021/12/14.
+//
+
+import Foundation
+
+class BFRecordScreenImageController: BFRecordScreenController {
+    override func startRecord() {
+        super.startRecord()
+        
+    }
+}

+ 15 - 0
BFRecordScreenKit/Classes/RecordScreen/Controller/BFRecordScreenVideoController.swift

@@ -0,0 +1,15 @@
+//
+//  BFRecordScreenVideoController.swift
+//  BFRecordScreenKit
+//
+//  Created by 胡志强 on 2021/12/14.
+//
+
+import Foundation
+
+class BFRecordScreenVideoController: BFRecordScreenController {
+    override func startRecord() {
+        super.startRecord()
+        
+    }
+}

+ 140 - 0
BFRecordScreenKit/Classes/RecordScreen/View/BFAudioSettingView.swift

@@ -0,0 +1,140 @@
+//
+//  BFAudioSettingView.swift
+//  BFRecordScreenKit
+//
+//  Created by ak on 2021/12/15.
+//  功能:设置视频素材的音量
+
+import Foundation
+import BFMediaKit
+import BFCommonKit
+import BFUIKit
+
+typealias BFAudioSettingViewCallBack = (_ haveSpeak: Float,_ noHaveSpeak:Float) -> Void
+
+class BFAudioSettingView: UIView {
+
+    var callBack: BFAudioSettingViewCallBack?
+    
+    
+    // 标题
+    public lazy var haveSpeakLab: UILabel = {
+        let haveSpeakLab = UILabel()
+        haveSpeakLab.font = UIFont.boldSystemFont(ofSize: 16)
+        haveSpeakLab.textAlignment = .left
+        haveSpeakLab.text = "说话时 视频音量"
+        haveSpeakLab.textColor = .white
+        haveSpeakLab.backgroundColor = .clear
+        return haveSpeakLab
+    }()
+    
+    //有录音
+    lazy var haveSpeakSlider: BFUISlider = {
+        let haveSpeakSlider = BFUISlider()
+        let thbImage = UIImage.moduleImage(named: BFConfig.shared.silderPinUsedImageName, moduleName: "BFFramework", isAssets: false)
+        haveSpeakSlider.setMinimumTrackImage(thbImage, for: .normal)
+        haveSpeakSlider.setMaximumTrackImage(thbImage, for: .normal)
+        haveSpeakSlider.setThumbImage(thbImage, for: .highlighted)
+        haveSpeakSlider.setThumbImage(thbImage, for: .normal)
+        haveSpeakSlider.maximumTrackTintColor = UIColor.hexColor(hexadecimal: "#E6E8E8")
+        haveSpeakSlider.minimumTrackTintColor = UIColor.hexColor(hexadecimal: BFConfig.shared.styleColor.rawValue)
+        haveSpeakSlider.tag = 10
+//        speechSlidView.addTarget(self, action: #selector(sliderTouchEnded(sender:)), for: .touchUpInside)
+        haveSpeakSlider.maximumValue = 100
+        haveSpeakSlider.minimumValue = 0
+        haveSpeakSlider.isMovePoint = false
+        haveSpeakSlider.valueTextColor = UIColor.hexColor(hexadecimal: BFConfig.shared.styleColor.rawValue)
+        haveSpeakSlider.value = 0.0
+
+        return haveSpeakSlider
+    }()
+    
+    // 标题
+    public lazy var noSpeakLab: UILabel = {
+        let noSpeakLab = UILabel()
+        noSpeakLab.font = UIFont.boldSystemFont(ofSize: 16)
+        noSpeakLab.textAlignment = .left
+        noSpeakLab.text = "没说话时 视频音量"
+        noSpeakLab.textColor = .white
+        return noSpeakLab
+    }()
+    
+    lazy var noSpeakSlider: BFUISlider = {
+        let noSpeakSlider = BFUISlider()
+        let thbImage = UIImage.moduleImage(named: BFConfig.shared.silderPinUsedImageName, moduleName: "BFFramework", isAssets: false)
+        noSpeakSlider.setMinimumTrackImage(thbImage, for: .normal)
+        noSpeakSlider.setMaximumTrackImage(thbImage, for: .normal)
+        noSpeakSlider.setThumbImage(thbImage, for: .highlighted)
+        noSpeakSlider.setThumbImage(thbImage, for: .normal)
+        noSpeakSlider.maximumTrackTintColor = UIColor.hexColor(hexadecimal: "#E6E8E8")
+        noSpeakSlider.minimumTrackTintColor = UIColor.hexColor(hexadecimal: BFConfig.shared.styleColor.rawValue)
+        noSpeakSlider.tag = 20
+        noSpeakSlider.isMovePoint = false
+//        speechSlidView.addTarget(self, action: #selector(sliderTouchEnded(sender:)), for: .touchUpInside)
+        noSpeakSlider.maximumValue = 100
+        noSpeakSlider.minimumValue = 0
+        noSpeakSlider.valueTextColor = UIColor.hexColor(hexadecimal: BFConfig.shared.styleColor.rawValue)
+        noSpeakSlider.value = 100
+
+        return noSpeakSlider
+    }()
+
+    override init(frame: CGRect) {
+        super.init(frame: frame)
+        
+        self.backgroundColor = UIColor.clear
+        addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(hidden)))
+        
+        let backView = UIView.init()
+        backView.backgroundColor = .black
+        addSubview(backView)
+        backView.snp.makeConstraints { make in
+            make.right.equalTo(self.snp.right)
+            make.bottom.equalTo(self.snp.bottom)
+            make.width.equalTo(cScreenWidth)
+            make.height.equalTo(220)
+        }
+ 
+        
+        backView.addSubview(haveSpeakSlider)
+        backView.addSubview(noSpeakSlider)
+        backView.addSubview(haveSpeakLab)
+        backView.addSubview(noSpeakLab)
+        
+        
+        haveSpeakLab.snp.makeConstraints { make in
+            make.left.equalToSuperview().offset(16)
+            make.right.equalToSuperview().offset(-16)
+            make.top.equalToSuperview().offset(25)
+        }
+        haveSpeakSlider.snp.makeConstraints { make in
+            make.left.equalToSuperview().offset(16)
+            make.right.equalToSuperview().offset(-16)
+            make.top.equalTo(haveSpeakLab).offset(24)
+        }
+        
+        noSpeakLab.snp.makeConstraints { make in
+            make.left.equalToSuperview().offset(16)
+            make.right.equalToSuperview().offset(-16)
+            make.top.equalTo(haveSpeakSlider).offset(42)
+        }
+        noSpeakSlider.snp.makeConstraints { make in
+            make.left.equalToSuperview().offset(16)
+            make.right.equalToSuperview().offset(-16)
+            make.top.equalTo(noSpeakLab).offset(24)
+        }
+    }
+    
+    required init?(coder: NSCoder) {
+        fatalError("init(coder:) has not been implemented")
+    }
+    
+    @objc func hidden(){
+        self.isHidden = true
+        if(callBack != nil){
+            callBack!(haveSpeakSlider.value,noSpeakSlider.value)
+        }
+    }
+    
+}
+

+ 3 - 2
BFRecordScreenKit/Classes/RecordScreen/View/BFRecordAvatarView.swift

@@ -6,8 +6,9 @@
 //  功能:录制头像 ,生成多个 MP4 文件。
 
 import Foundation
-import BFFramework
-
+import BFCommonKit
+import BFMediaKit
+import BFUIKit
 
 //录制完成回调
 typealias recordEndCallBack = (_ isSucess: Bool,_ material: PQEditVisionTrackMaterialsModel?) -> Void

+ 2 - 1
BFRecordScreenKit/Classes/RecordScreen/View/BFSubtitleEditView.swift

@@ -6,8 +6,9 @@
 //
 
 import Foundation
+import BFCommonKit
 import BFUIKit
-import BFFramework
+import BFMediaKit
 
 typealias EditSubtitleDone = (_ text: String) -> Void
 

+ 2 - 1
BFRecordScreenKit/Classes/RecordScreen/View/BFSubtitleSettingView.swift

@@ -6,8 +6,9 @@
 //  功能:设置字幕操作面板
 
 import Foundation
-import BFFramework
+import BFMediaKit
 import BFCommonKit
+import BFUIKit
 
 typealias SubtitleSettingCallBack = (_ subtitileModel: PQEditSubTitleModel) -> Void
 

+ 23 - 21
BFRecordScreenKit/Classes/RecordScreen/ViewModel/BFRecordScreenViewModel.swift

@@ -6,10 +6,12 @@
 //
 
 import Foundation
-import BFFramework
+import BFMediaKit
 import ObjectMapper
 import RealmSwift
-import BFVideoEditKit
+import BFCommonKit
+import BFNetRequestKit
+
 public class BFRecordScreenViewModel:NSObject{
    
     /// 取文本转语言 token
@@ -63,25 +65,25 @@ public class BFRecordScreenViewModel:NSObject{
             voiceMaterials.type = "voice"
             voiceMaterials.duration = assert.duration.seconds * 1_000_000
             BFLog(message: "上传录音-开始上传录音")
-            PQVideoEditViewModel.uploadMatarialData(isBatchUpload: false, materialData: voiceMaterials) { _, _, _, _, _, _, matarialInfo, _ in
-                let materialType: String = "\(matarialInfo?["materialType"] ?? "")"
-                let localPath: String = "\(matarialInfo?["localPath"] ?? "")"
-                
-                BFLog(message: "上传录音-录音上传返回--\(String(describing: matarialInfo))")
-                if matarialInfo != nil, matarialInfo?.keys.contains("localPath") ?? false, materialType == StickerType.VOICE.rawValue && localPath.contains("_noise_") {
-                    BFLog(message: "上传录音-录音上传成功开始转化字幕")
-                    let materialId: String = "\(matarialInfo?["materialId"] ?? "")"
-                    let duration: Float64 = Float64("\(matarialInfo?["duration"] ?? "")") ?? 0
-                    PQVideoEditViewModel.transferAudioMaterialToTextData(Int64(materialId) ?? 0, dutation: duration) { _, _, subTitleList, _ in
-                        BFLog(message: "上传录音-字幕转化完成:\(subTitleList.count)")
- 
-                        if subTitleList.count > 0 {
-                    
-                        }
-                
-                    }
-                }
-            }
+//            PQVideoEditViewModel.uploadMatarialData(isBatchUpload: false, materialData: voiceMaterials) { _, _, _, _, _, _, matarialInfo, _ in
+//                let materialType: String = "\(matarialInfo?["materialType"] ?? "")"
+//                let localPath: String = "\(matarialInfo?["localPath"] ?? "")"
+//                
+//                BFLog(message: "上传录音-录音上传返回--\(String(describing: matarialInfo))")
+//                if matarialInfo != nil, matarialInfo?.keys.contains("localPath") ?? false, materialType == StickerType.VOICE.rawValue && localPath.contains("_noise_") {
+//                    BFLog(message: "上传录音-录音上传成功开始转化字幕")
+//                    let materialId: String = "\(matarialInfo?["materialId"] ?? "")"
+//                    let duration: Float64 = Float64("\(matarialInfo?["duration"] ?? "")") ?? 0
+//                    PQVideoEditViewModel.transferAudioMaterialToTextData(Int64(materialId) ?? 0, dutation: duration) { _, _, subTitleList, _ in
+//                        BFLog(message: "上传录音-字幕转化完成:\(subTitleList.count)")
+// 
+//                        if subTitleList.count > 0 {
+//                    
+//                        }
+//                
+//                    }
+//                }
+//            }
         }
         
         //        dispatchGroup.notify(queue: DispatchQueue.main) {

+ 4 - 8
Example/BFRecordScreenKit.xcodeproj/project.pbxproj

@@ -252,7 +252,6 @@
 			inputPaths = (
 				"${PODS_ROOT}/Target Support Files/Pods-BFRecordScreenKit_Example/Pods-BFRecordScreenKit_Example-frameworks.sh",
 				"${BUILT_PRODUCTS_DIR}/Alamofire/Alamofire.framework",
-				"${BUILT_PRODUCTS_DIR}/AliyunOSSiOS/AliyunOSSiOS.framework",
 				"${BUILT_PRODUCTS_DIR}/BFCommonKit/BFCommonKit.framework",
 				"${BUILT_PRODUCTS_DIR}/BFLogger/BFLogger.framework",
 				"${BUILT_PRODUCTS_DIR}/BFNetRequestKit/BFNetRequestKit.framework",
@@ -262,9 +261,9 @@
 				"${BUILT_PRODUCTS_DIR}/KeychainAccess/KeychainAccess.framework",
 				"${BUILT_PRODUCTS_DIR}/Kingfisher/Kingfisher.framework",
 				"${BUILT_PRODUCTS_DIR}/KingfisherWebP/KingfisherWebP.framework",
-				"${BUILT_PRODUCTS_DIR}/LMJHorizontalScrollText/LMJHorizontalScrollText.framework",
 				"${BUILT_PRODUCTS_DIR}/MGSwipeTableCell/MGSwipeTableCell.framework",
 				"${BUILT_PRODUCTS_DIR}/MJRefresh/MJRefresh.framework",
+				"${PODS_ROOT}/NuiSDK/nuisdk.framework",
 				"${BUILT_PRODUCTS_DIR}/ObjectMapper/ObjectMapper.framework",
 				"${BUILT_PRODUCTS_DIR}/Realm/Realm.framework",
 				"${BUILT_PRODUCTS_DIR}/RealmSwift/RealmSwift.framework",
@@ -276,7 +275,6 @@
 			name = "[CP] Embed Pods Frameworks";
 			outputPaths = (
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Alamofire.framework",
-				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AliyunOSSiOS.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/BFCommonKit.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/BFLogger.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/BFNetRequestKit.framework",
@@ -286,9 +284,9 @@
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/KeychainAccess.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Kingfisher.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/KingfisherWebP.framework",
-				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/LMJHorizontalScrollText.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MGSwipeTableCell.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MJRefresh.framework",
+				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/nuisdk.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ObjectMapper.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Realm.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RealmSwift.framework",
@@ -309,17 +307,15 @@
 			);
 			inputPaths = (
 				"${PODS_ROOT}/Target Support Files/Pods-BFRecordScreenKit_Example/Pods-BFRecordScreenKit_Example-resources.sh",
-				"${PODS_CONFIGURATION_BUILD_DIR}/BFFramework/BFFramework_Resources.bundle",
 				"${PODS_CONFIGURATION_BUILD_DIR}/BFMaterialKit/BFMaterialKit_Resources.bundle",
+				"${PODS_CONFIGURATION_BUILD_DIR}/BFMediaKit/BFMediaKit_Resources.bundle",
 				"${PODS_CONFIGURATION_BUILD_DIR}/BFRecordScreenKit/BFRecordScreenKit_Resources.bundle",
-				"${PODS_CONFIGURATION_BUILD_DIR}/BFVideoEditKit/BFVideoEditKit_Resources.bundle",
 			);
 			name = "[CP] Copy Pods Resources";
 			outputPaths = (
-				"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/BFFramework_Resources.bundle",
 				"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/BFMaterialKit_Resources.bundle",
+				"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/BFMediaKit_Resources.bundle",
 				"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/BFRecordScreenKit_Resources.bundle",
-				"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/BFVideoEditKit_Resources.bundle",
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			shellPath = /bin/sh;

+ 1 - 0
Example/BFRecordScreenKit/AppDelegate.swift

@@ -8,6 +8,7 @@
 
 import UIKit
 import BFMaterialKit
+import BFCommonKit
 
 @UIApplicationMain
 class AppDelegate: UIResponder, UIApplicationDelegate {

+ 5 - 3
Example/BFRecordScreenKit/IntroduceController.swift

@@ -19,12 +19,14 @@ class IntroduceController : BFBaseViewController {
         super.viewDidLoad()
         
         let vc = BFRecordScreenController()
-        vc.asset = asset
+        if asset != nil {
+            vc.assets = [asset!]
+        }
         vc.nextActionHandle = {
             DispatchQueue.main.async { [weak self] in
                 let controller = VideoExportController()
-                controller.export.voiceList = vc.recordList
-                controller.export.asset = vc.avasset
+//                controller.export.voiceList = vc.recordList
+//                controller.export.exporter?.assets = vc.avasset
                 self?.navigationController?.pushViewController(controller, animated: true)
             }
         }

+ 1 - 1
Example/BFRecordScreenKit/PhotoVideoListController.swift

@@ -12,7 +12,7 @@ import BFMaterialKit
 import UIKit
 import BFRecordScreenKit
 import Photos
-
+import BFCommonKit
 
 class PhotoVideoListController: BFBaseViewController {
     

+ 1 - 1
Example/BFRecordScreenKit/VideoExportController.swift

@@ -79,6 +79,6 @@ class VideoExportController: BFBaseViewController{
         view.addSubview(progressView)
         view.addSubview(progressL)
 
-        export.startExprot()
+        export.startExprot(synthesisAll: true)
     }
 }

+ 1 - 1
Example/BFRecordScreenKit/ViewController.swift

@@ -7,7 +7,7 @@
 //
 
 import UIKit
-import BFFramework
+import BFMediaKit
 import BFRecordScreenKit
 import BFMaterialKit
 

+ 5 - 15
Example/Podfile

@@ -12,50 +12,40 @@ target 'BFRecordScreenKit_Example' do
 #  pod 'BFNetRequestKit',       '0.2.3'
 #  pod 'BFUIKit',               '0.1.1'
 #  pod 'BFMaterialKit',         '0.1.6'
-#  pod 'BFFramework',           '1.0.7'
-#  pod 'BFVideoEditKit',        '0.1.0'
-#  pod 'BFAliyunNlsSDK-Swift',  '0.1.0'
 #  pod 'BFLogger',              '0.1.0'
+#  pod 'BFMediaKit',            '0.1.0'
 
 ## Pods-for-Archive(Jenkins)
   pod 'BFCommonKit',           :git => 'https://git.yishihui.com/iOS/BFCommonKit.git'
   pod 'BFNetRequestKit',       :git => 'https://git.yishihui.com/iOS/BFNetRequestKit.git'
   pod 'BFUIKit',               :git => 'https://git.yishihui.com/iOS/BFUIKit.git'
   pod 'BFMaterialKit',         :git => 'https://git.yishihui.com/iOS/BFMaterialKit.git'
-  pod 'BFFramework',           :git => 'https://git.yishihui.com/iOS/BFFramework.git'
-  pod 'BFVideoEditKit',        :git => 'https://git.yishihui.com/iOS/BFVideoEditKit.git'
-  pod 'BFAliyunNlsSDK-Swift',  :git => 'https://git.yishihui.com/iOS/BFAliyunNlsSDK-Swift.git'
   pod 'BFLogger',              :git => 'https://git.yishihui.com/iOS/BFLogger.git'
+  pod 'BFMediaKit',            :git => 'https://git.yishihui.com/iOS/BFMediaKit.git'
 
 ## ak:Pods-for-testing
 #  pod 'BFCommonKit',           :path => '/Users/ak/Desktop/TZFrameworks/BFCommonKit/'
 #  pod 'BFNetRequestKit',       :path => '/Users/ak/Desktop/TZFrameworks/BFNetRequestKit/'
 #  pod 'BFUIKit',               :path => '/Users/ak/Desktop/TZFrameworks/BFUIKit/'
 #  pod 'BFMaterialKit',         :path => '/Users/ak/Desktop/TZFrameworks/BFMaterialKit/'
-#  pod 'BFFramework',           :path => '/Users/ak/Desktop/TZFrameworks/BFFramework/'
-#  pod 'BFVideoEditKit',        :path => '/Users/ak/Desktop/TZFrameworks/BFVideoEditKit/'
-#  pod 'BFAliyunNlsSDK-Swift',  :path => '/Users/ak/Desktop/TZFrameworks/BFAliyunNlsSDK-Swift/'
 #  pod 'BFLogger',              :path => '/Users/ak/Desktop/TZFrameworks/BFLogger/'
+#  pod 'BFMediaKit',            :path => '/Users/ak/Desktop/TZFrameworks/BFMediaKit/'
 
 ## zq:Pods-for-testing
 #  pod 'BFCommonKit',           :path => '../BFCommonKit/'
 #  pod 'BFNetRequestKit',       :path => '../BFNetRequestKit/'
 #  pod 'BFUIKit',               :path => '../BFUIKit/'
 #  pod 'BFMaterialKit',         :path => '../BFMaterialKit/'
-#  pod 'BFFramework',           :path => '../BFFramework/'
-#  pod 'BFVideoEditKit',        :path => '../BFVideoEditKit/'
-#  pod 'BFAliyunNlsSDK-Swift',  :path => '../BFAliyunNlsSDK-Swift/'
 #  pod 'BFLogger',              :path => '../BFLogger/'
+#  pod 'BFMediaKit',            :path => '../BFMediaKit/'
 
 ## ww:Pods-for-testing
 #  pod 'BFCommonKit',            :path => '../../../BFCommonKit/Trunk'
 #  pod 'BFNetRequestKit',        :path => '../../../BFNetRequestKit/Trunk'
 #  pod 'BFUIKit',                :path => '../../../BFUIKit/Trunk'
 #  pod 'BFMaterialKit',          :path => '../../../BFMaterialKit/Trunk'
-#  pod 'BFFramework',            :path => '../../../BFFramework/Trunk'
-#  pod 'BFVideoEditKit',         :path => '../../../BFVideoEditKit/Trunk'
-#  pod 'BFAliyunNlsSDK-Swift',   :path => '../../../BFAliyunNlsSDK-Swift/Trunk'
 #  pod 'BFLogger',               :path => '../../../BFLogger/Trunk'
+#  pod 'BFMediaKit',             :path => '../../../BFMediaKit/Trunk'
   
   post_install do |installer|
     installer.pods_project.targets.each do |target|

+ 54 - 84
Example/Podfile.lock

@@ -1,27 +1,27 @@
 PODS:
   - Alamofire (5.4.4)
-  - AliyunOSSiOS (2.10.10)
-  - BFAliyunNlsSDK-Swift (0.1.0)
-  - BFCommonKit (1.5.1):
-    - BFCommonKit/BFBase (= 1.5.1)
-    - BFCommonKit/BFCategorys (= 1.5.1)
-    - BFCommonKit/BFConfig (= 1.5.1)
-    - BFCommonKit/BFDebug (= 1.5.1)
-    - BFCommonKit/BFEnums (= 1.5.1)
-    - BFCommonKit/BFUtility (= 1.5.1)
-  - BFCommonKit/BFBase (1.5.1):
-    - Alamofire (= 5.4.4)
-    - BFCommonKit/BFCategorys
-    - BFCommonKit/BFConfig
-    - BFCommonKit/BFUtility
-    - SnapKit (= 5.0.1)
-  - BFCommonKit/BFCategorys (1.5.1):
+  - BFCommonKit (1.5.2):
+    - BFCommonKit/BFCategorys (= 1.5.2)
+    - BFCommonKit/BFConfig (= 1.5.2)
+    - BFCommonKit/BFEnums (= 1.5.2)
+    - BFCommonKit/BFEnv (= 1.5.2)
+    - BFCommonKit/BFModels (= 1.5.2)
+    - BFCommonKit/BFProtocols (= 1.5.2)
+    - BFCommonKit/BFUtility (= 1.5.2)
+    - BFCommonKit/BFVendors (= 1.5.2)
+  - BFCommonKit/BFCategorys (1.5.2):
     - KingfisherWebP (= 1.3.0)
-  - BFCommonKit/BFConfig (1.5.1)
-  - BFCommonKit/BFDebug (1.5.1):
-    - BFCommonKit/BFCategorys
-  - BFCommonKit/BFEnums (1.5.1)
-  - BFCommonKit/BFUtility (1.5.1):
+  - BFCommonKit/BFConfig (1.5.2):
+    - BFCommonKit/BFEnums
+  - BFCommonKit/BFEnums (1.5.2)
+  - BFCommonKit/BFEnv (1.5.2)
+  - BFCommonKit/BFModels (1.5.2):
+    - BFCommonKit/BFEnums
+    - ObjectMapper (= 4.2.0)
+    - RealmSwift (= 10.7.6)
+  - BFCommonKit/BFProtocols (1.5.2):
+    - BFCommonKit/BFEnums
+  - BFCommonKit/BFUtility (1.5.2):
     - Alamofire (= 5.4.4)
     - BFCommonKit/BFCategorys
     - BFCommonKit/BFConfig
@@ -29,35 +29,31 @@ PODS:
     - Kingfisher (= 6.3.1)
     - KingfisherWebP (= 1.3.0)
     - Toast-Swift (= 5.0.1)
-  - BFFramework (1.0.9):
-    - AliyunOSSiOS (= 2.10.10)
-    - BFCommonKit
-    - BFMaterialKit
-    - BFNetRequestKit
-    - Bugly (= 2.5.90)
-    - LMJHorizontalScrollText (= 2.0.2)
-    - MJRefresh (= 3.7.2)
-    - ObjectMapper (= 4.2.0)
-    - TXLiteAVSDK_Player (= 9.3.10765)
-    - WechatOpenSDK-Swift (= 1.8.7.1)
+  - BFCommonKit/BFVendors (1.5.2)
   - BFLogger (0.1.0):
     - BFCommonKit
     - BFUIKit
-  - BFMaterialKit (0.1.9):
+  - BFMaterialKit (0.2.0):
     - BFUIKit
-  - BFNetRequestKit (1.0.0):
+  - BFMediaKit (0.1.0):
+    - BFCommonKit
+    - NuiSDK (= 2.5.14)
+    - ObjectMapper (= 4.2.0)
+    - RealmSwift (= 10.7.6)
+  - BFNetRequestKit (1.0.1):
     - Alamofire (= 5.4.4)
   - BFRecordScreenKit (0.1.0):
     - BFCommonKit
-    - BFFramework
+    - BFMaterialKit
+    - BFMediaKit
+    - BFNetRequestKit
     - BFUIKit
-    - BFVideoEditKit
     - GPUImage
-  - BFUIKit (0.1.1):
+  - BFUIKit (0.1.2):
     - BFCommonKit
-    - BFUIKit/Comm (= 0.1.1)
-    - BFUIKit/Controller (= 0.1.1)
-    - BFUIKit/View (= 0.1.1)
+    - BFUIKit/Comm (= 0.1.2)
+    - BFUIKit/Controller (= 0.1.2)
+    - BFUIKit/View (= 0.1.2)
     - FDFullscreenPopGesture (= 1.1)
     - Kingfisher (~> 6.0)
     - MGSwipeTableCell (~> 1.0)
@@ -65,7 +61,7 @@ PODS:
     - RealmSwift (= 10.7.6)
     - SnapKit (~> 5.0)
     - SVProgressHUD (~> 2.0)
-  - BFUIKit/Comm (0.1.1):
+  - BFUIKit/Comm (0.1.2):
     - BFCommonKit
     - FDFullscreenPopGesture (= 1.1)
     - Kingfisher (~> 6.0)
@@ -74,7 +70,7 @@ PODS:
     - RealmSwift (= 10.7.6)
     - SnapKit (~> 5.0)
     - SVProgressHUD (~> 2.0)
-  - BFUIKit/Controller (0.1.1):
+  - BFUIKit/Controller (0.1.2):
     - BFCommonKit
     - FDFullscreenPopGesture (= 1.1)
     - Kingfisher (~> 6.0)
@@ -83,7 +79,7 @@ PODS:
     - RealmSwift (= 10.7.6)
     - SnapKit (~> 5.0)
     - SVProgressHUD (~> 2.0)
-  - BFUIKit/View (0.1.1):
+  - BFUIKit/View (0.1.2):
     - BFCommonKit
     - FDFullscreenPopGesture (= 1.1)
     - Kingfisher (~> 6.0)
@@ -92,14 +88,6 @@ PODS:
     - RealmSwift (= 10.7.6)
     - SnapKit (~> 5.0)
     - SVProgressHUD (~> 2.0)
-  - BFVideoEditKit (0.1.0):
-    - BFAliyunNlsSDK-Swift
-    - BFCommonKit
-    - BFFramework
-    - BFMaterialKit
-    - BFNetRequestKit
-    - BFUIKit
-  - Bugly (2.5.90)
   - FDFullscreenPopGesture (1.1)
   - GPUImage (0.1.7)
   - KeychainAccess (4.2.2)
@@ -116,9 +104,9 @@ PODS:
   - libwebp/mux (1.2.1):
     - libwebp/demux
   - libwebp/webp (1.2.1)
-  - LMJHorizontalScrollText (2.0.2)
   - MGSwipeTableCell (1.6.11)
-  - MJRefresh (3.7.2)
+  - MJRefresh (3.7.5)
+  - NuiSDK (2.5.14)
   - ObjectMapper (4.2.0)
   - Realm (10.7.6):
     - Realm/Headers (= 10.7.6)
@@ -128,94 +116,76 @@ PODS:
   - SnapKit (5.0.1)
   - SVProgressHUD (2.2.5)
   - Toast-Swift (5.0.1)
-  - TXLiteAVSDK_Player (9.3.10765)
-  - WechatOpenSDK-Swift (1.8.7.1)
 
 DEPENDENCIES:
-  - BFAliyunNlsSDK-Swift (from `../../../BFAliyunNlsSDK-Swift/Trunk`)
   - BFCommonKit (from `../../../BFCommonKit/Trunk`)
-  - BFFramework (from `../../../BFFramework/Trunk`)
   - BFLogger (from `../../../BFLogger/Trunk`)
   - BFMaterialKit (from `../../../BFMaterialKit/Trunk`)
+  - BFMediaKit (from `../../../BFMediaKit/Trunk`)
   - BFNetRequestKit (from `../../../BFNetRequestKit/Trunk`)
   - BFRecordScreenKit (from `../`)
   - BFUIKit (from `../../../BFUIKit/Trunk`)
-  - BFVideoEditKit (from `../../../BFVideoEditKit/Trunk`)
 
 SPEC REPOS:
   https://github.com/CocoaPods/Specs.git:
     - Alamofire
-    - AliyunOSSiOS
-    - Bugly
     - FDFullscreenPopGesture
     - GPUImage
     - KeychainAccess
     - Kingfisher
     - KingfisherWebP
     - libwebp
-    - LMJHorizontalScrollText
     - MGSwipeTableCell
     - MJRefresh
+    - NuiSDK
     - ObjectMapper
     - Realm
     - RealmSwift
     - SnapKit
     - SVProgressHUD
     - Toast-Swift
-    - TXLiteAVSDK_Player
-    - WechatOpenSDK-Swift
 
 EXTERNAL SOURCES:
-  BFAliyunNlsSDK-Swift:
-    :path: "../../../BFAliyunNlsSDK-Swift/Trunk"
   BFCommonKit:
     :path: "../../../BFCommonKit/Trunk"
-  BFFramework:
-    :path: "../../../BFFramework/Trunk"
   BFLogger:
     :path: "../../../BFLogger/Trunk"
   BFMaterialKit:
     :path: "../../../BFMaterialKit/Trunk"
+  BFMediaKit:
+    :path: "../../../BFMediaKit/Trunk"
   BFNetRequestKit:
     :path: "../../../BFNetRequestKit/Trunk"
   BFRecordScreenKit:
     :path: "../"
   BFUIKit:
     :path: "../../../BFUIKit/Trunk"
-  BFVideoEditKit:
-    :path: "../../../BFVideoEditKit/Trunk"
 
 SPEC CHECKSUMS:
   Alamofire: f3b09a368f1582ab751b3fff5460276e0d2cf5c9
-  AliyunOSSiOS: b8f1dfc229cd9abf68c8ee0cb245c2d66e00dd96
-  BFAliyunNlsSDK-Swift: 44049d173720cf858729d3b011c07e0c33c90fd2
-  BFCommonKit: fbebd7d46eaa7adaf5311aae2230b68ab5e99788
-  BFFramework: 2c44a33844e1a737c4f581b5c4949a9298867e5e
+  BFCommonKit: 86a8c8818c9430b01ee654ba60eb5cb8b863c0e6
   BFLogger: a286144e7dcdc20d3afc79deafed491aa0ac4306
-  BFMaterialKit: a10f33e7748689a3eeffff3b18df9c350241ba8d
-  BFNetRequestKit: 6b200205bd1a9491c04f5a3e95301d37a547f96b
-  BFRecordScreenKit: ebe9e2888a1a139274c807cf28171ca8112da9a4
-  BFUIKit: 982c86edec8883b3e6b60cb3ee1297eae23d9e4a
-  BFVideoEditKit: 7f86556c7604f221a591abfb3d80739be03448c3
-  Bugly: 88bc32c0acc6fef7b74d610f0319ee7560d6b9fe
+  BFMaterialKit: 0a15786e2a55587f1b2b4b74c0bff5321ebf3630
+  BFMediaKit: 9e2d138ae02e7d7f15425561de527a5bd470040b
+  BFNetRequestKit: 1d074023eafe7c272fab4ed3a608e685902235d0
+  BFRecordScreenKit: 73b1e0f58051bb6b70a9f88546884ea30274e57f
+  BFUIKit: f209190fb92c8f9050554ac5950a2e4852e8a481
   FDFullscreenPopGesture: a8a620179e3d9c40e8e00256dcee1c1a27c6d0f0
   GPUImage: 733a5f0fab92df9de1c37ba9df520a833ccb406d
   KeychainAccess: c0c4f7f38f6fc7bbe58f5702e25f7bd2f65abf51
   Kingfisher: 016c8b653a35add51dd34a3aba36b580041acc74
   KingfisherWebP: dec17a5eb1af2658791bde1f93ae9a853678f826
   libwebp: 98a37e597e40bfdb4c911fc98f2c53d0b12d05fc
-  LMJHorizontalScrollText: ebc9b908db297f603c5b98c9b4e5f4582f5a14b8
   MGSwipeTableCell: b804e4e450dee439c42250be90bd50458bf67fce
-  MJRefresh: 30997d30b347c8e9508a4db11e3a690da0c9b85a
+  MJRefresh: fdf5e979eb406a0341468932d1dfc8b7f9fce961
+  NuiSDK: 96e2a2acc66b6404bc794f2c4702ce0278edcd7c
   ObjectMapper: 1eb41f610210777375fa806bf161dc39fb832b81
   Realm: ed860452717c8db8f4bf832b6807f7f2ce708839
   RealmSwift: e31c4ddbcc42ac879313d656b86f9ca539f6f4f4
   SnapKit: 97b92857e3df3a0c71833cce143274bf6ef8e5eb
   SVProgressHUD: 1428aafac632c1f86f62aa4243ec12008d7a51d6
   Toast-Swift: 9b6a70f28b3bf0b96c40d46c0c4b9d6639846711
-  TXLiteAVSDK_Player: 2b60edf893a8e82165a5e4b961a6cb347b10be4a
-  WechatOpenSDK-Swift: 18a8f7b12e745c30acc013f72a9f8a25aad6e216
 
-PODFILE CHECKSUM: 6d008d3366f807ead4b6cc60ddc20baa0eed54ac
+PODFILE CHECKSUM: b307bac2715a66d1435240fec184fdd98cf36e67
 
 COCOAPODS: 1.11.2