我正在尝试从Mac Cocoa应用程序播放mp3。使用AVAudioPlayer看起来非常简单。但这是行不通的。我已经上网查看了,发现的大多数问题都与播放器对象被释放有关,但是我不认为这是我的问题。播放器对象是持久性的,并响应成员函数调用。
我通过这样的URL创建AVAudioPlayer:
class Soundtrack:Bobject, AVAudioPlayerDelegate {
var player:AVAudioPlayer!
var volume:Float = 1.0
var pan:Float = 0.0
var rate:Float = 1.0
var numberOfLoops:Int = -1
var url:URL?
var reference = false
...
func setFile(_ url:URL) throws {
self.url = url
player = try AVAudioPlayer(contentsOf: url)
player.prepareToPlay()
print("player duration: \(player.duration)")
print("player settings: \(player.settings)")
player.play() // this is commented / uncommented out for testing
}
Soundtrack对象是我创建的对象,并在调用setFile函数之前将其添加到对象的持久层次结构中。网址指向创建音轨之前在桌面上浏览的文件,例如“ file:///Users/bob/Desktop/2_02_Cycle.mp3”。
如果如上所述,我立即调用player.play(),那么它将起作用。这首歌一直播放,直到我暂停为止。但是,如果我注释掉该play()并稍后再调用,例如通过按一个键,则它将无法播放。表示成功:
player.prepareToPlay()
let ok = player!.play(atTime:atTime)
print("play \(ok)")
此处“ ok”返回true。另外,如果我随着时间检查player.isPlaying的值,大约一秒钟左右(80-90帧),它也会返回TRUE,然后停止。但是我什么也没听到。检查播放器设置会报告持续时间为正确的175秒,并且所有速率/音量/声相信息也都是正确的。我可以反复调用play()和pause(),每次播放时,它都认为播放了大约一秒钟。
但是,我提到如果在创建AVAudioPlayer之后立即开始播放,歌曲确实会播放。在这种情况下,我可以通过调用pause()来暂停歌曲,但是如果我随后尝试使用play()或play(atTime :)再次播放,则会崩溃,并显示以下内容:“ com.apple.audio.IOThread .client(36):EXC_BAD_INSTRUCTION(代码= EXC_I386_INVOP,子代码= 0x0)”。我已经附上了堆栈跟踪的图片。
编辑:今天早上在昨天遇到问题后,它不再崩溃。除非我在创建后立即播放它,否则它不会播放。尽管它说正在播放,但是大约一秒钟。另外,我第二次打印出player.currentTime变量,它默默地“播放”,它说时间是一个很大的数字,例如297130或594407。尽管我要求将开始播放时间设为0实际上,在进一步测试后,这个数字似乎是随机的-有时很低,例如10或35。当它是一个合理的数字时,玩家确实报告说它继续玩-一秒钟后它不会停止。但是我什么也听不到。
我认为释放播放器不是问题,因为我可以在整个过程中继续引用它并调用其功能。有人知道还有什么问题吗?
答案 0 :(得分:0)
好的-我解决了这个问题。我没有意识到play(atTime :)使用音频设备的当前时间。一旦使用deviceCurrentTime,它就会播放。就我而言,这是相当愚蠢的错误。我不知道为什么昨天崩溃了。那没有再次发生。