使用Swift 2.1在iOS中播放两个声音

时间:2016-02-09 15:42:25

标签: ios iphone xcode avaudioplayer

我有一个应用程序,包括一个选择器轮和一个播放按钮。当用户选择所需的声音并单击播放按钮时,将播放声音。除此之外,我还有一个"随机"将生成随机数的按钮,将选择器轮移动到相应的数组索引,然后播放声音。所有这些都可以。

问题是我试图添加" Combo"按钮基本上与"随机"按钮,但不是只播放1个声音,而是希望它播放2或3。

这是我现有的代码(playComboSound函数的问题):

// Play Audio
var audioPlayer = AVAudioPlayer()

func playAudio() {
    do {
        if let bundle = NSBundle.mainBundle().pathForResource(Sounds[selection], ofType: "mp3") {
            let alertSound = NSURL(fileURLWithPath: bundle)
            try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
            try AVAudioSession.sharedInstance().setActive(true)
            try audioPlayer = AVAudioPlayer(contentsOfURL: alertSound)
            audioPlayer.prepareToPlay()
            audioPlayer.play()
        }
    } catch {
        print(error)
    }
}

@IBAction func playRandomSound(sender: AnyObject) {

    // Generate Random Number Based on SoundNames Array Count and assign to Selection
    let randomNumber = Int(arc4random_uniform(UInt32(SoundNames.count)))
    selection = randomNumber

    // Move Picker Wheel to Match Random Number and Play Sound
    self.picker.selectRow(selection, inComponent: 0, animated: true)
    playAudio()
}

@IBAction func playComboSound(sender: AnyObject) {
    // Generate Random Number Based on SoundNames Array Count and assign to Selection
    let randomNumber1 = Int(arc4random_uniform(UInt32(SoundNames.count)))
    selection = randomNumber1

    // Move Picker Wheel to Match Random Number and Play Sound
    self.picker.selectRow(selection, inComponent: 0, animated: true)
    playAudio()

    // Generate Random Number Based on SoundNames Array Count and assign to Selection
    let randomNumber2 = Int(arc4random_uniform(UInt32(SoundNames.count)))
    selection = randomNumber2

    // Move Picker Wheel to Match Random Number and Play Sound
    self.picker.selectRow(selection, inComponent: 0, animated: true)
    playAudio()
}

当我点击playComboSound按钮时,它基本上与playRandomSound按钮相同。移动选择器轮并播放声音,但它只执行一次而不是两次。如果我在两者之间进行一次睡眠,我会在播放两种声音时获得一定程度的成功,但它似乎只能移动一次拾取轮(对于第二种声音)。任何帮助将不胜感激!感谢。

1 个答案:

答案 0 :(得分:2)

  

移动选择器轮并播放声音,但它只执行一次而不是两次。

它会播放一次声音,因为对playAudio的第二次调用会使用新的audioPlayer实例覆盖共享的AVAudioPlayer变量,该实例会释放第一个AVAudioPlayerDelegate实例。您应该保留一个对所有活动音频播放器的数组/引用集以防止它们被取消分配,并且只有在它们完成后才从它们中删除它们(使用AVAudioPlayer回调来检测播放器何时已完成)。

  

如果我在两者之间进行睡眠,我在播放两种声音方面取得了一定程度的成功,但它似乎只能将拾取轮移动一次(对于第二种声音)。

睡眠有帮助,因为当主线程处于休眠状态时,AVFoundation的线程有机会运行,并且在第二次调用playAudio覆盖之前,它们可以开始播放第一个selectRow它已被解除分配。您虽然在这里依赖于未定义的行为。

  

它似乎只是移动了一次拾取轮(对于第二个声音)

这是预期的行为。在拾取轮上只能选择一个项目。对SendInput, #d 的第二次调用会覆盖第一次调用。