无法让 AVAudioPlayer 停止播放

Posted

技术标签:

【中文标题】无法让 AVAudioPlayer 停止播放【英文标题】:Unable to get AVAudioPlayer to stop playing 【发布时间】:2021-04-22 18:15:32 【问题描述】:

我有一个定义为 Music.swift 的类,编码如下:

import Foundation
import AVFoundation

class Music 

   var isPlaying: Bool = false
   public var backgrndSound = AVAudioPlayer()
      
   func isMusicPlaying() -> Bool 
      isPlaying = UserDefaults.standard.bool(forKey: "isPlaying")
      return isPlaying
   
   
   func StartPlaying() 
      let path = Bundle.main.path(forResource: "Music.mp3", ofType: nil)!
      let url = URL(fileURLWithPath: path)
      do 
         self.backgrndSound = try AVAudioPlayer(contentsOf: url)
         self.backgrndSound.numberOfLoops = -1
         self.backgrndSound.play()
         UserDefaults.standard.setValue(true, forKey: "isPlaying")
       catch 
         // couldn't load file :(
      
   
   
   func StopPlaying() 
      self.backgrndSound.pause()
      self.backgrndSound.stop()
     

首次加载应用时,音乐会通过调用 StartPlaying() 自动开始。这工作得很好。之后我有一个设置菜单,其中有一个音乐播放开关:


import UIKit
import AVFoundation

class SettingsViewController: UIViewController 

   @IBOutlet weak var swMusic: UISwitch!
   var myMusic = Music()
   
   override func viewDidLoad() 
        super.viewDidLoad()

      swMusic.isOn = UserDefaults.standard.bool(forKey: "isPlaying")
   

   @IBAction func musicSwitch(_ sender: Any) 
      if swMusic.isOn == true 
         // turn on music
         myMusic.StartPlaying()
       else 
         myMusic.StopPlaying()
      
     

当我点击开关时,它会触发 StopPlaying(),但尽管点击了,背景中的音乐仍会继续播放。

我不确定为什么会这样,除非 AV 对象无法从原始创建中访问,因此无法正确停止它;但到目前为止,我也无法弄清楚。

任何帮助或建议将不胜感激。

【问题讨论】:

【参考方案1】:

通过在SettingsViewController 中实例化Music 类的新实例,您实际上是在创建一个对已经实例化的实例一无所知的新AVAudioPlayer 实例。

考虑一下这段代码,它包含 static 属性和 class 方法:

import Foundation
import AVFoundation

class Music 


   public static var backgrndSound: AVAudioPlayer?

   // AVAudioPlayer already has an isPlaying property          
   class func isMusicPlaying() -> Bool 
   
      return backgrndSound?.isPlaying ?? false
   
   
   class func StartPlaying() 
   
      let path = Bundle.main.path(forResource: "Music.mp3", ofType: nil)!
      let url = URL(fileURLWithPath: path)
      do 
      
         backgrndSound = try AVAudioPlayer(contentsOf: url)
         backgrndSound?.numberOfLoops = -1
         backgrndSound?.play()
       
      catch 
      
         // couldn't load file :(
      
   
   
   class func StopPlaying() 
   
      backgrndSound?.pause()
      backgrndSound?.stop()
     

然后使用:

Music.isMusicPlaying()
Music.startPlaying()
Music.stopPlaying()

即你不会这样做var myMusic = Music()

这样,AVAudioPlayerMusic.backgrndSound 的单个实例将始终存在

此示例代码将backgrndSound 更改为可选...您实际上是在创建一个未使用的AVAudioPlayer 实例,该实例在您startPlaying 时立即被丢弃。

它还删除了不必要的isPlaying 属性,因为AVAudioPlayer 已经有一个用于此目的的属性。

【讨论】:

该死,我错过了 func 的“类”部分并且我有一个静态错误,但我感谢我的朋友的帮助和帮助。我绝对想把它封装起来,这样我就可以在任何地方使用它,而不会产生大量的意大利面条代码。

以上是关于无法让 AVAudioPlayer 停止播放的主要内容,如果未能解决你的问题,请参考以下文章

如何让 avaudioplayer 在点击新闻歌曲时停止播放上一首歌曲?

Xcode:无法停止从子类播放 AVAudioPlayer 音乐

iOS AVAudioPlayer 让其他应用的背景音乐停止

快速恢复 AVAudioPlayer 中的声音

添加新的 NSView 时,AVAudioPlayer 播放停止

如何安全地停止 AVAudioPlayer