123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- //
- // BFRecordItemModel.swift
- // BFRecordScreenKit
- //
- // Created by 胡志强 on 2021/12/6.
- //
- import BFCommonKit
- import BFMediaKit
- import Foundation
- import Photos
- struct SplitRecordRange {
- var isRecord: Bool = false
- var range: CMTimeRange
- var index: Int
- }
- public class BFRecordItemModel: NSObject {
- // 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 playItem: AVPlayerItem? // 视频playerItem
- public var videoAsset: AVURLAsset? // 视频Asset
- public var mediaType: StickerType? // 素材类型
- public var progress: Double = 0 // 更新进度
- public var index = 0 // 素材index
- public var width = 0 // 素材宽
- public var height = 0 // 素材高
- func initOriginData(phasset: PHAsset) {
- width = phasset.pixelWidth
- height = phasset.pixelHeight
- if phasset.mediaType == .image {
- mediaType = .IMAGE
- } else if phasset.mediaType == .video {
- mediaType = .VIDEO
- }
- 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, _ in
- // 设置首帧/封面
- if image != nil {
- self?.coverImg = image
- self?.fetchCoverImg?(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, _ in
- guard let item = playerItem else {
- cShowHUB(superView: nil, msg: "视频获取失败:\(self?.index ?? 0)")
- return
- }
- self?.playItem = item
- 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?, _: AVAudioMix?, _) in
- if let videoAsset = asset as? AVURLAsset {
- self?.materialDuraion = videoAsset.duration.seconds
- self?.localPath = (videoAsset.url.absoluteString.removingPercentEncoding)?.replacingOccurrences(of: "file://", with: "")
- self?.videoAsset = videoAsset
- self?.fetchAVUrlAsset?(videoAsset)
- }
- })
- }
- func generationTimeRanges(needSort _: Bool = false) {
- dealedDurationRanges.removeAll()
- var start: Double = 0
- 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, 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, index: ind ?? -1))
- start = model.endTime
- }
- 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))
- }
- }
- }
|