Search code examples
iosavfoundationavplayerairplay

AirPlay: volume control is disabled when connected to Apple TV


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.

enter image description here

For example, I can change the volume in Overcast has expected and the audio doesn't start with the max volume:

enter image description here

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.


Solution

  • 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."

    Solution:

    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.

    Final note:

    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".