AVAudioPlayer.play() works but AVAudioPlayerNode.play() fails

扶醉桌前 提交于 2019-12-11 11:45:47

问题


I have the following Swift playground code that plays an audio file using AVAudioPlayerNode.

import AVFoundation
import Foundation

NSSetUncaughtExceptionHandler { exception in
    print("Exception thrown: \(exception)")
}

var filePath = "/Users/fractor/Desktop/TestFile.mp3"
let file : AVAudioFile
do {
    file = try AVAudioFile(forReading: URL(fileURLWithPath: filePath))
} catch let error {
    print(error.localizedDescription)
    throw error
}

let audioEngine = AVAudioEngine()
let playerNode = AVAudioPlayerNode()
audioEngine.attach(playerNode)
audioEngine.connect(playerNode, to: audioEngine.outputNode, format: file.processingFormat);

do {
    try audioEngine.start()
} catch let error {
    print(error.localizedDescription)
    throw error
}

playerNode.scheduleFile(file, at: nil){}
playerNode.play();

This works fine on my mac mini when using the inbuilt speaker or when connected to a UE WONDERBOOM bluetooth speaker. However it crashes when connected to a UE BOOM 2 bluetooth speaker.

Using AVAudioPlayer works fine with all speakers I have tried including the UE BOOM 2.

The exception message is "player started when engine not running" however inserting print commands shows that the engine is running prior to playerNode.play() being called.

Here's (part of) the stack trace.

What does EXC_BAD_INSTRUCTION indicate in this case?

To remove the possibility of erroneous behaviour being introduced due to using a Swift playground, I have also created a Swift macOS Cocoa app. Here is the code:

class ViewController: NSViewController {

    let filePath = "/Users/fractor/Desktop/TestFile.mp3"
    var file : AVAudioFile?
    var audioEngine = AVAudioEngine()
    var playerNode = AVAudioPlayerNode()

    override func viewDidLoad() {
        super.viewDidLoad()

        do {
            file = try AVAudioFile(forReading: URL(fileURLWithPath: filePath))
        } catch let error {
            print(error.localizedDescription)
            return
        }

        audioEngine.attach(playerNode)
        audioEngine.connect(playerNode, to: audioEngine.outputNode, format: file!.processingFormat);

        do {
            try audioEngine.start()
        } catch let error {
            print(error.localizedDescription)
            return
        }

        playerNode.scheduleFile(file!, at: nil){}

        print("audioEngine.isRunning = \(audioEngine.isRunning)");
        playerNode.play();
        print("playerNode.isPlaying = \(playerNode.isPlaying)");
    }
}

This fails to play when connected to the UE BOOM 2 speaker with the following errors:

2019-07-23 13:32:50.784444+0100 AVAudioPlayerNodeSwiftTest[1757:29297] [AudioHAL_Client] HALC_ProxyIOContext.cpp:958:IOWorkLoop:  HALC_ProxyIOContext::IOWorkLoop: the server failed to start, Error: 0xE00002D6
2019-07-23 13:32:51.696089+0100 AVAudioPlayerNodeSwiftTest[1757:29249] Failed to set (contentViewController) user defined inspected property on (NSWindow): player started when engine not running
2019-07-23 13:32:53.815222+0100 AVAudioPlayerNodeSwiftTest[1757:29448] [AudioHAL_Client] HALC_ProxyIOContext.cpp:958:IOWorkLoop:  HALC_ProxyIOContext::IOWorkLoop: the server failed to start, Error: 0xE00002D6

Again this works fine with the WONDERBOOM speaker and the inbuilt speaker.

I manage to get an exception trace if I call play on a background thread using the following code:

DispatchQueue.global(qos: .background).async {
    print("audioEngine.isRunning = \(self.audioEngine.isRunning)");
    self.playerNode.play();
    print("playerNode.isPlaying = \(self.playerNode.isPlaying)");
}

The full output being:

