Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ExoPlayer get available audio tracks and switch between them

I have an android application which streams videos with ExoPlayer. I want to add language support to the streams. What languages the stream will have, must be taken from the stream's metadata.

In ExoPlayer library I found the way to get list of the tracks from the stream by following:

player.getCurrentTrackGroups().get(i).getFormat(i) //player is SimpleExoPlayer class

but this give me kind of raw information, here is videos, audios, and other tracks that need to be labeled. printed formats looks like following:

Format(1/100, null, video/avc, -1, null, [1920, 1080, -1.0], [-1, -1])
Format(1/8292, null, application/cea-608, -1, null, [-1, -1, -1.0], [-1, -1])
Format(1/200, null, audio/mpeg-L2, -1, , [-1, -1, -1.0], [2, 48000])
Format(1/201, null, audio/mpeg-L2, -1, , [-1, -1, -1.0], [2, 48000])

I wonder if there is an easier way to get only audio tracks and their required information for switching between them for later.

My next problem is I don't know how to switch between the audio tracks. I searched and there is an answer accepted that this is done by the following code:

player.selectTrack(FullPlayer.TYPE_AUDIO, ExoPlayer.TRACK_DEFAULT);

this code is taken from this answer. Problem is, that my SimpleExoPlayer class has not this function. I have exoplayer 2.8.2 and neither SimpleExoPlayer nor ExoPlayer class got that function. So i'm stuck there.
Another found answer was from DefaultTrackSelector class which has following face:

 trackSelector.setParameters( trackSelector.getParameters().buildUpon().setPreferredAudioLanguage("eng"));

this looks like simple and good way, But not all streams are labeled like that. many tracks has no string for language name. Only thing that they have different is ID string. And passing the id string does not work.

like image 877
oto Avatar asked May 09 '19 15:05

oto


People also ask

What is track selector ExoPlayer?

Direct Known Subclasses: MappingTrackSelector public abstract class TrackSelector extends Object. The component of an ExoPlayer responsible for selecting tracks to be consumed by each of the player's Renderer s. The DefaultTrackSelector implementation should be suitable for most use cases.

How do you change ExoPlayer tracks on Android?

You can use hls video (. trackSelector = new DefaultTrackSelector(); trackSelector. setParameters( trackSelector. getParameters(). buildUpon().

Does ExoPlayer use mediaplayer?

ExoPlayer is an app-level media player built on top of low-level media APIs in Android. It is an open source project used by Google apps, including YouTube and Google TV.

Does ExoPlayer support WebRTC?

Most Media players, like ExoPlayer, support these protocols well, although they are complex and evolving protocols so there are always edge cases. Many video conferencing applications use WebRTC which is a real time optimised protocol - the usual approach is to use a WebRTC client for this type of stream.


1 Answers

With the stream metadata I had, I don't think it was possible to get the language list. Now after fixing the metadata, it looks like this:

Format(1/21, null, application/id3, -1, null, [-1, -1, -1.0], [-1, -1])
Format(0, null, video/hevc, 2541422, null, [1920, 1080, -1.0], [-1, -1])
Format(1/8228, null, application/cea-608, -1, null, [-1, -1, -1.0], [-1, -1])
Format(1/21, null, application/id3, -1, null, [-1, -1, -1.0], [-1, -1])
Format(eng, null, audio/mpeg-L2, -1, eng, [-1, -1, -1.0], [2, 48000])
Format(1/21, null, application/id3, -1, null, [-1, -1, -1.0], [-1, -1])
Format(rus, null, audio/mpeg-L2, -1, rus, [-1, -1, -1.0], [2, 48000])

I wrote the code to get information from the metadata:

for(int i = 0; i < player.getCurrentTrackGroups().length; i++){
   String format = player.getCurrentTrackGroups().get(i).getFormat(0).sampleMimeType;
   String lang = player.getCurrentTrackGroups().get(i).getFormat(0).language;
   String id = player.getCurrentTrackGroups().get(i).getFormat(0).id;

   System.out.println(player.getCurrentTrackGroups().get(i).getFormat(0));
   if(format.contains("audio") && id != null && lang != null){
      //System.out.println(lang + " " + id);
      audioLanguages.add(new Pair<>(id, lang));
   }
}

If metadata's sampleMimeType contains "audio" string I assume it's about audio. there can be many different types of audio.

Now about switching between the audio tracks:

trackSelector.setParameters( trackSelector.getParameters().buildUpon().setPreferredAudioLanguage("eng"));

this inside string should match .getFormat(0).language or .getFormat(0).id (I don't know exactly).

like image 122
oto Avatar answered Oct 17 '22 11:10

oto