google / ExoPlayer

This project is deprecated and stale. The latest ExoPlayer code is available in https://github.com/androidx/media
https://developer.android.com/media/media3/exoplayer
Apache License 2.0
21.73k stars 6.03k forks source link

Support choosing preferred audio device #1993

Open keyboardr opened 8 years ago

keyboardr commented 8 years ago

Expose setPreferredDevice(AudioDeviceInfo) in AudioTrack on API 23+. This would allow developers to play audio on a specific output device.

elbekD commented 5 years ago

Hi! When this feature is going to be supported?

hendercine commented 5 years ago

Sadface... Just spent many days building a very specific exoPlayer only to discover that I can't setPreferredDevice. Any chance there is a known workaround to achieve this?

andrewlewis commented 5 years ago

I don't think there's a convenient workaround at the moment unless you fork/patch DefaultAudioSink to get access to its AudioTrack unfortunately.

The original plan was to expose a compatibility wrapper for AudioDeviceInfo. Pre-API 23 we'd list any available passthrough output options as separate devices and allow selection via the same API. However, maybe it's okay to just expose the API 23 method for now as a quick fix. I'll take a look.

keyboardr commented 5 years ago

FWIW, I have a fork (it's a few versions behind) that added this capability for my own app. It's not really suitable for a pull request, but could be a decent starting point. https://github.com/keyboardr/ExoPlayer/tree/output-device

hendercine commented 5 years ago

Thanks so much for your replies, kind sirs.

hendercine commented 5 years ago

The original plan was to expose a compatibility wrapper for AudioDeviceInfo. Pre-API 23 we'd list any available passthrough output options as separate devices and allow selection via the same API. However, maybe it's okay to just expose the API 23 method for now as a quick fix. I'll take a look.

Hi @andrewlewis . I checked out the YouTube video of yours and @ojw28's presentation at io 2017 btw and thought it was great. Anyway, I'm just wondering if you've had a chance to look into applying the quick fix as you mentioned above? I don't feel like my skills or time are up to the challenge of presenting a solution of my own, but if I could try with a little instruction perhaps...

@keyboardr I did try to implement the mods in your fork, but I was unable to get them to work. Again, it appears my skills are not quite that advanced... yet. ( ^ – ^ )

elbekD commented 5 years ago

@andrewlewis

Hi every one once again! Sorry for off top, but is there a solid way to set preferred output device for an application sounds that it will not reroute, for example, sounds from third party apps like music app?

AudioTrack#setPreferredDevice helps, but it doesn't work on some devices, especially, on Xiaomi Redmi x4 doesn't work, but on nexus 5x or nexus 6 it works. Maybe you can advise some sources to read and explore.

Thanks in advance!

hendercine commented 5 years ago

Any movement on this?

andrewlewis commented 5 years ago

I'm afraid not. I'll plan to update this issue when we get round to it.

keyboardr commented 4 years ago

FWIW, I was able to change how I do this in my app so that I don't need to fork the entirety of ExoPlayer anymore. I made a copy of DefaultAudioSink (with the same package name as the original). My copy has three differences (besides renaming the class): it's not final, audioTrack is protected, and the initialize(long) method was modified so that the AudioTrack creation was extracted to a protected method. I then have my own AudioSink class extend from it. My AudioSink's override mostly just copies the buildAudioTrack() method of DefaultAudioSink.Configuration, but also sets the preferred output device at the end. This could have been even simpler (just adding a protected method called after buildAudioTrack() in initialize()), but I also wanted to set the performance mode of the AudioTrack.

I then have another class extend MediaCodecAudioRenderer to inject the AudioSink and handle messaging (for changing the preferred output). There's also a class that extends DefaultRenderersFactory to override buildAudioRenderers(). Finally I have a class extending SimpleExoPlayer to put it all together and send my custom message whenever the output needs changing.

Now instead of a careful rebase with all of ExoPlayer, I only need to worry about updating two classes, one of which rarely needs anything changed. It would still be better if DefaultAudioSink allowed this level of modification directly, and even better if ExoPlayer had this functionality out of the box.

PratimMallick commented 4 years ago

@andrewlewis Please update this. There are a lot of users on S/PDIF who are unable to get proper eac3 because exoplayer does not detect and allow passthrough via optical cable

stevemayhew commented 4 years ago

@andrewlewis we are working a number of issues with our customers around audio routing, not an easy problem.

The universe of Android STB's we support includes everything from the simple (Xiaomi MI, with Bluetooth, Optical micro SPIDF, headphone, HDMI) to boxes that even include composite video connectors.

Pass-thru is particularly tricky, we have experienced vendor and android platform code that did not support correctly reporting the user settings for Pass-thru, so this could be part of the issue. The bug cause the STB not to report correct (MediaCodecInfo) so ExoPlayer could not properly select the raw (pass-thru) codec.

We have @sneelavara working this issue for us, we would be happy to contribute with testing as well as coding. Our preference would be to support a TrackSelection API to express the requested audio path, the decision for how to set this could come from watching the MediaRouter API's