1

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

ViewController.swift

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()
        }
    }
}

苹果建议增加控制中心支持

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
}
4

0 回答 0