使用 AVAudioEngine 重复播放音频文件
Posted
技术标签:
【中文标题】使用 AVAudioEngine 重复播放音频文件【英文标题】:Playing an audio file repeatedly with AVAudioEngine 【发布时间】:2015-04-15 15:10:09 【问题描述】:我正在使用 Swift 和 Xcode 6 开发 ios 应用程序。我想做的是使用 AVAudioEngine 播放音频文件,直到此时一切正常。但是我怎样才能不停地播放它,我的意思是,当它结束时它又重新开始呢?
这是我的代码:
/*==================== CONFIGURATES THE AVAUDIOENGINE ===========*/
audioEngine.reset() //Resets any previous configuration on AudioEngine
let audioPlayerNode = AVAudioPlayerNode() //The node that will play the actual sound
audioEngine.attachNode(audioPlayerNode) //Attachs the node to the audioengine
audioEngine.connect(audioPlayerNode, to: audioEngine.outputNode, format: nil) //Connects the applause playback node to the sound output
audioPlayerNode.scheduleFile(applause.applauseFile, atTime: nil, completionHandler: nil)
audioEngine.startAndReturnError(nil)
audioPlayerNode.play() //Plays the sound
在我说我应该为此使用 AVAudioPlayer 之前,我不能,因为以后我将不得不使用一些效果并同时播放三个音频文件,还要重复播放。
【问题讨论】:
【参考方案1】:我在另一个问题中找到了解决方案,@CarveDrone 提出并自动回答了这个问题,所以我刚刚复制了他使用的代码:
class aboutViewController: UIViewController
var audioEngine: AVAudioEngine = AVAudioEngine()
var audioFilePlayer: AVAudioPlayerNode = AVAudioPlayerNode()
override func viewDidLoad()
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let filePath: String = NSBundle.mainBundle().pathForResource("chimes", ofType: "wav")!
println("\(filePath)")
let fileURL: NSURL = NSURL(fileURLWithPath: filePath)!
let audioFile = AVAudioFile(forReading: fileURL, error: nil)
let audioFormat = audioFile.processingFormat
let audioFrameCount = UInt32(audioFile.length)
let audioFileBuffer = AVAudioPCMBuffer(PCMFormat: audioFormat, frameCapacity: audioFrameCount)
audioFile.readIntoBuffer(audioFileBuffer, error: nil)
var mainMixer = audioEngine.mainMixerNode
audioEngine.attachNode(audioFilePlayer)
audioEngine.connect(audioFilePlayer, to:mainMixer, format: audioFileBuffer.format)
audioEngine.startAndReturnError(nil)
audioFilePlayer.play()
audioFilePlayer.scheduleBuffer(audioFileBuffer, atTime: nil, options:.Loops, completionHandler: nil)
您唯一需要更改的是filePath
常量。这是原始答案的链接:Having AVAudioEngine repeat a sound
【讨论】:
请注意,将长文件读入缓冲区将需要很长时间才能加载。 scheduleFile 方法有效地将文件流式传输到播放器,立即开始。不幸的是它没有循环。 嗯,我刚刚将这段代码翻译成 Swift 5,但我在控制台中得到了沉默和几个kAudioUnitErr_TooManyFramesToProcess
...【参考方案2】:
Swift 5,感谢@Guillermo Barreiro
var audioEngine: AVAudioEngine = AVAudioEngine()
var audioFilePlayer: AVAudioPlayerNode = AVAudioPlayerNode()
override func viewDidLoad()
super. viewDidLoad()
guard let filePath: String = Bundle.main.path(forResource: "chimes", ofType: "wav") else return
print("\(filePath)")
let fileURL: URL = URL(fileURLWithPath: filePath)
guard let audioFile = try? AVAudioFile(forReading: fileURL) else return
let audioFormat = audioFile.processingFormat
let audioFrameCount = UInt32(audioFile.length)
guard let audioFileBuffer = AVAudioPCMBuffer(pcmFormat: audioFormat, frameCapacity: audioFrameCount) else return
do
try audioFile.read(into: audioFileBuffer)
catch
print("over")
let mainMixer = audioEngine.mainMixerNode
audioEngine.attach(audioFilePlayer)
audioEngine.connect(audioFilePlayer, to:mainMixer, format: audioFileBuffer.format)
try? audioEngine.start()
audioFilePlayer.play()
audioFilePlayer.scheduleBuffer(audioFileBuffer, at: nil, options:AVAudioPlayerNodeBufferOptions.loops)
【讨论】:
以上是关于使用 AVAudioEngine 重复播放音频文件的主要内容,如果未能解决你的问题,请参考以下文章
使用 AVAudioEngine 从 AVAudioPCMBuffer 播放音频