无法让 AVAudioPlayer 停止播放

Unable to get AVAudioPlayer to stop playing

我有一个 class 定义为 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 对象无法从原始创建中访问,因此无法正确停止它;但到目前为止我也无法弄清楚。

如有任何帮助或建议,我们将不胜感激。

通过在 SettingsViewController 中实例化 Music class 的新实例,您实际上是在创建一个新的 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 已经有一个用于此目的的 属性。