-
Notifications
You must be signed in to change notification settings - Fork 6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Ability to switch audio track during playback #514
Comments
It seems only SS and Dash are support switch between multiple audio tracks. Those have implement MultiTrackChunkSource. |
Correct. Also, when we implement this for HLS, we'll use MultiTrackChunkSource there as well. I think we're less interested in the ExtractorSampleSource case in general, since muxing multiple tracks of the same type into a single stream is fundamentally not the best approach (DASH or SS is always going to be better if you want multiple tracks of the same type). If you were to add support, however, doing it at the ExtractorSampleSource layer would be more consistent with the model used elsewhere. You shouldn't need multiple renderers. It should be possible to switch track by (1) pause, (2) disable renderer, (3) reconfigure sample source to provide samples for a different track, (4) re-enable renderer [if applicable], (5) unpause [if applicable]. Like: Step (3) is something you'd need to implement. |
I completely understand and agree that there might be better formats out there which handle multiple tracks of the same type. However, since it's basically common practice to store multiple audio tracks within a single MP4/MKV/whatever, it does feel like a useful/important feature to support. I've had a go at working through what you suggested, and still struggling a little. The renderer and selected track within the sample source are fairly tightly coupled, the If I start changing the ExoPlayer source to allow
I'm sorry, but is there any other way to do this cleanly? I'm trying to avoid deviating from the standard ExoPlayer source as much as possible (to ensure it's easier to pick up changes). |
Just a quick update, but I have got things working using the following code: A custom audio codec renderer:
Code to switch the audio track:
The thing that's not possible without modifying the ExoPlayer source is the Would that change be considered? |
This looks like a related issue: #168 |
In my proposal there would be a single track exposed by the sample source, and the switching would be hidden behind it. The approach definitely works; if you look at how we do it for DASH/SS, it's following that approach. Having said that, it seems things would be better if track switching were made more of a first class citizen of ExoPlayer. I think we should do the following, which should be good for what you need:
We'll need to figure out what an appropriate TrackInfo object is. It will need to contain more than the current TrackInfo object. To implement multi-track selection in an app you'd then:
It may also make sense to merge setRendererEnabled into this new API. Disabling a renderer could be implemented by calling selectTrack(renderer, -1). Thoughts? |
I have a version of this working, but it's pretty major surgery through the code-base. It'll likely be a few weeks until it's all merged. |
Assume you are going to use 2 separate chunk sources for this use case? 1 for video and the MultiTrackChunkSource for the various audio tracks? If so, there is a big risk the two will not correctly synchronize audio since the loading of playlists can (and will) happen at different times and under the right circumstances, the player will choose different start segments to start with. For example: Video playlist is loaded and contains sequence numbers 5,6,7,8,9,10 - playback will start with 8 So, there is a need to synchronize this somehow between the chunk sources. Perhaps you have already considered this but I thought I'd bring it up. |
This request is unrelated to HLS. Multi-audio in HLS is tracked by #73. |
My bad - will the work you are doing here bring #73 closer to being implemented too? In any case, will re-post this there. |
It will provide plumbing for passing track information through common player components, so yes it will help. |
where download the source code that the MediaCodecAudioTrackRenderer Ability to switch audio track |
Hey @ojw28, any updates on how this is progressing? If there is anything I can do to help out, please just let me know! |
We'll start merging some steps towards this soon. The first one will create a common base class for all TrackRenderer implementations that pull samples from a SampleSource, so as to avoid having to add multi-track propagation logic in multiple renderers separately. We'll then start merging code to actually propagate the tracks through the various components. Initially we'll be exposing fairly useless information about each track, although once we're at that point the task of populating the information properly can probably be parallelised to some extent. |
BTW, when will it be done? We also need this feature. |
This will allow multi-track support when consuming from a SampleSource to be added in a single class, rather than in 6. Prep for Issue #514.
- Generalize rendererEnabledFlags to be selected track indices through ExoPlayerImpl/ExoPlayerImplInternal. - Selecting an out-of-bound track index (e.g. -1) is equivalent to disabling a renderer prior to the generalization. - A prepared TrackRenderer that exposes 0 tracks is equivalent to a TrackRenderer in the STATE_IGNORE state prior to the generalization. Issue #514.
multi-track support upstream to the ChunkSource interface. This change does not yet make use of the newly exposed APIs. This will come in a subsequent CL. Issue #514.
When ChunkSource implementations implement multi-track for DASH and SS, format selection will move inside of ChunkSource. If we, for example, fail to query the decoder to determine which tracks are playable, we need an opportunity to fail (i.e. say we're not prepared, so that maybeThrowError is called, from which we can throw). This may go away in the future if we remove the distinct preparation step and treat tracks/formats as things that can change dynamically, but for now this is what we have. Issue #514.
- Migrate demo app to use new APIs. - Add multi-track support for ExtractorSampleSource case. - Add multi-track support for SmoothStreaming use case. The final step is to add support back for the DASH use case and delete MultiTrackChunkSource. This is blocked on multi-period support landing, in order to prevent a horrendous merge conflict. We also need to update HLS to expose sensible track information. Issue: #514
Status update:
|
|
Does this means it will also be supported to mute the video while it's playing? (by switching to a null/empty audio track) |
@dnutcracker: you should be able to achieve this already by doing something like this in your ExoPlayer interface (equivalent of the DemoPlayer class of the demo app): |
This has been possible for a long time (the demo app has had this ability for a long time too). Using ExoPlayer's setRendererEnabled method is the best way to do it in the current release. |
Ok.Thanks. On Fri, Aug 21, 2015 at 12:30 PM, ojw28 notifications@github.com wrote:
|
- Video track is always marked as adaptive, the resolution is stripped out (since it's otherwise just set to whatever the resolution of the first selected variant is), and the max dimensions are set. Issue #514
|
I'm attempting to add support to our video player that allows individual audio tracks to be selected during playback. Initially i'm focussing on my ExtractorRendererBuilder (with MP4s) but this really affects any media which can contain multiple different audio tracks.
First Issue
MediaCodecAudioTrackRenderer
by default will select, and use, the first audio track provided by theSampleSource
. It therefore seemed appropriate to extend this class and override thehandlesMimeType
used duringonPrepare
in order to try and "select" the audio stream that you want. A problem then arrises that "mimeType" is not a unique identifier within a video. For example, you could easily have an MP4 which has 2 AAC tracks, the main feature vs the directors commentary. In order to make it easier to identify individual tracks, it might be worth considering including thetrackIndex
into the method, for example:With this change in place, it should then be possible to create N individual audio track renderers (one for each known audio track), and to disable / enable them on demand.
Second Issue
There are two possible (related) issues with what I described above:
MediaCodecAudioTrackRenderer
?The audio tracks are available via the
SampleSource
but this is prepared after theMediaCodecAudioTrackRenderer
's have been created. I therefore looked at what it would take to have a singleMediaCodecAudioTrackRenderer
that when we needed to "change" it (because we needed to select a new track index) we would attempt to re-use the originalSampleSource
but create a new instance of the audio track renderer. However, there doesn't appear to be any way to replace/substitute a new track renderer like this. As mentioned in my approach above, thehandlesMimeType
is called when being prepared. However, if you call theExoPlayer.prepare
a second time it will dispose of all the original renderers and eventually theirSampleSource
(that we're trying to re-use).Is there something that i'm missing on how best to implement this?
The text was updated successfully, but these errors were encountered: