Home > Net >  AVAudioEngine doesn't playback a sound
AVAudioEngine doesn't playback a sound

Time:10-22

I am trying to play with AVAudioEngine to playback the wav file. I tried to do it in a few different ways, but nothing work.

Try 1

...
    private var audioEngine: AVAudioEngine = AVAudioEngine()
    private var mixer: AVAudioMixerNode = AVAudioMixerNode()
    private var audioFilePlayer: AVAudioPlayerNode = AVAudioPlayerNode()

    func Play1() {
        guard let filePath = Bundle.main.url(forResource: "testwav", withExtension: "wav", subdirectory: "res") else {
            print("file not found")
            return
        }
        
        print("\(filePath)")
        
        guard let audioFile = try? AVAudioFile(forReading: filePath) 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)
        audioEngine.connect(mainMixer, to:audioEngine.outputNode, format: audioFileBuffer.format)
        try? audioEngine.start()
        audioFilePlayer.play()
        audioFilePlayer.scheduleBuffer(audioFileBuffer, at: nil, options:AVAudioPlayerNodeBufferOptions.loops)
    }
...

Try 2

...
    private var audioEngine: AVAudioEngine = AVAudioEngine()
    private var mixer: AVAudioMixerNode = AVAudioMixerNode()
    private var audioFilePlayer: AVAudioPlayerNode = AVAudioPlayerNode()

    func Play2() {
        DispatchQueue.global(qos: .background).async {
            self.audioEngine.attach(self.mixer)
            self.audioEngine.connect(self.mixer, to: self.audioEngine.outputNode, format: nil)
            // !important - start the engine *before* setting up the player nodes
            try! self.audioEngine.start()

            let audioPlayer = AVAudioPlayerNode()
            self.audioEngine.attach(audioPlayer)
            // Notice the output is the mixer in this case
            self.audioEngine.connect(audioPlayer, to: self.mixer, format: nil)
            
            guard let fileUrl = Bundle.main.url(forResource: "testwav", withExtension: "wav", subdirectory: "res") else {
                //            guard let url = Bundle.main.url(forResource: "audiotest", withExtension: "mp3", subdirectory: "res") else {
                print("mp3 not found")
                return
            }
            
            do {
                let file = try AVAudioFile(forReading: fileUrl)
                
                audioPlayer.scheduleFile(file, at: nil, completionHandler: nil)
                audioPlayer.play(at: nil)
            } catch let error {
                print(error.localizedDescription)
            }
        }
    }
...
...
    private var audioEngine: AVAudioEngine = AVAudioEngine()
    private var mixer: AVAudioMixerNode = AVAudioMixerNode()
    private var audioFilePlayer: AVAudioPlayerNode = AVAudioPlayerNode()

    func Play3() {
        DispatchQueue.global(qos: .background).async {
            self.audioEngine = AVAudioEngine()
            _ = self.audioEngine.mainMixerNode
            
            self.audioEngine.prepare()
            do {
                try self.audioEngine.start()
            } catch {
                print(error)
            }
            
            guard let url = Bundle.main.url(forResource: "testwav", withExtension: "wav", subdirectory: "res") else {
                //            guard let url = Bundle.main.url(forResource: "audiotest", withExtension: "mp3", subdirectory: "res") else {
                print("mp3 not found")
                return
            }
            
            let player = AVAudioPlayerNode()
            player.volume = 1.0
            
            do {
                let audioFile = try AVAudioFile(forReading: url)
                
                let format = audioFile.processingFormat
                print(format)
                
                self.audioEngine.attach(player)
                self.audioEngine.connect(player, to: self.audioEngine.mainMixerNode, format: format)
                
                player.scheduleFile(audioFile, at: nil, completionHandler: nil)
            } catch let error {
                print(error.localizedDescription)
            }
            
            player.play()
        }
    }
...

Also should be mentioned that there are no errors, while debugging I see that all the methods are executed and everything is ok, but I don't hear sound playback...

What am I doing wrong?

CodePudding user response:

Try to activate your audio session with the following method:

func setActive(_ active: Bool, options: AVAudioSession.SetActiveOptions = []) throws.

Please note that if another active audio session has higher priority than yours (for example, a phone call), and neither audio session allows mixing, attempting to activate your audio session fails. Deactivating an audio session that has running audio objects stops them, deactivates the session, and return an AVAudioSession.ErrorCode.isBusy error.

  • Related