在 Swift 5 中,您将如何通过背景音频将音频控件添加到控制中心?

时间:2021-06-05 17:25:23

标签: ios swift audio control-center

我正在播放来自我构建的 JSON 源的音频,用于将音频 URL 和它的音频信息提供给我的应用程序(例如标题、描述和封面图片 URL)。音频是广播电台的馈送。音频作品、播放/停止控件作品、封面艺术作品和背景音频作品。我很难将控件添加到控制中心以在应用程序外播放/停止音频。我已经看过 Apple's Documentation 了,这很直接。我还启用了构建设置以允许后台获取、后台音频和蓝牙。但它似乎不适用于通过 USB-C 连接到 Xcode 的 iPhone(我假设 iOS 模拟器不支持控制中心)。下面是我的工作代码。关于如何让这个工作的任何想法?我需要将音频传递给 IMPLEMENT_SERIAL(ChildClass,Computer,1) 吗?我假设虽然标题和封面艺术需要从数据源传递,但总体而言,控制中心不会识别出该应用正在播放音频。

ViewController.swift

setupRemoteTransportControls()

Apple 建议添加控制中心支持

import UIKit
import MediaPlayer
import AVFoundation
import Foundation

class ViewController: UIViewController {

    var player: AVPlayer!
    var playerItem: AVPlayerItem!
    
    var audioCheck: Timer?
    var timer: Timer?
    
    var passText: String? = "Test"

    @IBOutlet weak var trackTitle: UILabel!
    @IBOutlet weak var togglePlay: UIButton!
    @IBOutlet weak var coverPhoto: UIImageView!

    func loadAudio() {
        let audioURL = URL.init(string: "AUDIO_URL_GOES_HERE")
        player = AVPlayer.init(url: audioURL!)
    }
    
    let minutes = 60

    func playAudio() {
               let audioURL = URL.init(string: "AUDIO_URL_GOES_HERE")
               player = AVPlayer.init(url: audioURL!)
               player.play()
           }
    
    @IBAction func OpenPlayer(_ sender: Any) {
        performSegue(withIdentifier: "PlayerSegue", sender: self)
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        loadAudio()
        
        
        // Audio in the background
        let audioSession = AVAudioSession.sharedInstance()
        
        do {
            try audioSession.setCategory(AVAudioSession.Category.playback)
        } catch {
            print("Error: Audio is not paying in the background.")
        }
        
        
        // Timer checking if other audio sources are running
        audioCheck = Timer.scheduledTimer(timeInterval: 0, target: self, selector: #selector(timedAudioCheck), userInfo: nil, repeats: true)
        struct currentTrack: Codable {
            let title: String
            let artwork_url: String
        }
        struct getTrack: Codable {
            // let name: String
            // let status: String
            let current_track: currentTrack
            
        }

        let jsonURL = URL(string: "JSON_URL_GOES_HERE")!
        URLSession.shared.dataTask(with: jsonURL) {data, _, _ in
            if let data = data {
                let trackData = try? JSONDecoder().decode([getTrack].self, from: data)
                // print(users)
                // print(trackData![0].current_track.title)
                // print(trackData![0].current_track.artwork_url)
                
                DispatchQueue.main.async {
          
                        self.trackTitle.text = trackData![0].current_track.title
                        let coverPhotoURL = trackData![0].current_track.artwork_url
                        if let coverPhotoConverted = URL(string: coverPhotoURL) {
                            do {
                                let coverPhotoData = try Data(contentsOf: coverPhotoConverted)
                                self.coverPhoto.image = UIImage(data: coverPhotoData)
                            } catch {
                                
                            }
                        }
                }
            }
        }.resume()
        
        _ = Timer.scheduledTimer(withTimeInterval: 10.0, repeats: true) { timer in
            // print("Data updated!")
           let jsonURL = URL(string: "JSON_URL_GOES_HERE")!
           URLSession.shared.dataTask(with: jsonURL) {data, _, _ in
               if let data = data {
                   let trackData = try? JSONDecoder().decode([getTrack].self, from: data)
                   // print(users)
                   // print(trackData![0].current_track.title)
                   // print(trackData![0].current_track.artwork_url)
                   
                   DispatchQueue.main.async {
             
                           self.trackTitle.text = trackData![0].current_track.title
                           let coverPhotoURL = trackData![0].current_track.artwork_url
                           if let coverPhotoConverted = URL(string: coverPhotoURL) {
                               do {
                                   let coverPhotoData = try Data(contentsOf: coverPhotoConverted)
                                   self.coverPhoto.image = UIImage(data: coverPhotoData)
                               } catch {
                                   
                               }
                           }
                   }
               }
           }.resume()
        }
        
        func setupRemoteTransportControls() {
        // Get the shared MPRemoteCommandCenter
        let commandCenter = MPRemoteCommandCenter.shared()

        // Add handler for Play Command
        commandCenter.playCommand.addTarget { [unowned self] event in
            if self.player.rate == 0.0 {
                self.player.play()
                return .success
            }
            return .commandFailed
        }

        // Add handler for Pause Command
        commandCenter.pauseCommand.addTarget { [unowned self] event in
            if self.player.rate == 1.0 {
                self.player.pause()
                return .success
            }
            return .commandFailed
        }
    }
        
        
        // Apple's Documentation on playing audio in control center
        func setupRemoteTransportControls() {
            // Get the shared MPRemoteCommandCenter
            let commandCenter = MPRemoteCommandCenter.shared()
        
            // Add handler for Play Command
            commandCenter.playCommand.addTarget { [unowned self] event in
                if self.player.rate == 0.0 {
                    self.player.play()
                    return .success
                }
                return .commandFailed
            }
        
            // Add handler for Pause Command
            commandCenter.pauseCommand.addTarget { [unowned self] event in
                if self.player.rate == 1.0 {
                    self.player.pause()
                    return .success
                }
                return .commandFailed
            }
        }
        
        func setupNowPlaying() {
            // Define Now Playing Info
            var nowPlayingInfo = [String : Any]()
            nowPlayingInfo[MPMediaItemPropertyTitle] = "My Movie"
        
            if let image = UIImage(named: "lockscreen") {
                nowPlayingInfo[MPMediaItemPropertyArtwork] =
                    MPMediaItemArtwork(boundsSize: image.size) { size in
                        return image
                }
            }
            nowPlayingInfo[MPNowPlayingInfoPropertyElapsedPlaybackTime] = playerItem.currentTime().seconds
            nowPlayingInfo[MPMediaItemPropertyPlaybackDuration] = playerItem.asset.duration.seconds
            nowPlayingInfo[MPNowPlayingInfoPropertyPlaybackRate] = player.rate
        
            // Set the metadata
            MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlayingInfo
        }
        

    }

    // Along with timer, checks if other audio sources are playing and resets the audio in the app
    @objc func timedAudioCheck() {
        if (AVAudioSession.sharedInstance().secondaryAudioShouldBeSilencedHint) {
            togglePlay.setTitle("Play", for: .normal)
        } else if (player.rate == 0) {
            togglePlay.setTitle("Play", for: .normal)
        } else {
            togglePlay.setTitle("Puase", for: .normal)
        }
    }
    
    @IBAction func togglePlay(_ sender: UIButton) {

        if player.rate == 0 {
            // Plays the audio stream
            sender.setTitle("Pause", for: .normal)
            playAudio()
        } else {
            sender.setTitle("Play", for: .normal)
            player.pause()
        }
    }
}

0 个答案:

没有答案