iOS MPNowPlayingInfoCenter 不显示使用 AVPlayer 和 AVAudioSession

iOS MPNowPlayingInfoCenter not Displaying Using AVPlayer and AVAudioSession

我正在构建一个广播流媒体应用程序。声音正常,包括当应用程序处于后台时以及 phone 被锁定时。但是,我无法让 MediaPlayer 信息出现在锁定屏幕上。

我正在尝试使用 AVPlayerAVAudioSessionMPNowPlayingInfoCenter 的组合。我查看了有关 Stack Overflow () 的其他问题,但他们的解决方案似乎对我不起作用。

我将尝试列出我的应用程序的重要方面:

Info.plist

已添加Required background modes: App plays audio or streams audio/video using AirPlay

AppDelegate.swift

我在 didFinishLaunchingWithOptions

中添加了以下代码
do {
            try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.playback)
            print("Playback OK")
            try AVAudioSession.sharedInstance().setActive(true)
            print("Session is Active")
        } catch {
            print(error)
        }

然后我覆盖了remoteControlReceived

override func remoteControlReceived(with event: UIEvent?) {
        let rc = event!.subtype
                print("does this work? \(rc.rawValue)")
    }

流模型

在一个结构中,我使用 AVPlayer 创建了一个无线电模型。流已成功发送到 ViewController.

ViewController

在viewDidLoad中,下面的代码是运行

override func viewDidLoad() {
        super.viewDidLoad()
        self.becomeFirstResponder()
        UIApplication.shared.beginReceivingRemoteControlEvents()
}

我还在 ViewController 中覆盖了以下两个函数,遵循另一个教程:

override var canBecomeFirstResponder: Bool {
        return true;
    }
    
    override func remoteControlReceived(with event: UIEvent?) {
        let type = event?.subtype
        
        if (type == UIEvent.EventSubtype.remoteControlTogglePlayPause) {
            //if ([self.radioManager.player.])
            
        }
        
    }

最后,我编写了以下函数,我在阅读新教程时一直在添加它。我运行流开始播放后的这个功能:

func setNowPlayingInfo() {

        
        UIApplication.shared.beginReceivingRemoteControlEvents()
        MPRemoteCommandCenter.shared()
        MPRemoteCommandCenter.shared().playCommand.addTarget {event in
              return .success
            }
            MPRemoteCommandCenter.shared().pauseCommand.addTarget {event in
              return .success
            }
            MPRemoteCommandCenter.shared().nextTrackCommand.addTarget {event in
              return .success
            }
            MPRemoteCommandCenter.shared().previousTrackCommand.addTarget {event in
              return .success
            }
        
        var nowPlayingInfo = [String: Any]()
        // prepare title and subtitle
        nowPlayingInfo[MPMediaItemPropertyTitle] = "Test"
    
        MPNowPlayingInfoCenter.default().nowPlayingInfo = [
            MPMediaItemPropertyTitle: self.trackTitle.text,
            MPMediaItemPropertyArtist: self.nameLabel.text
        
        ]
    }

一件奇怪的事情是,当我添加行 MPNowPlayingInfoCenter.default().playbackState = .playing 时,会显示 MediaPlayer。当我在实际 phone 上对其进行测试时(与模拟器相比),应用程序停止了,因为 属性 仅适用于 MacOS。

当应用程序正在播放时,我尝试打开 Youtube,YouTube 视频开始静音。这让我觉得 phone 识别了我的应用程序的 AVAudioSession。此外,当我在 运行ning setNowPlayingInfo() 之后调用 print(MPNowPlayingInfoCenter.default().nowPlayingInfo?[MPMediaItemPropertyTitle]) 时,会打印正确的信息。

非常感谢任何建议。对于这个很长的问题,我深表歉意。

编辑

这个问题可能是我的AVPlayer没有正确初始化造成的?这是 .swift 文件中的初始化代码,它通过委托

与视图控制器通信
struct RadioManager {
    var player: AVPlayer = AVPlayer.init()
    var streamPlaying = false
    var badRadioURL = "http://server.badradio.biz:8000/"
    var delegate: RadioManagerDelegate?
    
    mutating func initializeRadio() {
        let urlString = "\(badRadioURL)stream"
        guard let url = URL.init(string: urlString)
                else {
                    return
            }
        let playerItem = AVPlayerItem.init(url: url)
        player = AVPlayer.init(playerItem: playerItem)
    }
    
    mutating func stream() {
        print("loading")
    
        player.play()
        streamPlaying = true
    
    }

你的代码看起来不错,你不需要第一响应者的东西。

在您的 AVAudioSession 配置上放置一个断点并确保它确实被调用或检查它的日志输出是否存在。

锁定屏幕并收听以确保您的音频在后台运行。

您还需要实际播放音频才能影响正在播放的信息屏幕。

好的,我解决了。我的应用程序很好;问题是模拟器不像实际设备那样运行。当我在实际 iPad 上测试它时,锁屏信息显示完美。不过,它仍然没有显示在模拟器上。谢谢你的时间。