菜鸟教程小白 发表于 2022-12-11 19:49:04

ios - Swift 需要关闭音频播放器


                                            <p><p>我正在构建一个包含多个 ViewController 的应用程序。我需要控制所有音乐,所以我创建了一个专门的音乐类,我用它来设置/播放/停止/暂停。 </p>

<p>我已经录制了音频问题和答案,我需要能够播放 <strong>question</strong> 和 <strong>answer</strong> mp3 文件。 </p>

<p>所以我相信这里有几种方法来完成这个委托(delegate)和协议(protocol),使用 func audioPlayerDidFinishPlaying 和使用闭包。据我所知,闭包是我想要实现的最佳选择。 </p>

<p>我在 MakeMusic 课上的出发点是:</p>

<pre><code>class MakeMusicClass : NSObject, AVAudioPlayerDelegate {
    static let shared = MakeMusicClass()
    var audioPlayer = AVAudioPlayer()

    override init() { }

    func setup(Selection: String) {
      do {
            audioPlayer =try AVAudioPlayer(contentsOf: URL.init(fileURLWithPath: Bundle.main.path(forResource: Selection, ofType: &#34;mp3&#34;)!))
            audioPlayer.prepareToPlay()
            audioPlayer.delegate=self
      } catch {
            print (error)
      }
    }

    func play() {
      audioPlayer.play()
    }
</code></pre>

<p>我的调用文件是:</p>

<pre><code>class ViewController: UIViewController {
    override func viewDidLoad() {
      super.viewDidLoad()
      MakeMusicClass.shared.setup(Selection: &#34;Question11&#34;)
      MakeMusicClass.shared.play()

      MakeMusicClass.shared.setup(Selection: &#34;Answer11&#34;)
      MakeMusicClass.shared.play()
</code></pre>

<p>为了让它工作,我知道我需要为被调用的类添加一个闭包:</p>

<pre><code>func play() {
    var closure = { in
      audioPlayer.play()
    }
}
</code></pre>

<p>我需要更新我需要调用函数的位置,例如:</p>

<pre><code>override func viewDidLoad() {
    super.viewDidLoad()
    MakeMusicClass.shared.setup(Selection: &#34;Question11&#34;)
    MakeMusicClass.shared.play() {

    MakeMusicClass.shared.setup(Selection: &#34;Answer11&#34;)
    MakeMusicClass.shared.play()
}
</code></pre>

<p>我花了很长时间试图解决这个问题,但我很挣扎。我的代码显然不起作用,因为我缺少一些基本的东西。我尝试过传递 void 和参数,但我不明白应该传递哪些参数。我最接近的是使用 makemusic 类中的 audioPlayerDidFinishPlaying 触发下一个音频文件,但我不知道这是理想的。 </p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>我认为您最好的选择是在您的 <code>MakeMusicClass</code> 中使用 <code>Array</code> 作为初始化程序,例如一个问题和答案,然后使用 <code>AVAudioPlayerDelegate</code> 触发下一个文件,我认为这是你想要得到的(非常接近 ^________*)。</p>

<p>例如:</p>

<pre><code>class AudioLooper: NSObject, AVAudioPlayerDelegate {

var debugView = true

var audioLoopPlayer: AVAudioPlayer!

var audioFileIndex: Int = 0

var audioFileArray: = []

//-------------------------------------------------
//MARK: Audio Player Initialisation &amp; Functionality
//-------------------------------------------------

/// Function To Initialise The Audio Loop Player
///
/// - Parameter audioFiles: - The Array Of Audio Files To Play
func initAudioPlayerWith(audioFiles: ) {

    audioFileArray = audioFiles

    if debugView { print(&#34;Audio Files To Play In Sequence == \(audioFileArray)&#34;) }

}

/// Function To Play An Array Of Audio Files
///
/// - Parameter index: (Int) - The Current Index Of The Audio Sequence
func playAudioLoopAt(index: Int) {

    let currentAudioFile = &#34;\(audioFileArray)&#34;

    if let audioFilePath = Bundle.main.path(forResource: currentAudioFile, ofType: &#34;mp3&#34;){

      do {
            let audioFileUrl = NSURL.fileURL(withPath: audioFilePath)

            // Set An Instance Of AVAudioSession Which Allows Playback Even When Device Is Muted
            try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
            try AVAudioSession.sharedInstance().setActive(true)

            audioLoopPlayer = try AVAudioPlayer(contentsOf: audioFileUrl)
            audioLoopPlayer.prepareToPlay()
            audioLoopPlayer.delegate = self
            audioLoopPlayer.play()
            if debugView { print(&#34;Playing \(currentAudioFile) &#34;) }
            audioFileIndex += 1

      } catch {
            print(&#34;Error Playing Audio&#34;)
      }

    } else {

      print(&#34;Error Finding File: \(currentAudioFile)&#34;)
    }

}

/// Function To Continue The Audio Sequence
@objc func continueAudioLoop(){

    playAudioLoopAt(index: audioFileIndex)
}

/// Function To Stop The Audio Looop Player
func stopAudioPlayer() {

    if audioLoopPlayer != nil {
      audioFileIndex=0
      audioLoopPlayer.stop()
      audioLoopPlayer = nil
    }

}

//-----------------------------
//MARK: AVAudio Player Delegate
//-----------------------------

func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {

    if audioFileIndex &lt; audioFileArray.count {

      self.perform(#selector(continueAudioLoop), with: self, afterDelay: 0.5)

    }else{

      audioFileIndex=0

      }
}
}
</code></pre>

<p>在我的示例中,您只需像这样初始化:</p>

<pre><code>    audioLooper = AudioLooper()
    audioLooper?.initAudioPlayerWith(audioFiles: [&#34;question&#34;, &#34;answer&#34;])
    audioLooper?.playAudioLoopAt(index: 0)
</code></pre>

<p>audioLooper 声明如下:<code>var audioLooper:AudioLooper?</code></p>

<p>显然我的示例不是单例,但它应该让您了解如何调整 <code>MakeMusicClass</code> 以使其适合...</p>

<p>你也可以像这样添加一个 <code>Delegate</code> 方法来通知 <code>ViewController</code> 音频已经完成或执行一些其他任务,比如更新下一个问题等,例如:</p >

<pre><code>@objc protocol AudioLooperDelegate {

   @objc optional func update()
}
</code></pre>

<p>然后在你的 <code>ViewController</code> 中:</p>

<pre><code>var delegate: AudioLooperDelegate?
</code></pre>

<p>然后在 <code>AudioLooper</code> 类中,您可以在需要的地方添加委托(delegate)方法,例如:</p>

<pre><code>func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {

if audioFileIndex &lt; audioFileArray.count {

    self.perform(#selector(continueAudioLoop), with: self, afterDelay: 0.5)

}else{

    audioFileIndex=0
   delegate?.updateUI!()

}
}
}
</code></pre></p>
                                   
                                                <p style="font-size: 20px;">关于ios - Swift 需要关闭音频播放器,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/49081121/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/49081121/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - Swift 需要关闭音频播放器