Reputation: 454
I'm trying to implement player controls on iOS lock screen for my Remote Control application that controls Music Player on PC. So basically I need to control playback outside of iOS device. I've enabled Background Modes in capabilities (Audio) and tried to set MPRemoteCommandCenter lock screen controls, but they aren't shown. Here is code:
class RemoteCommandHandler: NSObject {
static let shared = RemoteCommandHandler()
private let player = AVPlayer()
private let audioSession = AVAudioSession.sharedInstance()
private let commandCenter = MPRemoteCommandCenter.shared()
func initRemote() {
//UIApplication.shared.beginReceivingRemoteControlEvents()
do {
if #available(iOS 10.0, *) {
try audioSession.setCategory(.playback, mode: .default, options: [])
} else {
// Fallback on earlier versions
try audioSession.setCategory(.playback)
}
} catch {
NSLog("\(error)")
}
do {
try audioSession.setActive(true)
NSLog("AVSession is active")
} catch {
NSLog("\(error)")
}
setupRemoteTransportControls()
setupNowPlaying()
}
func setupRemoteTransportControls() {
commandCenter.togglePlayPauseCommand.isEnabled = true
commandCenter.togglePlayPauseCommand.addTarget(self, action: #selector(controlPlayPause))
}
func setupNowPlaying() {
var nowPlayingInfo = [String : Any]()
nowPlayingInfo[MPMediaItemPropertyTitle] = NowPlayingInfo.getValue(.Title)
if let image = UIImage(named: "DemoArtwork") {
nowPlayingInfo[MPMediaItemPropertyArtwork] = MPMediaItemArtwork(image: image)
}
nowPlayingInfo[MPNowPlayingInfoPropertyElapsedPlaybackTime] = TimeInterval(exactly: 10)
nowPlayingInfo[MPMediaItemPropertyPlaybackDuration] = NowPlayingInfo.getDurationMs() / 1000
nowPlayingInfo[MPNowPlayingInfoPropertyPlaybackRate] = 1.0
MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlayingInfo
}
}
Is it even possible to do what I want? What I'm doing wrong?
Upvotes: 2
Views: 1789
Reputation: 454
It looks like the only possible way to have controls on lock screen is to initiate playback of real audio file from your app. I did a workaround of very short silent file playback on app startup and now I have access to those controls.
Keep in mind that Background Mode (Audio) should be enabled in order to see controls while your app is not on the screen.
Another limitation is that Volume control is hard-wired to device volume, so you cannot change app volume separately.
Here is the minimal code to enable controls:
import MediaPlayer
import AVFoundation
class RemoteCommandHandler: NSObject {
static let shared = RemoteCommandHandler()
private var player: AVPlayer!
private var playerItem: AVPlayerItem!
private let audioSession = AVAudioSession.sharedInstance()
private let commandCenter = MPRemoteCommandCenter.shared()
func initRemote() {
let sound = Bundle.main.path(forResource: "SilenceAAC", ofType: "m4a")
playerItem = AVPlayerItem(url: URL(fileURLWithPath: sound!))
player = AVPlayer(playerItem: playerItem)
do {
if #available(iOS 10.0, *) {
try audioSession.setCategory(.playback, mode: .default, options: [])
} else {
// Fallback on earlier versions
try audioSession.setCategory(.playback)
}
try audioSession.setActive(true)
NSLog("AVSession is active - \(audioSession)")
} catch {
NSLog("\(error)")
}
setupNowPlaying()
setupRemoteTransportControls()
player.play()
}
func setupRemoteTransportControls() {
commandCenter.togglePlayPauseCommand.addTarget(self, action: #selector(controlPlayPause))
}
func setupNowPlaying() {
var nowPlayingInfo = [String : Any]()
nowPlayingInfo[MPMediaItemPropertyTitle] = NowPlayingInfo.getValue(.Title)
MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlayingInfo
}
}
Upvotes: 2