SwiftUI: showing AVPlayer playback (media) on locked screen

I am trying to show AVPlayer controls and audio info on the locked screen, but it is not working. Please consider example below.

Code Block swift
import SwiftUI
import MediaPlayer
import AVFoundation
class ViewModel: ObservableObject {
@Published var isPlaying = false
private let audioSession = AVAudioSession.sharedInstance()
private let player = AVPlayer()
init() {
if let path =
Bundle.main.path(forResource: "5.mp3", ofType: nil) {
let asset = AVAsset(url: URL(fileURLWithPath: path))
let playerItem = AVPlayerItem(asset: asset)
player.replaceCurrentItem(with: playerItem)
}
try! self.audioSession.setCategory(AVAudioSession.Category.playback)
try! self.audioSession.setActive(true)
setupRemoteTransportControls()
setupNowPlaying()
}
func setupRemoteTransportControls() {
let commandCenter = MPRemoteCommandCenter.shared()
commandCenter.playCommand.isEnabled = true
commandCenter.playCommand.addTarget { [unowned self] event in
if !self.isPlaying {
self.play()
return .success
}
return .commandFailed
}
commandCenter.pauseCommand.isEnabled = true
commandCenter.pauseCommand.addTarget { [unowned self] event in
if self.isPlaying {
self.pause()
return .success
}
return .commandFailed
}
}
func setupNowPlaying() {
// Define Now Playing Info
var nowPlayingInfo = [String : Any]()
nowPlayingInfo[MPMediaItemPropertyTitle] = "My Movie"
if let image = UIImage(named: "lockscreen") {
nowPlayingInfo[MPMediaItemPropertyArtwork] =
MPMediaItemArtwork(boundsSize: image.size) { size in
return image
}
}
nowPlayingInfo[MPNowPlayingInfoPropertyElapsedPlaybackTime] = player.currentItem?.currentTime().seconds
nowPlayingInfo[MPMediaItemPropertyPlaybackDuration] = player.currentItem?.asset.duration.seconds
nowPlayingInfo[MPNowPlayingInfoPropertyPlaybackRate] = player.rate
// Set the metadata
MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlayingInfo
}
func play() {
isPlaying.toggle()
player.play()
}
func pause() {
isPlaying.toggle()
player.pause()
}
}
struct ContentView: View {
@StateObject private var viewModel = ViewModel()
var body: some View {
Button(action: {
if viewModel.isPlaying {
viewModel.pause()
} else {
viewModel.play()
}
}, label: {
Image(systemName: viewModel.isPlaying ? "pause" : "play")
})
}
}

Does anybody has any clue what am i missing to make it work with SwiftUI?

I also tried to add beginReceivingRemoteControlEvents but it does not make any difference
Code Block swift
struct PlayerApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var delegate
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
class AppDelegate: NSObject, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
application.beginReceivingRemoteControlEvents()
return true
}
}


The audio is playing ok with the locked screen, it is just there is no playback controls and media info

Tested with Xcode 12.4, iphone-12 simulator

Answered by zhikharev in 666385022
The solution I found is: changing AVAudioSession's category to: .playAndRecord
Accepted Answer
The solution I found is: changing AVAudioSession's category to: .playAndRecord
SwiftUI: showing AVPlayer playback (media) on locked screen
 
 
Q