Swift iOS MPNowPlayingFoCenter不使用AVPlayer和AVAudioSession显示
我正在构建一个广播流应用程序。声音正常,包括应用程序处于后台和手机锁定时。但是,我无法在锁定屏幕上显示MediaPlayer信息 我正在尝试使用Swift iOS MPNowPlayingFoCenter不使用AVPlayer和AVAudioSession显示,swift,avplayer,avaudiosession,mpnowplayinginfocenter,Swift,Avplayer,Avaudiosession,Mpnowplayinginfocenter,我正在构建一个广播流应用程序。声音正常,包括应用程序处于后台和手机锁定时。但是,我无法在锁定屏幕上显示MediaPlayer信息 我正在尝试使用AVPlayer、AVAudioSession和mpnowplayingfocenter的组合。我已经研究了关于stackoverflow()的其他问题,但他们的解决方案似乎对我不起作用 我将尝试展示我的应用程序的重要方面: Info.plist 添加了所需的背景模式:应用程序使用AirPlay播放音频或流式音频/视频 AppDelegate.swift
AVPlayer
、AVAudioSession
和mpnowplayingfocenter
的组合。我已经研究了关于stackoverflow()的其他问题,但他们的解决方案似乎对我不起作用
我将尝试展示我的应用程序的重要方面:
Info.plist
添加了所需的背景模式:应用程序使用AirPlay播放音频或流式音频/视频
AppDelegate.swift
我将以下代码添加到didfishlaunchingwithoptions
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
视图控制器
在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
]
}
一件奇怪的事情是,当我添加行mpnowplayingfocenter.default().playbackState=.playing
时,会显示MediaPlayer。不过,当我在实际手机上进行测试时(与模拟器相比),应用程序停止了,因为该属性仅适用于MacOS
当应用程序正在播放流媒体时,我尝试打开Youtube,Youtube视频将以静音启动。这让我觉得手机可以识别我的应用程序的音频。此外,当我在运行setNowPlayingInfo()
后调用print(mpNowPlayingFoCenter.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上测试时,锁屏信息显示得非常完美。不过,它仍然没有显示在模拟器上。谢谢您抽出时间。谢谢您的回答!我不熟悉断点,但我在try session.setActive(true)
行中放置了一个断点,它被触发了。这里是我在这里检查的一些变量:AVAudioSession.sharedInstance().outputVolume
=0.6AVAudioSession.sharedInstance().outputDataSource
=nilAVAudioSessionCategor
y=rawValue:AVAudioSessionCategoryPlayback
。缺少“输出数据源”是否表明存在问题?