代码之家  ›  专栏  ›  技术社区  ›  bsabiston

Mac上的avaudioplayer无法播放/崩溃

  •  0
  • bsabiston  · 技术社区  · 8 年前

    我正在尝试从我的Mac Cocoa应用程序中播放MP3。使用avaudioplayer看起来很简单。但它不起作用。我在网上查过,我看到的大多数问题都与玩家对象被释放有关,但我不认为这是我的问题。player对象是持久的,并响应成员函数调用。

    我从这样的URL创建avaudioplayer:

    class soundtrack:bobject,avaudioplayerLegate{
    
    var玩家:avaudioplayer!
    变量体积:浮点=1.0
    变量盘:浮动=0.0
    无功率:浮动=1.0
    var numberofloops:int=-1
    var url:url?
    var引用=假
    
    ……
    
    func setfile(u url:url)抛出{
    self.url=网址
    player=尝试avaudioplayer(contentsof:url)
    播放器。准备播放()。
    打印(“播放器持续时间(player.duration)”)
    打印(“播放器设置(player.settings)”)
    player.play()//这是注释/未注释的,用于测试
    }
    

    SoundTrack对象是我在调用setFile函数之前创建并添加到对象的持久层次结构中的对象。该URL指向一个文件,我在创建声轨之前在桌面上浏览该文件,例如“file:///users/bob/desktop/2_02_cycle.mp3”。

    如果我立即调用player.play(),如上图所示,那么它就工作了。这首歌一直播放到我停下来。但是,如果我注释掉play()并稍后调用它,例如通过按一个键,那么它就不会播放。它说它是成功的:

    player.PrepareToplay()。
    让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(code=exc_i386_invop,subcode=0x0)”。我已附上堆栈跟踪的图片。

    编辑:今天早上,昨天发生问题后,它不再崩溃。它只是不播放,除非我在创建后立即播放。虽然它说它在演奏,但大约有一秒钟。另外,我打印了player.currentTime变量作为它执行“播放”的第二个变量,它无声地说时间是一个巨大的数字,比如297130或594407。尽管我要求开始播放时间为0。实际上,经过进一步的测试,这个数字似乎是随机的——有时很低,比如10或35。当它是一个合理的数字时,玩家会报告说它会继续玩——一秒钟后它不会停止。但我从未听到任何声音。

    我不认为这是玩家被释放的问题,因为我可以继续引用它并在整个过程中调用它的函数。有人知道还有什么问题吗?

    .

    我从这样的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函数之前创建并添加到对象的持久层次结构中的对象。该URL指向一个文件,我在创建声轨之前在桌面上浏览该文件,例如“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(code=exc_i386_invop,subcode=0x0)”。我附上了一张堆栈跟踪的图片。

    编辑:今天早上,昨天发生问题后,它不再崩溃。它只是不播放,除非我在创建后立即播放。虽然它说它在演奏,但大约有一秒钟。另外,我打印了player.currentTime变量作为它执行“播放”的第二个变量,它无声地说时间是一个巨大的数字,比如297130或594407。尽管我要求开始播放时间为0。实际上,经过进一步的测试,这个数字似乎是随机的——有时很低,比如10或35。当它是一个合理的数字时,玩家会报告说它会继续玩——一秒钟后它不会停止。但我从来没有听到任何声音。

    我不认为这是玩家被释放的问题,因为我可以继续引用它并在整个过程中调用它的函数。有人知道还有什么问题吗?

    1 回复  |  直到 8 年前
        1
  •  0
  •   bsabiston    8 年前

    好的-我解决了这个问题。我没有意识到Play(Attime:)使用音频设备的当前时间。一旦我使用了设备当前时间,它就会播放。我犯了一个相当愚蠢的错误。我不知道为什么昨天它会坠毁。这还没有再次发生。