本文共 11843 字,大约阅读时间需要 39 分钟。
?????????????????????????????????????????????????????????????????????????????
?????????????????????????????????????????????????????????????beginFrame
???????endFrame
???????????seekFrame
????????????WQAudioEditModel
?????????????????????????????
class WQAudioEditModel: NSObject { var beginFrame: Int64! var endFrame: Int64! var seekFrame: Int64! var fileUrl: URL! var audioFile: AVAudioFile! var editAction: AudioEditActionEnum! class func model(bgFrame: Int64, edFrame: Int64, editAction: AudioEditActionEnum, fileUrl: URL) -> WQAudioEditModel { let model = WQAudioEditModel() model.beginFrame = bgFrame model.endFrame = edFrame model.seekFrame = bgFrame model.editAction = editAction model.fileUrl = fileUrl do { try model.audioFile = AVAudioFile.init(forReading: fileUrl) } catch { // ???????? } return model }}
?????????????????????????????????????????????????????????????
private func config() { self.editModelArray = NSMutableArray.init() let firstModel = WQAudioEditModel.model(bgFrame: 0, edFrame: 0, editAction: .none, fileUrl: self.defaultUrl) firstModel.endFrame = firstModel.audioFile.length self.editModelArray.add(firstModel)}
????????????????????????copyArray
???????????????????????????????????????????
func copyAction(firstFrame: Int64, endFrame: Int64) { self.copyArray = NSMutableArray.init() let cpLength = endFrame - firstFrame var realLoc: Int64 = 0 for model in self.editModelArray { let aeModel = model as! WQAudioEditModel let modelLength = aeModel.endFrame - aeModel.beginFrame if realLoc + modelLength > firstFrame { if realLoc + modelLength >= endFrame { let cpFirstFrame = firstFrame - realLoc + aeModel.beginFrame let cpEndFrame = cpFirstFrame + cpLength let cpModel = WQAudioEditModel.model(bgFrame: cpFirstFrame, edFrame: cpEndFrame, editAction: .copy, fileUrl: aeModel.fileUrl) self.copyArray.add(cpModel.reinitModel()) break } else if realLoc + modelLength < endFrame { let cpFirstFrame = firstFrame - realLoc + aeModel.beginFrame self.copyArray.add(WQAudioEditModel.model(bgFrame: cpFirstFrame, edFrame: aeModel.endFrame, editAction: .copy, fileUrl: aeModel.fileUrl)) let index = self.editModelArray.index(of: model) let lastArray = self.editModelArray.subarray(with: NSMakeRange(index + 1, self.editModelArray.count - index - 1)) for lastModel in lastArray { let lastM = lastModel as! WQAudioEditModel let lastMLength = lastM.endFrame - lastM.beginFrame if realLoc + lastMLength > endFrame { self.copyArray.add(WQAudioEditModel.model(bgFrame: lastM.beginFrame, edFrame: endFrame - realLoc + lastM.beginFrame, editAction: .copy, fileUrl: aeModel.fileUrl)) break } else { realLoc = realLoc + lastMLength self.copyArray.add(lastM.reinitModel()) } } break } } else { realLoc = modelLength + realLoc } }}
???????????????seekFrame
????????????????????????????????????????
func pasteAction(locFrame: Int64) { if self.copyArray.count > 0 { var realLoc: Int64 = 0 let forModel = NSArray.init(array: self.editModelArray) for model in forModel { let aeModel = model as! WQAudioEditModel let modelLength = aeModel.endFrame - aeModel.beginFrame if realLoc + modelLength > locFrame { let index = self.editModelArray.index(of: model) if realLoc == locFrame { let lastarray = self.editModelArray.subarray(with: NSMakeRange(index, self.editModelArray.count - index)) self.editModelArray.removeObjects(in: lastarray) self.editModelArray.addObjects(from: self.copyArray as! [Any]) self.editModelArray.addObjects(from: lastarray) } else { let newModel1 = WQAudioEditModel.model(bgFrame: aeModel.beginFrame, edFrame: locFrame - realLoc + aeModel.beginFrame, editAction: .none, fileUrl: aeModel.fileUrl) self.editModelArray.replaceObject(at: index, with: newModel1) let lastarray = self.editModelArray.subarray(with: NSMakeRange(index + 1, self.editModelArray.count - index - 1)) self.editModelArray.removeObjects(in: lastarray) let newModel2 = WQAudioEditModel.model(bgFrame: locFrame - realLoc + aeModel.beginFrame, edFrame: aeModel.endFrame, editAction: .none, fileUrl: aeModel.fileUrl) self.editModelArray.addObjects(from: self.copyArray as! [Any]) self.editModelArray.add(newModel2) self.editModelArray.addObjects(from: lastarray) } break } else if realLoc + modelLength == locFrame { let index = self.editModelArray.index(of: model) let lastarray = self.editModelArray.subarray(with: NSMakeRange(index + 1, self.editModelArray.count - index - 1)) self.editModelArray.removeObjects(in: lastarray) self.editModelArray.addObjects(from: self.copyArray as! [Any]) self.editModelArray.addObjects(from: lastarray) break } else { realLoc = realLoc + modelLength } } }}
??????????????????????????????????????????????????????????
func cutAction(firstFrame: Int64, endFrame: Int64) { self.copyAction(firstFrame: firstFrame, endFrame: endFrame) var realLoc: Int64 = 0 let forModel = NSArray.init(array: self.editModelArray) for model in forModel { let aeModel = model as! WQAudioEditModel let modelLength = aeModel.endFrame - aeModel.beginFrame if realLoc + modelLength > firstFrame { let index = self.editModelArray.index(of: model) if realLoc + modelLength >= endFrame { if realLoc == firstFrame { if realLoc + modelLength != endFrame { let newModel2 = WQAudioEditModel.model(bgFrame: endFrame - realLoc, edFrame: aeModel.endFrame, editAction: .none, fileUrl: aeModel.fileUrl) self.editModelArray.replaceObject(at: index, with: newModel2) } } else { let newModel1 = WQAudioEditModel.model(bgFrame: aeModel.beginFrame, edFrame: firstFrame - realLoc, editAction: .none, fileUrl: aeModel.fileUrl) self.editModelArray.replaceObject(at: index, with: newModel1) if realLoc + modelLength != endFrame { let newModel2 = WQAudioEditModel.model(bgFrame: endFrame - realLoc, edFrame: aeModel.endFrame, editAction: .none, fileUrl: aeModel.fileUrl) self.editModelArray.insert(newModel2, at: index + 1) } } break } else if realLoc + modelLength < endFrame { let cutFirstFrame = firstFrame - realLoc + aeModel.beginFrame let newFirstModel = WQAudioEditModel.model(bgFrame: aeModel.beginFrame, edFrame: cutFirstFrame, editAction: .none, fileUrl: aeModel.fileUrl) self.editModelArray.replaceObject(at: index, with: newFirstModel) let index = self.editModelArray.index(of: model) let lastArray = self.editModelArray.subarray(with: NSMakeRange(index + 1, self.editModelArray.count - index - 1)) for lastModel in lastArray { let lastM = lastModel as! WQAudioEditModel let lastMLength = lastM.endFrame - lastM.beginFrame if realLoc + lastMLength > endFrame { let newEndModel = WQAudioEditModel.model(bgFrame: endFrame - realLoc + lastM.beginFrame, edFrame: lastM.endFrame, editAction: .none, fileUrl: aeModel.fileUrl) let cutIndex = self.editModelArray.index(of: lastM) self.editModelArray.replaceObject(at: cutIndex, with: newEndModel) break } else { realLoc = realLoc + lastMLength self.editModelArray.remove(lastModel) } } break } } else { realLoc = realLoc + modelLength } }}
???????? AVAudioPlayerNode
???????????????????????????? 1024
????????????????????????? completionHandler
?????????????????????
open func scheduleSegment(_ file: AVAudioFile, startingFrame startFrame: AVAudioFramePosition, frameCount numberFrames: AVAudioFrameCount, at when: AVAudioTime?, completionHandler: AVAudioNodeCompletionHandler? = nil) { self.playerNode.scheduleSegment(file, startingFrame: startFrame, frameCount: numberFrames, at: when, completionHandler: completionHandler)}@objc private func playNoti(noti: Notification) { let model = noti.object as! WQAudioEditModel if self.playerNode.isPlaying == false { model.seekFrame = model.beginFrame NotificationCenter.default.removeObserver(self) if self.playFinishBlock != nil { self.playFinishBlock() } return } if model.seekFrame >= model.endFrame { let index = self.editModelArray.index(of: model) if index < self.editModelArray.count - 1 { model.seekFrame = model.beginFrame let nextModel = self.editModelArray.object(at: index + 1) as! WQAudioEditModel self.realScheduleSegment(fromFrame: nextModel.seekFrame, length: self.segLength, model: nextModel) } else { model.seekFrame = model.beginFrame NotificationCenter.default.removeObserver(self) if self.playFinishBlock != nil { self.playFinishBlock() } } } else if (model.seekFrame + self.segLength < model.endFrame) { self.realScheduleSegment(fromFrame: model.seekFrame, length: self.segLength, model: model) } else if (model.seekFrame + self.segLength >= model.endFrame) { self.realScheduleSegment(fromFrame: model.seekFrame, length: model.endFrame - model.seekFrame, model: model) }}
?????? AVAudioFile
??????????????????????????????????????????????
func beginSave() { var writeFile: AVAudioFile! = nil do { writeFile = try AVAudioFile.init(forWriting: URL.init(string: self.fileUrl)!, settings: [AVFormatIDKey:NSNumber.init(value: kAudioFormatLinearPCM), AVNumberOfChannelsKey:NSNumber.init(value: 2), AVSampleRateKey:NSNumber.init(value: self.actionTool.getSampleRate())]) } catch { // ???????? } if writeFile == nil { return } for model in self.editModelArray as! [WQAudioEditModel] { let buffer = AVAudioPCMBuffer.init(pcmFormat: model.audioFile.processingFormat, frameCapacity: AVAudioFrameCount(model.endFrame - model.beginFrame))! model.audioFile.framePosition = model.beginFrame do { try model.audioFile.read(into: buffer, frameCount: AVAudioFrameCount(model.endFrame - model.beginFrame)) } catch { // ?????? } do { try writeFile.write(from: buffer) } catch { // ?????? } } do { try self.editPlay.audioEngine.start() } catch { // ?????? }}
?????????????????????????????????????????? AVAudioFile
?AVAudioPlayerNode
? AVAudioEngine
??????????????????????????????????????????????????????
转载地址:http://rcrdz.baihongyu.com/