audioEngine.isRunning = true
2019-07-24 12:25:38.710647+0100 AVAudioPlayerNodeSwiftTest[1852:21353] [AudioHAL_Client] HALC_ProxyIOContext.cpp:958:IOWorkLoop:  HALC_ProxyIOContext::IOWorkLoop: the server failed to start, Error: 0xE00002D6
2019-07-24 12:25:40.717683+0100 AVAudioPlayerNodeSwiftTest[1852:21340] [General] An uncaught exception was raised
2019-07-24 12:25:40.717738+0100 AVAudioPlayerNodeSwiftTest[1852:21340] [General] player started when engine not running
2019-07-24 12:25:40.717865+0100 AVAudioPlayerNodeSwiftTest[1852:21340] [General] (
    0   CoreFoundation                      0x00007fff2d017cfd __exceptionPreprocess + 256
    1   libobjc.A.dylib                     0x00007fff576bea17 objc_exception_throw + 48
    2   CoreFoundation                      0x00007fff2d032a1a +[NSException raise:format:arguments:] + 98
    3   AVFAudio                            0x00007fff291f2304 _Z19AVAE_RaiseExceptionP8NSStringz + 156
    4   AVFAudio                            0x00007fff29247d8c _ZN21AVAudioPlayerNodeImpl9StartImplEP11AVAudioTime + 1282
    5   AVFAudio                            0x00007fff29246b48 -[AVAudioPlayerNode play] + 75
    6   AVAudioPlayerNodeSwiftTest          0x0000000100002924 $s26AVAudioPlayerNodeSwiftTest14ViewControllerC11viewDidLoadyyFyycfU0_ + 644
    7   AVAudioPlayerNodeSwiftTest          0x0000000100002b8d $s26AVAudioPlayerNodeSwiftTest14ViewControllerC11viewDidLoadyyFyycfU0_TA + 13
    8   AVAudioPlayerNodeSwiftTest          0x00000001000025dd $sIeg_IeyB_TR + 45
    9   libdispatch.dylib                   0x000000010034fe7c _dispatch_call_block_and_release + 12
    10  libdispatch.dylib                   0x0000000100350f1b _dispatch_client_callout + 8
    11  libdispatch.dylib                   0x0000000100363a06 _dispatch_root_queue_drain + 816
    12  libdispatch.dylib                   0x00000001003642da _dispatch_worker_thread2 + 125
    13  libsystem_pthread.dylib             0x00000001003ca0b7 _pthread_wqthread + 583
    14  libsystem_pthread.dylib             0x00000001003c9e01 start_wqthread + 13
)
2019-07-24 12:25:40.718570+0100 AVAudioPlayerNodeSwiftTest[1852:21340] *** Terminating app due to uncaught exception 'com.apple.coreaudio.avfaudio', reason: 'player started when engine not running'
*** First throw call stack:
(
    0   CoreFoundation                      0x00007fff2d017cfd __exceptionPreprocess + 256
    1   libobjc.A.dylib                     0x00007fff576bea17 objc_exception_throw + 48
    2   CoreFoundation                      0x00007fff2d032a1a +[NSException raise:format:arguments:] + 98
    3   AVFAudio                            0x00007fff291f2304 _Z19AVAE_RaiseExceptionP8NSStringz + 156
    4   AVFAudio                            0x00007fff29247d8c _ZN21AVAudioPlayerNodeImpl9StartImplEP11AVAudioTime + 1282
    5   AVFAudio                            0x00007fff29246b48 -[AVAudioPlayerNode play] + 75
    6   AVAudioPlayerNodeSwiftTest          0x0000000100002924 $s26AVAudioPlayerNodeSwiftTest14ViewControllerC11viewDidLoadyyFyycfU0_ + 644
    7   AVAudioPlayerNodeSwiftTest          0x0000000100002b8d $s26AVAudioPlayerNodeSwiftTest14ViewControllerC11viewDidLoadyyFyycfU0_TA + 13
    8   AVAudioPlayerNodeSwiftTest          0x00000001000025dd $sIeg_IeyB_TR + 45
    9   libdispatch.dylib                   0x000000010034fe7c _dispatch_call_block_and_release + 12
    10  libdispatch.dylib                   0x0000000100350f1b _dispatch_client_callout + 8
    11  libdispatch.dylib                   0x0000000100363a06 _dispatch_root_queue_drain + 816
    12  libdispatch.dylib                   0x00000001003642da _dispatch_worker_thread2 + 125
    13  libsystem_pthread.dylib             0x00000001003ca0b7 _pthread_wqthread + 583
    14  libsystem_pthread.dylib             0x00000001003c9e01 start_wqthread + 13
)
libc++abi.dylib: terminating with uncaught exception of type NSException

Again, no problem if using the WONDERBOOM or built in speaker.

People are also having a problem here: https://forums.developer.apple.com/thread/118459

AudioKit also crashes: AudioKit macOS HelloWorld crashes with UE BOOM 2 speaker

AVAudioPlayer is not sufficient for the application I am developing. What is the problem? Presumably since it throws an exception, it is a bug in Apple code?

来源:https://stackoverflow.com/questions/57092434/avaudioplayer-play-works-but-avaudioplayernode-play-fails

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!