I'm implementing AirPlay support in a podcast app. I added an AVRoutePickerView
and the AirPlay devices are loading fine and I can connect to a device successfully.
I'm testing in an Apple TV and the audio plays well but it's using always the max volume and I can't change it. The volume slider is disabled and I can't understand why that's happening because it works in other apps.
For example, I can change the volume in Overcast has expected and the audio doesn't start with the max volume:
What am I doing wrong? Am I missing any option.
UPDATE:
I'm using an AVPlayer
and allowsExternalPlayback
property is true.
UPDATE2:
The same issue happens with MPVolumeView
.
Some Reddit users told me "It assumes a person would use the volume control of the output device (TV, sound system, etc) to control the volume.", "Like when you plug a MacBook into a tv via hdmi", and it makes sense but how can I force to not use the output device to control the volume? It works as I expected in other podcast apps.
After discussion with a DTS Engineer, he found a workaround (rdar://42881405 Volume control is disabled when connected to Apple TV using AirPlay).
"According to engineering, the disabling of the volume control is correct behavior for certain Apple TV configurations, where the audio is being sent to the actual TV via HDMI. In that case, volume is controlled by the TV itself.
An alteration to this standard behavior is made for audio-only apps (such as Podcasts and Overcast). In those cases, the volume control is enabled anyway, and it provides a software volume adjustment of the audio in addition to the hardware volume control. The reason you weren’t getting this is that you used AVQueuePlayer, which is regarded as a video player, not a pure audio player. I modified your sample project to use AVAudioPlayer instead, and the volume control was enabled for AirPlay output as expected.
However, AVAudioPlayer cannot play streamed assets, so it may not be a viable solution in your use case. I’m still researching whether the audio-only behavior can be obtained for other playback techniques."
Basically, setting allowsExternalPlayback
property of an AVPlayer/AVQueuePlayer to false
will disallow the routing of video playback to AirPlay, and (as a side-effect) allows the pure audio playback.
Even so, I think that using the new AVSampleBufferAudioRenderer
and AVSampleBufferRenderSynchronizer
classes would also work but they are way more complex to setup.
rdar://42966681 as been created: Provide an API for designating an app using AVPlayer/AVQueuePlayer as "audio-only".