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

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

  •  2
  • Simant  · 技术社区  · 8 年前

    我必须一次播放三种类型的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()
        }
    }    
    

    }

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

    1 回复  |  直到 8 年前
        1
  •  1
  •   user9606220 user9606220    8 年前

    播放声音的代码

    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)
            }
            }