Swift 3 AVFoundation 停止上一个 AVAudioPlayer
Swift 3 AVFoundation Stop previous AVAudioPlayer
我有一个名为 PlayerController 的视图控制器,当我转到 PlayerController 时,它会加载一个音频文件并将其放入 AVAudioPlayer 中,他们的播放按钮是播放 AVAudioPlayer。到目前为止,一切都很好。问题是,如果我离开 PlayerController 并再次转到它,前一个 AVAudioPlayer 的音频仍在播放,在我的 viewWillAppear 方法中,我有此行来停止 AVAudioPlayer 播放,但它不起作用,它不会停止前一个AVAudioPlayer 从播放....我将如何完成我想做的事情?我应该在我的 appDelegate 文件中定义 AVAudioPlayer 并从他们的文件中读取它吗?
这是我的 viewWillAppear 方法:
override func viewWillAppear(_ animated: Bool)
{
super.viewWillAppear(animated)
timer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: (#selector(PlayerController.updateTimer)), userInfo: nil, repeats: true)
if(UserDefaults.standard.integer(forKey: "nowPlayingPost") == 0)
{
UserDefaults.standard.set(self.postid, forKey: "nowPlayingPost")
audioSlider.setValue(0, animated: false)
if(self.audio != nil && (self.audio?.isPlaying)!)
{
self.audio?.stop()
}
}
else
{
audioSlider.value = Float((self.audio?.currentTime)!)
self.audioSlider.maximumValue = Float((self.audio?.duration)!)
self.postid = UserDefaults.standard.integer(forKey: "nowPlayingPost")
if(self.audio?.isPlaying)!
{
self.playButton.setTitle("Stop", for: .normal)
}
else
{
if(self.audio?.currentTime == 0)
{
self.playButton.setTitle("Play", for: .normal)
}
else
{
self.playButton.setTitle("Resume", for: .normal)
}
}
}
Alamofire.request(audioUrl!).responseData { response in
do {
self.audio = try AVAudioPlayer(data: response.data!)
self.audio?.prepareToPlay()
self.audioSlider.maximumValue = Float((self.audio?.duration)!)
}catch{
}
}
}
那么我应该在 appDelegate 中定义 AVAudioPlayer 还是使用 UserDefaults 或 CoreData 或其他?这方面的最佳做法是什么?
我认为最好的解决方案是使用 class 单例来控制您的音频功能,这样您就不会创建另一个需要停止且不需要复杂性的 AVAudioPlayer 实例通知中心。您还可以从任何视图控制器访问 Singleton 并添加从 Alamofire 检索音频数据的方法,这样您就不需要通过 segue 或使用 NSUserDefaults 传递数据。
class AudioController {
static let sharedInstance = AudioController()
var nowPlayingPost: Int = 0
private init(){}
func playAudioFrom(url: URL){
// your implementation
}
// Other methods, stop, pause, etc.
}
视图控制器中的任何位置:
AudioController.sharedInstance.playAudio(url: url)
我有一个名为 PlayerController 的视图控制器,当我转到 PlayerController 时,它会加载一个音频文件并将其放入 AVAudioPlayer 中,他们的播放按钮是播放 AVAudioPlayer。到目前为止,一切都很好。问题是,如果我离开 PlayerController 并再次转到它,前一个 AVAudioPlayer 的音频仍在播放,在我的 viewWillAppear 方法中,我有此行来停止 AVAudioPlayer 播放,但它不起作用,它不会停止前一个AVAudioPlayer 从播放....我将如何完成我想做的事情?我应该在我的 appDelegate 文件中定义 AVAudioPlayer 并从他们的文件中读取它吗?
这是我的 viewWillAppear 方法:
override func viewWillAppear(_ animated: Bool)
{
super.viewWillAppear(animated)
timer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: (#selector(PlayerController.updateTimer)), userInfo: nil, repeats: true)
if(UserDefaults.standard.integer(forKey: "nowPlayingPost") == 0)
{
UserDefaults.standard.set(self.postid, forKey: "nowPlayingPost")
audioSlider.setValue(0, animated: false)
if(self.audio != nil && (self.audio?.isPlaying)!)
{
self.audio?.stop()
}
}
else
{
audioSlider.value = Float((self.audio?.currentTime)!)
self.audioSlider.maximumValue = Float((self.audio?.duration)!)
self.postid = UserDefaults.standard.integer(forKey: "nowPlayingPost")
if(self.audio?.isPlaying)!
{
self.playButton.setTitle("Stop", for: .normal)
}
else
{
if(self.audio?.currentTime == 0)
{
self.playButton.setTitle("Play", for: .normal)
}
else
{
self.playButton.setTitle("Resume", for: .normal)
}
}
}
Alamofire.request(audioUrl!).responseData { response in
do {
self.audio = try AVAudioPlayer(data: response.data!)
self.audio?.prepareToPlay()
self.audioSlider.maximumValue = Float((self.audio?.duration)!)
}catch{
}
}
}
那么我应该在 appDelegate 中定义 AVAudioPlayer 还是使用 UserDefaults 或 CoreData 或其他?这方面的最佳做法是什么?
我认为最好的解决方案是使用 class 单例来控制您的音频功能,这样您就不会创建另一个需要停止且不需要复杂性的 AVAudioPlayer 实例通知中心。您还可以从任何视图控制器访问 Singleton 并添加从 Alamofire 检索音频数据的方法,这样您就不需要通过 segue 或使用 NSUserDefaults 传递数据。
class AudioController {
static let sharedInstance = AudioController()
var nowPlayingPost: Int = 0
private init(){}
func playAudioFrom(url: URL){
// your implementation
}
// Other methods, stop, pause, etc.
}
视图控制器中的任何位置:
AudioController.sharedInstance.playAudio(url: url)