我正在构建一个广播流应用程序。声音正常工作,包括应用程序在后台和手机锁定时。但是,我无法将MediaPlayer信息显示在锁定屏幕上。
我正在尝试使用AVPlayer
、AVAudioSession
和MPNowPlayingInfoCenter
的组合。我已经看了关于Stack Overflow的其他问题(尤其是这一个(,但他们的解决方案似乎对我不起作用
我将尝试布局我的应用程序的重要方面:
信息.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。不过,当我在实际手机上测试它时(与模拟器相比(,该应用程序会停止,因为该属性仅适用于MacOS。
当应用程序正在流媒体播放时,我尝试打开Youtube,Youtube视频会以静音方式开始。这让我觉得手机可以识别我的应用程序的AVAudioSession。此外,当我在运行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上测试它时,锁屏信息显示得很完美。不过,它仍然没有显示在模拟器上。谢谢你抽出时间。