问题描述
我正在构建一个广播流媒体应用。声音有效,包括应用程序在后台和手机锁定时。但是,我无法在锁定屏幕上显示 MediaPlayer 信息。
我正在尝试使用 AVPlayer
、AVAudioSession
和 MPNowPlayingInfoCenter
的组合。我查看了有关 Stack Overflow (this one,especially) 的其他问题,但他们的解决方案似乎对我不起作用。
我将尝试列出我的应用的重要方面:
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) }
@H_404_31@然后我覆盖了
remoteControlReceived
override func remoteControlReceived(with event: UIEvent?) { let rc = event!.subtype print("does this work? \(rc.rawValue)") }
@H_404_31@流媒体模型
在结构体中,我使用
AVPlayer
创建了一个无线电模型。流成功发送到 ViewController。视图控制器
在viewDidLoad中,运行如下代码
override func viewDidLoad() { super.viewDidLoad() self.becomeFirstResponder() UIApplication.shared.beginReceivingRemoteControlEvents() }
@H_404_31@我还按照另一个教程覆盖了 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.]) } }
@H_404_31@最后,我编写了以下函数,我在阅读新教程时一直在添加该函数。我在流开始播放后运行此函数:
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 ] }
@H_404_31@一件奇怪的事情是,当我添加了
MPNowPlayingInfoCenter.default().playbackState = .playing
行时,会显示 MediaPlayer。但是,当我在实际手机上对其进行测试时(与模拟器相比),该应用会停止运行,因为该属性仅适用于 MacOS。当应用正在流式传输时,我尝试打开 Youtube,YouTube 视频开始静音。这让我觉得手机可以识别我的应用程序的 AVAudioSession。此外,当我在运行
print(MPNowPlayingInfoCenter.default().NowPlayingInfo?[MPMediaItemPropertyTitle])
后调用setNowPlayingInfo()
时,会打印正确的信息。非常感谢任何建议。对于这个很长的问题,我深表歉意。
编辑
这个问题可能是因为我的 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 }
@H_404_31@解决方法
你的代码看起来不错,你不需要第一响应者的东西。
在您的
AVAudioSession
配置上放置一个断点并确保它确实被调用或检查其日志输出是否存在。通过锁定屏幕和聆听来确保您的音频在后台正常工作。
您还需要实际播放音频以影响正在播放的信息屏幕。
,好的,我解决了。我的应用程序很好;问题是模拟器的行为不像实际设备。当我在实际的 iPad 上测试时,锁屏信息显示完美。但是,它仍然没有显示在模拟器上。感谢您抽出宝贵时间。