2016-07-16 158 views
1

我正在尝试在应用程序中构建一个音板,并找出了使用标签控制播放声音的有效方法。但是我现在想集成一个暂停按钮,可使用在AVAudioPlayer.stop()方法一起使用,但是我得到一个错误与我当前的代码:Swift - 停止播放器

EXC_BAD_ACCESS

这是我使用的那一刻是什么,有任何想法吗?

import UIKit 
import AVFoundation 

let soundFilenames = ["sound","sound2","sound3"] 
var audioPlayers = [AVAudioPlayer]() 

class SecondViewController: UIViewController { 

    var audioPlayer = AVAudioPlayer() 

    override func viewDidLoad() { 
     super.viewDidLoad() 

    for sound in soundFilenames { 
      do { 
       let url = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource(sound, ofType: "mp3")!) 
       let audioPlayer = try AVAudioPlayer(contentsOfURL: url) 
       audioPlayers.append(audioPlayer) 
      } catch { 
       //Catch error thrown 
       audioPlayers.append(AVAudioPlayer()) 
      } 
    } 
    } 


    @IBAction func buttonPressed(sender: UIButton) { 
      let audioPlayer = audioPlayers[sender.tag] 
      audioPlayer.play() 
    } 
    @IBAction func stop(sender: UIButton) { 
      audioPlayer.stop() 
    } 

} 
+0

可以工作......但只适用于播放的第一个声音文件,即与停止按钮具有相同标记的文件。我想停止按钮停止所有的声音,不管他们的标签。 – dwinnbrown

回答

2

您的audioPlayer停止功能不是玩家。您应该将其分配在buttonPressed函数中。

@IBAction func buttonPressed(sender: UIButton) { 
     audioPlayer = audioPlayers[sender.tag] 
     audioPlayer.play() 
} 

顺便说一下,您可以将audioPlayer标记为“?”属性,当初始化这个Controller时它会更有效率。

class SecondViewController: UIViewController { 

    var audioPlayer: AVAudioPlayer? 

    let enableMuiltPlayers = false 
.... 


    @IBAction func buttonPressed(sender: UIButton) { 
      if sender.tag < audioPlayers.count else { 
       print("out of range") 
       return 
      } 
      if enableMuiltPlayers { 
      audioPlayers[sender.tag].play() 
      } else { 
      audioPlayer?.stop() 
      //set the current playing player 
      audioPlayer = audioPlayers[sender.tag] 
      audioPlayer?.play() 
      } 
    } 

    @IBAction func stop(sender: UIButton) { 
      let wantToStopAll = false 
      if enableMuiltPlayers && wantToStopAll { 
       stopAll() 
      } else { 
       audioPlayer?.stop() 
      } 
      audioPlayer = nil 
    } 
} 

停止一切:

fun stopAll() { 
    for player in audioPlayers { 
     player.stop() 
    } 
} 
+0

好的谢谢。我应该从stop函数中调用stopAll吗? – dwinnbrown

+0

如果您在同一时间播放音频,如果您想停止所有音频,则应该调用stopAll函数。 – Hao

+0

非常感谢 - 在调用stopAll函数后现在完美地工作 – dwinnbrown

2

您的代码可能有其他错误,但有一点肯定的:

使用默认初始AVAudioPlayer()你不应该实例AVAudioPlayer

改变这一行:

 var audioPlayer = AVAudioPlayer() 

到:

 var playingAudioPlayer: AVAudioPlayer? 

而改变这一部分:

  } catch { 
       //Catch error thrown 
       audioPlayers.append(AVAudioPlayer()) 
      } 

是这样的:

  } catch { 
       //Catch error thrown 
       fatalError("Sound resource: \(sound) could not be found") 
      } 

(后半部分解决问题非常重要。但我发现,它已成为一个刚刚浩的答案的某些部分的重复后,我剪辑...)

而且start方法:

 @IBAction func start(sender: UIButton) { 
      let audioPlayer = audioPlayers[sender.tag] 
      audioPlayer.start() 
      playingAudioPlayer = audioPlayer 
    } 

而且stop应该是:

 @IBAction func start(sender: UIButton) { 
      playingAudioPlayer?.stop() 
    } 
+0

这几乎可以工作,但是如果两个文件同时播放,只有原始的文件被停止播放。 – dwinnbrown

+1

@dwinnbrown,正确。这个答案的主要关注点是“你不应该使用'AVAudioPlayer()'”来避免这种错误。我相信郝的“stopAll()”会像你期望的那样工作。 – OOPer

0
if audioPlayer != nil { 
    if audioPlayer.playing { 
     audioPlayer.stop() 
    } 
} 
+0

请添加一些信息,说明为什么以及如何解决OP描述的问题 – loki