ios - 在iOS中使用多个播放按钮播放声音

标签 ios swift avaudioengine avaudioplayernode

我必须一次播放三种类型的wav文件。当我单击“输入”区域中的“播放”按钮时,它将播放名为“EnterRegion.wav”的声音,然后单击“退出区域”,则播放按钮将播放“ExitRegion.wav”音频文件。

但是对于即时播放的播放按钮,它会重复播放声音,直到我按下停止按钮为止。

第一个和第二个“播放”按钮对我来说都工作正常,但是当我单击“即时”中的播放按钮时,它会第一次播放声音,但是当我单击其他播放按钮并再次回到“即时”播放按钮时,应用程序会引发异常。当我按下停止按钮并返回到立即部分的播放按钮时,也会发生同样的情况。 Swift 4中的示例应用程序屏幕截图和代码示例如下所示。

enter image description here

import UIKit
import AVFoundation

class ViewController: UIViewController {

    var engine: AVAudioEngine!

    var enterWavFile: AVAudioFile!

    var audioPlayerNode : AVAudioPlayerNode!
    var immediaAudioPlayerNode: AVAudioPlayerNode!


    var exitWavFile: AVAudioFile!

    var flatlineWavFile:AVAudioFile!

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

        engine = AVAudioEngine()

        enterWavFile = try? AVAudioFile(forReading: NSURL.fileURL(withPath:
            Bundle.main.path(forResource: "EnterRegion", ofType: "wav")!))
        exitWavFile = try? AVAudioFile(forReading: NSURL.fileURL(withPath:
            Bundle.main.path(forResource: "ExitRegion", ofType: "wav")!))

        flatlineWavFile = try? AVAudioFile(forReading: NSURL.fileURL(withPath:
            Bundle.main.path(forResource: "Immediate", ofType: "wav")!))

    }

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

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

    func playSound(audioFile: AVAudioFile)  {
        audioPlayerNode = AVAudioPlayerNode()
        if(audioPlayerNode.isPlaying){
            audioPlayerNode.stop()
        }

        if(engine.isRunning){
            engine.stop()
            engine.reset()
        }

        engine.attach(audioPlayerNode)

    engine.connect(audioPlayerNode, to: engine.mainMixerNode, format: audioFile.processingFormat)
    audioPlayerNode.scheduleFile(audioFile, at: nil, completionHandler: nil)

    // Start the audio engine
    engine.prepare()
    try! engine.start()

    audioPlayerNode.play()
}


@IBAction func playImmediateFlatline(_ sender: UIButton) {
    immediaAudioPlayerNode = AVAudioPlayerNode()
    if(immediaAudioPlayerNode.isPlaying){
        print("immediateAudioPlayerNode Playing")
        immediaAudioPlayerNode.stop()
    }


    if(engine.isRunning){
        print("engine Running")
        engine.stop()
        engine.reset()
    }

    let audioFileBuffer = AVAudioPCMBuffer(pcmFormat: flatlineWavFile.processingFormat, frameCapacity: AVAudioFrameCount( flatlineWavFile.length))!

    try? flatlineWavFile.read(into: audioFileBuffer)

    engine.attach(immediaAudioPlayerNode)

    engine.connect(immediaAudioPlayerNode, to: engine.mainMixerNode, format: flatlineWavFile.processingFormat)
    immediaAudioPlayerNode.scheduleBuffer(audioFileBuffer, at: nil, options: AVAudioPlayerNodeBufferOptions.loops, completionHandler: nil)

    // Start the audio engine
    engine.prepare()
    try! engine.start()

    immediaAudioPlayerNode.play()
}


@IBAction func stopImmediateFlatline(_ sender: UIButton) {
    if (immediaAudioPlayerNode.isPlaying){
        print("immediateAudioPlayerNode playing")
        immediaAudioPlayerNode.pause()
    }

    if(engine.isRunning){
        print("engine Running")
        engine.stop()
        engine.reset()
    }
}    

}

我无法找到发生这种情况的原因,请您帮我解决问题或任何建议。

最佳答案

播放声音的代码

var player1: AVAudioPlayer?
var player2: AVAudioPlayer?
var player3: AVAudioPlayer?

     func playSound() {
        guard let url = Bundle.main.url(forResource: "Music", withExtension: "wav") else { return }

        do {
        try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
        try AVAudioSession.sharedInstance().setActive(true)

        /* The following line is required for the player to work on iOS 11. Change the file type accordingly*/
        player = try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileType.mp3.rawValue)

        /* iOS 10 and earlier require the following line:
         player = try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileTypeMPEGLayer3) */

        guard let player = player else { return }
        // read this line of code for you to play the wav file you wanted to play ang then trigger it using a button.
        player.play()

        } catch let error {
        print(error.localizedDescription)
        }
        }

关于ios - 在iOS中使用多个播放按钮播放声音,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49915996/

相关文章:

ios - Swift 不能使用函数指针吗?

ios - 通过搜索 LinkedIn 获取公开资料 URL

ios - Storyboard元素不可见

ios - 如何停止 UISegmentedControl 分段动画

ios - 从另一个值创建新的字典

Swift - AVAudioPlayer 无法正常工作

ios - 从 Swift 中的文本框循环用户输入

swift - SKLabelNode 边界和边界问题

ios - 我可以使用 AVAudioEngine 以比实时更快的速度读取文件、处理音频单元并写入文件吗?

swift - AVAudioFile 中的 URL 为 nil