用户在应用中移动时如何继续播放音乐。[不在背景模式下]

查克

我正在Swift中制作一个musicPlayer应用程序,该应用程序基于Tab Bar Controller,现在正在创建NowPlayingViewController,该应用程序显示了播放场景,如下图所示。当我从另一个tableViewController单击表行时,将打开此NowPlayingViewController并播放歌曲。

我的问题是,当我关闭该视图控制器以返回到上一个视图或移至“标签栏控制器”的其他视图时,音乐播放将停止。搜寻了一些Google之后,有人建议使用Singleton进行音乐播放的共享会话。

在此处输入图片说明

///这是我项目的故事板 在此处输入图片说明

///我更改代码以添加一个Audio Manager.swift作为单例类。但是我不确定我是否做对了,需要帮助。也找不到从NowPlayingVewController获取playSong变量的方法...

import AVKit

class AudioManager {
    // use Singleton pattern keep the music continuing when user move through the App.
    static let sharedInstance = AudioManager()

    var audioPlayer: AVAudioPlayer!
    var playingSong: SongData?

    private init() {
        // config for audio background playing
        do {
            try AVAudioSession.sharedInstance().setCategory(.playback, mode: .default, options: [.mixWithOthers])
            print("Playback OK")
            try AVAudioSession.sharedInstance().setActive(true)
            print("Session is Active")
        } catch {
            print(error)
        }
    }

    func startMusic() {
        do {
            // how to retrieve the playingSong variable from NowPlayingViewController?
            // playingSong =
            try audioPlayer = AVAudioPlayer(contentsOf: playingSong!.url)
            audioPlayer.prepareToPlay()
            audioPlayer.play()
        } catch {
            print("could not load file")
        }
    }

    func pauseMusic() {
       audioPlayer.pause()
    }
}

/// NowPlayViewController.swift,以防它与上面的图片不完全对齐,因为它只是显示播放场景的示例图片。

import UIKit
import AVKit

class NowPlayingViewController: UIViewController {

    var playingSong: SongData?
    var audioPlayer: AVAudioPlayer!
    var isPlaying = true
    var timer:Timer!

    @IBOutlet weak var songTitle: UILabel!
    @IBOutlet weak var songAlbum: UILabel!
    @IBOutlet weak var songArtwork: UIImageView!
    @IBOutlet weak var playOrPauseButton: UIButton!

    override func viewDidLoad() {
        super.viewDidLoad()

        songTitle.text = playingSong?.songName
        songAlbum.text = playingSong?.albumName
        songArtwork.image = playingSong?.albumArtwork

        // start play music in AudioManager sharedInstance
        AudioManager.sharedInstance.startMusic()
    }

    @IBAction func NaviBack(_ sender: UIButton) {
        print("press button")
        // not sure about this, use present modally of segue,
        // so need to use dismiss to return to the previous scene/view.
        self.dismiss(animated: true, completion: nil)
    }

    @IBAction func PlayOrPauseMusic(_ sender: UIButton) {
        if isPlaying {
            print("isPlaying")
            AudioManager.sharedInstance.pauseMusic()
            isPlaying = false
            playOrPauseButton.setTitle("Pause", for: .normal)
        } else {
            print("isPaused")
            AudioManager.sharedInstance.startMusic()
            isPlaying = true
            playOrPauseButton.setTitle("Play", for: .normal)
        }
    }
}

///使用Segue以模态形式将数据从tableViewController发送到NowPlayingViewController。

// define segue to the transition to NowPlaying View
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "playingSong" {
             if let indexPath = self.tableView.indexPathForSelectedRow {
                let controller = segue.destination as! NowPlayingViewController
                if resultSearchController.isActive {
                    controller.playingSong = filteredTableData[indexPath.row]
                } else {
                    controller.playingSong = tableData[indexPath.row]
                }

            }
        }
    }
查克

糟糕,我发现我的AudioManger实际上是通过在用户单击此视图中的单元格行时从tableViewController中获取playingSong:SongData来工作的。我将此playingSong声明为静态变量,以便从AudioManager访问/使用它。

现在,当用户通过Tab Bar Controller导航时,正在播放音乐,如下所示更新我的代码。下一步可以在导航视图的左/右上方添加一个按钮,以重新呈现播放场景:)

错误,我发现它仍然有问题,当前歌曲的播放和恢复正常,但是如果我在tableViewController中选择另一首歌曲,那么它仍会在NowPlayingView中播放前一首歌曲。原因可能只是一次init(),所以我需要找到一种在选择另一单元格行时将值重新分配给sharedInstance的方法。

import AVKit

class AudioManager {
    // use Singleton pattern keep the music continuing when user move through the App.
    static let sharedInstance = AudioManager()

    var audioPlayer: AVAudioPlayer!
    var playingSong: SongData?

    private init() {
        // config for audio background playing
        do {
            try AVAudioSession.sharedInstance().setCategory(.playback, mode: .default, options: [.mixWithOthers])
            print("Playback OK")
            try AVAudioSession.sharedInstance().setActive(true)
            print("Session is Active")
        } catch {
            print(error)
        }

        do {
            playingSong = SongsTableViewController.playingSong
            try audioPlayer = AVAudioPlayer(contentsOf: playingSong!.url)
            audioPlayer.prepareToPlay()
        } catch {
            print("could not load file")
        }
    }

    func playMusic() {
       audioPlayer.play()
    }

    func pauseMusic() {
       audioPlayer.pause()
    }

}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章