2016-07-16 131 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