CarPlay outputs no audio

I have an application that includes custom artwork for the album cover and text details setup with the MPRemoteCommandCenter.shared() reference. I need the user to have a full featured "now playing" display to see all of this. My experience is that cannot find a set of parameters for AVAudioSession.setCategory() that route audio successfully, and display the full featured now playing deck.

If I use .playAndRecord, the audio I send out plays out on the radio. But, the now-playing deck is empty and nothing I do with the command center seems to change that. If I instead use .playback, I cannot use .defaultToSpeaker option which is the only way I've found to cause the "now-playing" navigation button to appear so that the full featured deck will display. But, of course setCategory() fails with an error about .defaultToSpeaker only available with .playAndRecord, so some default or intermediate state is entered and I see the full featured deck, but no audio goes out to the radio.

What combination is supposed to be used here and is this more likely a problem with thread use (@MainActor) and/or some ordering of operations that I've overlooked?

I am not sure if there is just no-one doing much with car play audio, or if there is something unclear with the above text. What I have found is that I cannot get the navigation to the now-playing deck to appear on the radio without using .playback category and also specifying .defaultToSpeaker which is not an acceptable combination. I have to use session.setActive(false) before trying to set the category, and then catch the error thrown, and then use .setActive(true) after the error and then things work. The is the only way I seem to be able to set the artist, album title and artwork on the radio to make it visible to the users.

				do {
					try session.setActive(false)
					try session.setCategory(.playback, mode: .default, options: [
						.defaultToSpeaker,
						.allowBluetoothA2DP,
						.mixWithOthers
					])
					try session.setActive(true)

					logRoute("setCategory(.playback) [CarPlay]")
				} catch {
					try session.setActive(true)
					logRoute("setCategory(.playback) [CarPlay] failed: \(error)")
				}

This block just doesn't seem like the right thing to do.

.playAndRecord does not seem to allow anything about the now-playing deck to be configured and the navigation button does not appear. I have to push the now-playing view to see it, but it's blank with none of the details I've set with code like:

let info = nowPlayingInfo()
MPNowPlayingInfoCenter.default().playbackState = dataValue != nil ? .playing : .stopped
MPNowPlayingInfoCenter.default().nowPlayingInfo = info

Ultimately, there seems to be quite a bit of integration into "music" playing, but I need my audio to come through AVAudioSession/AVAudioEngine because it's raw, streaming audio. I have meta data to display and so the now-playing Deck seems like the best place to put that meta data because there is already so much provided with the play/pause buttons and the album cover image. If I use .playAndRecord, the now-playing dev navigation button does not appear. If I use .playback, the button does not appear unless I create an error by also trying to use .defaultToSpeaker. What is it that I cannot get the now-playing deck navigation button to appear?

Thanks for the post

I believe iOS categorizes it as a secondary audio source, by design, secondary audio sources are not allowed to take over the system's Now Playing deck. The Now Playing screen (and the navigation button to reach it in CarPlay) is strictly reserved for the primary media app.

.defaultToSpeaker and .allowBluetoothA2DP are strictly invalid for the .playback category as they are only for .playAndRecord.

I believe, you need to use the .playback category without any options that downgrade your app to a secondary audio source or conflict with the category as CarPlay is very strict about when it shows the Now Playing button. CarPlay often refuses to show the Now Playing icon in the navigation bar until the app has actually pushed audio buffers through the active AVAudioSession.

Remove .mixWithOthers and the invalid flags, ensure your playback state is set to .playing, and the CarPlay Now Playing deck should behave exactly as expected?

https://developer.apple.com/documentation/AVFAudio/AVAudioSession

Hope a CarPlay engineer jumps into this thread to provide better guidance instead of my gut feeling based on secondary audio source to primary one.

Albert 
  Worldwide Developer Relations.

CarPlay outputs no audio
 
 
Q