简体   繁体   中英

Sound is playing only for the first time using AVAudioEngine in iOS

I have a sound file which listens as beep sound and I have to play this sound repeatedly with changing its pitch depending on some condition. I am using AVAudioEngine, AVAudioPlayerNode, and AVAudioUnitTimePitch to achieve this objective. There are two buttons in my view namely Play and Stop . When I press on the Play button for the first time, the sound is playing repeatedly but after clicking on the Stop button once and then again clicking on the Play button, the sound is not playing and giving no errors as well. I have been looking into this issue for a long time but unable to get the solution and I came here. Could you please help me to fix this issue. Or are there any other alternate solutions for my problem? My code is as below:

import UIKit
import AVFoundation

class ViewController: UIViewController {

    let engine = AVAudioEngine()
    let audioPlayer = AVAudioPlayerNode()
    let pitchUnit = AVAudioUnitTimePitch()

    var avAudioFile: AVAudioFile!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        let path = Bundle.main.path(forResource: "Beep", ofType: "wav")!
        let url = NSURL.init(fileURLWithPath: path)
        avAudioFile = try? AVAudioFile(forReading: url as URL)

        setup()
    }

    func setup() {
        engine.attach(audioPlayer)
        engine.attach(pitchUnit)
        engine.connect(audioPlayer, to: pitchUnit, format: nil)
        engine.connect(pitchUnit, to:engine.mainMixerNode, format: nil)

        try? engine.start()

        audioPlayer.volume = 1.0
        audioPlayer.play()

    }
    @IBAction func playSound(_ sender: UIButton) {

        pitchUnit.pitch = 1

        // interrupt playing sound if you have to
        if audioPlayer.isPlaying {
            audioPlayer.stop()
            audioPlayer.play()
        }
        let buffer = AVAudioPCMBuffer(pcmFormat: avAudioFile.processingFormat, frameCapacity: AVAudioFrameCount(avAudioFile.length))
        try? avAudioFile.read(into: buffer!)
        audioPlayer.scheduleBuffer(buffer!, at: nil, options: AVAudioPlayerNodeBufferOptions.loops, completionHandler: nil)
    }

    @IBAction func stopSound(_ sender: UIButton) {
        audioPlayer.stop()
    }
}

The problem lies in your playSound func.

// interrupt playing sound if you have to
if audioPlayer.isPlaying {
    audioPlayer.stop()
    audioPlayer.play()
}

You are trying to play the player only if its already playing. so that doesnt make any sense. you can remove these lines and can simply use just this.

 audioPlayer.play()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM