MPRemoteCommandCenter - 锁定屏幕上的远程控制不显示

MPRemoteCommandCenter - Remote controls on lock screen does not show up

我在视图控制器中实现了两个函数(setupRemoteTransportControls() 和 setupNowPlaying())并向 AppDelegate 添加了一个函数,但我仍然无法在锁定屏幕上看到我的应用程序的背景音频控件,而且音频中断功能不工作。这是来自 url 的直播,您可以在代码中看到这一点。在常规设置中我添加了后台播放:

我想做的是在 Remote Command Center 艺术家、标题和 albumArt 标签和 UIImage 上打印(UIImage 标签取自我的站点 API),但我只是显示指挥中心。这是我的代码:

import UIKit
import AVKit
import MediaPlayer
class ViewController: UIViewController, AVAudioPlayerDelegate {

@IBAction func buttonPressed(_ sender: UIButton){
              if isPlaying {
                   player.pause()
                   sender.setImage(playImage, for: .normal)
              } else {
                   let url = "https://myradio.com/radio.mp3"
                   do {
                        try AVAudioSession.sharedInstance().setCategory(.playback, mode: .default, options: [.mixWithOthers, .allowAirPlay])
                        try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.playback, options: [])
                        print("Playback OK")
                        try AVAudioSession.sharedInstance().setActive(true)
                        print("Session is Active")
                   } catch {
                        print(error)
                   }
                   
                   player = AVPlayer(url: URL(string: url)!)
                   player.volume = 1.0
                   player.rate = 1.0
                   player.play()
                sender.setImage(pauseImage, for: .normal)
              }
              
              isPlaying.toggle()
         }


    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        overrideUserInterfaceStyle = .light
        setupRemoteTransportControls()
        requestNowPlaying()
        setupNowPlaying()
    }

// Here is the API data downloading part, so i skipped it 


    //Command Center audio controls
    
    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 == 1.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] = "Test"

        if let image = UIImage(named: "Default_albumart") {
            nowPlayingInfo[MPMediaItemPropertyArtwork] = MPMediaItemArtwork(boundsSize: image.size) { size in
                return image
            }
        }
        nowPlayingInfo[MPNowPlayingInfoPropertyIsLiveStream] = true
        

        // Set the metadata
        MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlayingInfo
    }


    func updateNowPlaying(isPause: Bool) {
        // Define Now Playing Info
        let nowPlayingInfo = MPNowPlayingInfoCenter.default().nowPlayingInfo!

        //nowPlayingInfo[MPNowPlayingInfoPropertyElapsedPlaybackTime] = player.currentTime
        //nowPlayingInfo[MPNowPlayingInfoPropertyPlaybackRate] = isPause ? 0 : 1

        // Set the metadata
        MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlayingInfo
    }
    

    
    
//audio interruption
    @objc func handleInterruption(notification: Notification) {
        guard let userInfo = notification.userInfo,
                let typeValue = userInfo[AVAudioSessionInterruptionTypeKey] as? UInt,
                let type = AVAudioSession.InterruptionType(rawValue: typeValue) else {
                    return
            }

            // Switch over the interruption type.
            switch type {

            case .began:
                print("Interruption began")
                

            case .ended:
               // An interruption ended. Resume playback, if appropriate.

                guard let optionsValue = userInfo[AVAudioSessionInterruptionOptionKey] as? UInt else { return }
                let options = AVAudioSession.InterruptionOptions(rawValue: optionsValue)
                if options.contains(.shouldResume) {
                    player.play()
                } else {
                    // An interruption ended. Don't resume playback.
                }

            default: ()
            }
        }
    
            
    
}

这是我在我的 AppDelegate.swift 中添加的内容:

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        application.beginReceivingRemoteControlEvents()
     //    Override point for customization after application launch.
       return true
    }

从您的类别选项中删除 .mixWithOthers。 我认为原因是只有主 iOS 音频应用程序可以控制远程屏幕。 .mixWithOthers 用于辅助音频应用。

使用此代码将您自己标识为 .longForm 音频内容提供商:

try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback, mode: AVAudioSessionModeDefault, routeSharingPolicy: .longForm)

要了解 AirPlay2 的完整实现,请查看此 Apple WWDC 演示文稿:https://developer.apple.com/videos/play/wwdc2017/509/