Open luxband opened 7 years ago
Note: Streams were sent via email.
The problematic streams are HLS media playlists. I don't think it's officially supported in HLS to mux multiple streams of the same type into TS chunks. This is supported in straightforward MPEG-TS because the pid for each stream is guaranteed to be constant, but in HLS the pid can change from one chunk to the next, which makes supporting multiple streams of the same type problematic in the general case. HLS officially supports multiple audio via HLS master playlists with alternate renditions.
So I think this is working as intended. If you wish to distribute HLS variants of these streams, you'll need to work out a way of generating them to use alternate renditions as per the HLS spec. Note that this approach is also significantly more efficient, since the client will only need to download the enabled audio track, rather than all seven of them.
@AquilesCanta - Is there a valid general case way to support this, or is the above correct? Would there be value in providing an option to enable support for this case (i.e. by forcing mapByType to false) if the application knows that the PIDs in the content wont change?
First things first: This behavior is expected. As stated, we don't support TS variants with multiple muxed tracks of the same type. Initially, the idea was to add support for multiple closed caption tracks only. Unlike with closed captions, the main obstacle for supporting multiple audios in the same TS(in HLS) is that they cannot be described by the manifest. That is, the #EXT-X-MEDIA tag only provides instream id for closed captions. That being said, the spec also states(read the whole section of the spec for some context):
Clients SHOULD be prepared to handle multiple tracks of a particular type (e.g. audio or video). A client with no other preference SHOULD choose the track with the lowest numerical track identifier that it can play.
I used to think this was not supported for some reason I don't remember. Even though ambiguous, this suggests the contrary. I also found an hls stream producer that allows muxing multiple audios in each variant. I will mark this as an enhancement but it will probably pass some time before I get to this. The best option, as @ojw28 says, is providing different streams for each language, and let the client download whatever it wants to play.
Hi! Any progress on this issue?
Hello. Any progress?
Hi! Any progress ?
Hi, as labeled, this is low priority for us. There are technical complications of having this implemented in the library (due to the variety of streams we need to support). Have you had a look at #2976? You could try implementing your own HlsExtractorFactory which builds a TsExtractor using MODE_SINGLE_PMT. As stated there, this is not officially supported, and you might run into issues if your stream has discontinuities. Plus, chunkless preparation will not work correctly either. Might be worth giving it a try for your case, if strictly necessary for your usecase.
Simple fix from #2976 or MODE_SINGLE_PMT stopped working in recent versions, does anyone have a new fix ?
Answering to myself: reverting 3919843db27c78dc04ec498087182058393cced0 seems to have helped to bring back the old behavior.
Answering to myself: reverting 3919843 seems to have helped to bring back the old behavior.
Confirm it helps. Remove code from HlsSampleStreamWrapper and HlsMediaChunk which was added in 3919843.
Hi. Is there any progress on this? With the amount of issues referenced and the popularity iptv services have acquired lately, I respectfully request the "low priority" tag on this is reconsidered
Hi, could you please mention status of this issue?
There is no change in the priority of this issue, and the update in https://github.com/google/ExoPlayer/issues/2014#issuecomment-379015825 still applies. The HLS specification supports multiple tracks as independent streams, which is both more efficient and more consistent with DASH, SmoothStreaming, and the overall direction of the industry.
As an additional piece of information, it seems like Apple mandate that multiple tracks are delivered as independent streams when streaming to Apple devices. As per their HLS authoring specifications for Apple devices:
9.6. If you have multichannel audio, you MUST use separate audio streams. 9.7. If you have alternate audio content (languages/commentary/DVS), you MUST use separate audio streams.
@ojw28 The specific part of the HLS specification only applies to streams which provide a Master Playlist. Many Live-TV providers do not have that and thus serve muxed streams, which apple also supports.
As I and probably many others are not in control of the media served and this format is (in my opinion) used widely enough, I'd think the priority could be increased.
Answering to myself: reverting 3919843 seems to have helped to bring back the old behavior.
Confirm it helps. Remove code from HlsSampleStreamWrapper and HlsMediaChunk which was added in 3919843.
It's not working for me. I'm using MODE_SINGLE_PMT in DefaultHlsExtractorFactory and removed code from HlsSampleStreamWrapper (as stated in 3919843)
Logcat errors:
07-05 18:43:36.167 D/PlayerWrapper( 7892): PLAY URL http://cdn1.cgctv.cgc.ge/secure/1562341415/1562341475/prLIPKZ74WVZHjO_mP-4v_fUvoCiz4H_iy06kgAGw74=/transcoder3/hls/relay/adaptive/MZmxiZ4/index.m3u8
07-05 18:43:36.207 D/PlayerWrapper( 7892): initDRM() before drmData=null
07-05 18:43:36.207 D/PlayerWrapper( 7892): initDRM() drmSessionManager=null
07-05 18:43:36.311 I/ExoPlayerImpl( 7892): Init 971a67 [ExoPlayerLib/2.10.0] [p212_1113, p212, Amlogic, 23]
07-05 18:43:36.357 D/EventLogger( 7892): surfaceSizeChanged [0.00, 0.00, window=0, 1920, 1080]
07-05 18:43:36.358 D/EventLogger( 7892): state [0.00, 0.00, window=0, true, IDLE]
07-05 18:43:36.359 D/VideoViewExoPlayer2( 7892): Player state = STATE_IDLE
07-05 18:43:36.383 D/EventLogger( 7892): state [0.03, 0.00, window=0, true, BUFFERING]
07-05 18:43:36.384 D/VideoViewExoPlayer2( 7892): Player state = STATE_BUFFERING
07-05 18:43:36.558 D/TvChannels( 7892): onItemSelected channel=TV 1000
07-05 18:43:36.601 D/EventLogger( 7892): onLoadStarted [0.24, 0.00, window=0, uri=http://cdn1.cgctv.cgc.ge/secure/1562341415/1562341475/prLIPKZ74WVZHjO_mP-4v_fUvoCiz4H_iy06kgAGw74=/transcoder3/hls/relay/adaptive/MZmxiZ4/index.m3u8]
07-05 18:43:36.605 D/EventLogger( 7892): onLoadStarted [0.25, 0.00, window=0, uri=http://cdn1.cgctv.cgc.ge/secure/1562341415/1562341475/prLIPKZ74WVZHjO_mP-4v_fUvoCiz4H_iy06kgAGw74=/transcoder3/hls/relay/adaptive/MZmxiZ4/MZmxTw4/index.m3u8]
07-05 18:43:36.606 D/EventLogger( 7892): onLoadCompleted [0.25, 0.00, window=0, uri=http://cdn1.cgctv.cgc.ge/secure/1562341415/1562341475/prLIPKZ74WVZHjO_mP-4v_fUvoCiz4H_iy06kgAGw74=/transcoder3/hls/relay/adaptive/MZmxiZ4/index.m3u8]
07-05 18:43:36.606 D/EventLogger( 7892): onLoadCompleted [0.25, 0.00, window=0, uri=http://cdn1.cgctv.cgc.ge/secure/1562341415/1562341475/prLIPKZ74WVZHjO_mP-4v_fUvoCiz4H_iy06kgAGw74=/transcoder3/hls/relay/adaptive/MZmxiZ4/MZmxTw4/index.m3u8]
07-05 18:43:36.607 D/EventLogger( 7892): timelineChanged [0.25, 60.48, window=0, periodCount=1, windowCount=1, reason=PREPARED
07-05 18:43:36.607 D/EventLogger( 7892): period [?]
07-05 18:43:36.607 D/EventLogger( 7892): window [90.72, true, true]
07-05 18:43:36.607 D/EventLogger( 7892): ]
07-05 18:43:36.608 D/EventLogger( 7892): mediaPeriodCreated [0.25, 60.48, window=0, period=0]
07-05 18:43:36.635 D/EventLogger( 7892): onLoadStarted [0.28, 60.48, window=0, period=0, uri=http://cdn1.cgctv.cgc.ge/secure/1562341415/1562341475/prLIPKZ74WVZHjO_mP-4v_fUvoCiz4H_iy06kgAGw74=/transcoder3/hls/relay/adaptive/MZmxiZ4/MZmxTw4/2019-07-05/19/chunk1562341382.ts]
07-05 18:43:36.639 D/EventLogger( 7892): loading [0.28, 60.48, window=0, period=0, true]
07-05 18:43:36.813 E/LoadTask( 7892): Unexpected exception loading stream
07-05 18:43:36.813 E/LoadTask( 7892): java.lang.NullPointerException: Attempt to write to field 'long com.google.android.exoplayer2.extractor.PositionHolder.position' on a null object reference
07-05 18:43:36.813 E/LoadTask( 7892): at com.google.android.exoplayer2.extractor.ts.TsDurationReader.readLastPcrValue(TsDurationReader.java:167)
07-05 18:43:36.813 E/LoadTask( 7892): at com.google.android.exoplayer2.extractor.ts.TsDurationReader.readDuration(TsDurationReader.java:86)
07-05 18:43:36.813 E/LoadTask( 7892): at com.google.android.exoplayer2.extractor.ts.TsExtractor.read(TsExtractor.java:257)
07-05 18:43:36.813 E/LoadTask( 7892): at com.google.android.exoplayer2.source.hls.HlsMediaChunk.feedDataToExtractor(HlsMediaChunk.java:357)
07-05 18:43:36.813 E/LoadTask( 7892): at com.google.android.exoplayer2.source.hls.HlsMediaChunk.loadMedia(HlsMediaChunk.java:325)
07-05 18:43:36.813 E/LoadTask( 7892): at com.google.android.exoplayer2.source.hls.HlsMediaChunk.load(HlsMediaChunk.java:301)
07-05 18:43:36.813 E/LoadTask( 7892): at com.google.android.exoplayer2.upstream.Loader$LoadTask.run(Loader.java:381)
07-05 18:43:36.813 E/LoadTask( 7892): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
07-05 18:43:36.813 E/LoadTask( 7892): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
07-05 18:43:36.813 E/LoadTask( 7892): at java.lang.Thread.run(Thread.java:818)
07-05 18:43:36.817 E/ExoPlayerImplInternal( 7892): Source error.
07-05 18:43:36.817 E/ExoPlayerImplInternal( 7892): com.google.android.exoplayer2.upstream.Loader$UnexpectedLoaderException: Unexpected NullPointerException: Attempt to write to field 'long com.google.android.exoplayer2.extractor.PositionHolder.position' on a null object reference
07-05 18:43:36.817 E/ExoPlayerImplInternal( 7892): at com.google.android.exoplayer2.upstream.Loader$LoadTask.run(Loader.java:403)
07-05 18:43:36.817 E/ExoPlayerImplInternal( 7892): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
07-05 18:43:36.817 E/ExoPlayerImplInternal( 7892): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
07-05 18:43:36.817 E/ExoPlayerImplInternal( 7892): at java.lang.Thread.run(Thread.java:818)
07-05 18:43:36.817 E/ExoPlayerImplInternal( 7892): Caused by: java.lang.NullPointerException: Attempt to write to field 'long com.google.android.exoplayer2.extractor.PositionHolder.position' on a null object reference
07-05 18:43:36.817 E/ExoPlayerImplInternal( 7892): at com.google.android.exoplayer2.extractor.ts.TsDurationReader.readLastPcrValue(TsDurationReader.java:167)
07-05 18:43:36.817 E/ExoPlayerImplInternal( 7892): at com.google.android.exoplayer2.extractor.ts.TsDurationReader.readDuration(TsDurationReader.java:86)
07-05 18:43:36.817 E/ExoPlayerImplInternal( 7892): at com.google.android.exoplayer2.extractor.ts.TsExtractor.read(TsExtractor.java:257)
07-05 18:43:36.817 E/ExoPlayerImplInternal( 7892): at com.google.android.exoplayer2.source.hls.HlsMediaChunk.feedDataToExtractor(HlsMediaChunk.java:357)
07-05 18:43:36.817 E/ExoPlayerImplInternal( 7892): at com.google.android.exoplayer2.source.hls.HlsMediaChunk.loadMedia(HlsMediaChunk.java:325)
07-05 18:43:36.817 E/ExoPlayerImplInternal( 7892): at com.google.android.exoplayer2.source.hls.HlsMediaChunk.load(HlsMediaChunk.java:301)
07-05 18:43:36.817 E/ExoPlayerImplInternal( 7892): at com.google.android.exoplayer2.upstream.Loader$LoadTask.run(Loader.java:381)
07-05 18:43:36.817 E/ExoPlayerImplInternal( 7892): ... 3 more
07-05 18:43:36.837 E/EventLogger( 7892): internalError [0.48, 60.48, window=0, period=0, loadError]
07-05 18:43:36.837 E/EventLogger( 7892): com.google.android.exoplayer2.upstream.Loader$UnexpectedLoaderException: Unexpected NullPointerException: Attempt to write to field 'long com.google.android.exoplayer2.extractor.PositionHolder.position' on a null object reference
07-05 18:43:36.837 E/EventLogger( 7892): at com.google.android.exoplayer2.upstream.Loader$LoadTask.run(Loader.java:403)
07-05 18:43:36.837 E/EventLogger( 7892): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
07-05 18:43:36.837 E/EventLogger( 7892): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
07-05 18:43:36.837 E/EventLogger( 7892): at java.lang.Thread.run(Thread.java:818)
07-05 18:43:36.837 E/EventLogger( 7892): Caused by: java.lang.NullPointerException: Attempt to write to field 'long com.google.android.exoplayer2.extractor.PositionHolder.position' on a null object reference
07-05 18:43:36.837 E/EventLogger( 7892): at com.google.android.exoplayer2.extractor.ts.TsDurationReader.readLastPcrValue(TsDurationReader.java:167)
07-05 18:43:36.837 E/EventLogger( 7892): at com.google.android.exoplayer2.extractor.ts.TsDurationReader.readDuration(TsDurationReader.java:86)
07-05 18:43:36.837 E/EventLogger( 7892): at com.google.android.exoplayer2.extractor.ts.TsExtractor.read(TsExtractor.java:257)
07-05 18:43:36.837 E/EventLogger( 7892): at com.google.android.exoplayer2.source.hls.HlsMediaChunk.feedDataToExtractor(HlsMediaChunk.java:357)
07-05 18:43:36.837 E/EventLogger( 7892): at com.google.android.exoplayer2.source.hls.HlsMediaChunk.loadMedia(HlsMediaChunk.java:325)
07-05 18:43:36.837 E/EventLogger( 7892): at com.google.android.exoplayer2.source.hls.HlsMediaChunk.load(HlsMediaChunk.java:301)
07-05 18:43:36.837 E/EventLogger( 7892): at com.google.android.exoplayer2.upstream.Loader$LoadTask.run(Loader.java:381)
07-05 18:43:36.837 E/EventLogger( 7892): ... 3 more
07-05 18:43:36.840 E/EventLogger( 7892): playerFailed [0.48, 60.48, window=0, period=0]
07-05 18:43:36.840 E/EventLogger( 7892): com.google.android.exoplayer2.ExoPlaybackException: com.google.android.exoplayer2.upstream.Loader$UnexpectedLoaderException: Unexpected NullPointerException: Attempt to write to field 'long com.google.android.exoplayer2.extractor.PositionHolder.position' on a null object reference
07-05 18:43:36.840 E/EventLogger( 7892): at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:386)
07-05 18:43:36.840 E/EventLogger( 7892): at android.os.Handler.dispatchMessage(Handler.java:98)
07-05 18:43:36.840 E/EventLogger( 7892): at android.os.Looper.loop(Looper.java:148)
07-05 18:43:36.840 E/EventLogger( 7892): at android.os.HandlerThread.run(HandlerThread.java:61)
07-05 18:43:36.840 E/EventLogger( 7892): Caused by: com.google.android.exoplayer2.upstream.Loader$UnexpectedLoaderException: Unexpected NullPointerException: Attempt to write to field 'long com.google.android.exoplayer2.extractor.PositionHolder.position' on a null object reference
07-05 18:43:36.840 E/EventLogger( 7892): at com.google.android.exoplayer2.upstream.Loader$LoadTask.run(Loader.java:403)
07-05 18:43:36.840 E/EventLogger( 7892): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
07-05 18:43:36.840 E/EventLogger( 7892): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
07-05 18:43:36.840 E/EventLogger( 7892): at java.lang.Thread.run(Thread.java:818)
07-05 18:43:36.840 E/EventLogger( 7892): Caused by: java.lang.NullPointerException: Attempt to write to field 'long com.google.android.exoplayer2.extractor.PositionHolder.position' on a null object reference
07-05 18:43:36.840 E/EventLogger( 7892): at com.google.android.exoplayer2.extractor.ts.TsDurationReader.readLastPcrValue(TsDurationReader.java:167)
07-05 18:43:36.840 E/EventLogger( 7892): at com.google.android.exoplayer2.extractor.ts.TsDurationReader.readDuration(TsDurationReader.java:86)
07-05 18:43:36.840 E/EventLogger( 7892): at com.google.android.exoplayer2.extractor.ts.TsExtractor.read(TsExtractor.java:257)
07-05 18:43:36.840 E/EventLogger( 7892): at com.google.android.exoplayer2.source.hls.HlsMediaChunk.feedDataToExtractor(HlsMediaChunk.java:357)
07-05 18:43:36.840 E/EventLogger( 7892): at com.google.android.exoplayer2.source.hls.HlsMediaChunk.loadMedia(HlsMediaChunk.java:325)
07-05 18:43:36.840 E/EventLogger( 7892): at com.google.android.exoplayer2.source.hls.HlsMediaChunk.load(HlsMediaChunk.java:301)
07-05 18:43:36.840 E/EventLogger( 7892): at com.google.android.exoplayer2.upstream.Loader$LoadTask.run(Loader.java:381)
07-05 18:43:36.840 E/EventLogger( 7892): ... 3 more
07-05 18:43:36.840 D/TvChannels( 7892): OnErrorListener onError: what = -1, extra = -1
07-05 18:43:36.849 D/EventLogger( 7892): mediaPeriodReleased [0.49, 60.48, window=0, period=0]
07-05 18:43:36.850 D/EventLogger( 7892): loading [0.49, 60.48, window=0, false]
07-05 18:43:36.851 D/EventLogger( 7892): state [0.50, 60.48, window=0, true, IDLE]
07-05 18:43:36.851 D/VideoViewExoPlayer2( 7892): Player state = STATE_IDLE
Additional info about my stream in https://github.com/google/ExoPlayer/issues/6101
Now I'm using sources of exoplayer 2.10.2
@tipoc123 I created a fork which supports this. It's based on release-v2 and doesn't require any special MODE_ etc.
It's on branch hls-multi-track: https://github.com/Jenjen1324/ExoPlayer/tree/hls-multi-track
@tipoc123
1) TsExtractor.java
change
int trackId = mode == MODE_HLS ? streamType : elementaryPid;
to
int trackId = elementaryPid;
2) DefaultHlsExtractorFactory.java
change
muxedCaptionFormats = Collections.emptyList();
to
esReaderFactoryFlags |= DefaultTsPayloadReaderFactory.FLAG_ALLOW_NON_IDR_KEYFRAMES;
muxedCaptionFormats = Collections.emptyList();
3) HlsMediaChunk.java
change
output.init(uid, shouldSpliceIn, reusingExtractor);
to
output.init(uid, shouldSpliceIn);
4) HlsSampleStreamWrapper.java
remove
private int audioSampleQueueIndex;
private boolean videoSampleQueueMappingDone;
private int videoSampleQueueIndex;
audioSampleQueueIndex = C.INDEX_UNSET;
videoSampleQueueIndex = C.INDEX_UNSET;
if (!reusingExtractor) {
audioSampleQueueMappingDone = false;
videoSampleQueueMappingDone = false;
}
if (type == C.TRACK_TYPE_AUDIO) {
audioSampleQueueMappingDone = true;
audioSampleQueueIndex = trackCount;
} else if (type == C.TRACK_TYPE_VIDEO) {
videoSampleQueueMappingDone = true;
videoSampleQueueIndex = trackCount;
}
private static DummyTrackOutput createDummyTrackOutput(int id, int type) {
Log.w(TAG, "Unmapped track with id " + id + " of type " + type);
return new DummyTrackOutput();
}
change
if (type == C.TRACK_TYPE_AUDIO) {
if (audioSampleQueueIndex != C.INDEX_UNSET) {
if (audioSampleQueueMappingDone) {
return sampleQueueTrackIds[audioSampleQueueIndex] == id
? sampleQueues[audioSampleQueueIndex]
: createDummyTrackOutput(id, type);
}
audioSampleQueueMappingDone = true;
sampleQueueTrackIds[audioSampleQueueIndex] = id;
return sampleQueues[audioSampleQueueIndex];
} else if (tracksEnded) {
return createDummyTrackOutput(id, type);
}
} else if (type == C.TRACK_TYPE_VIDEO) {
if (videoSampleQueueIndex != C.INDEX_UNSET) {
if (videoSampleQueueMappingDone) {
return sampleQueueTrackIds[videoSampleQueueIndex] == id
? sampleQueues[videoSampleQueueIndex]
: createDummyTrackOutput(id, type);
}
videoSampleQueueMappingDone = true;
sampleQueueTrackIds[videoSampleQueueIndex] = id;
return sampleQueues[videoSampleQueueIndex];
} else if (tracksEnded) {
return createDummyTrackOutput(id, type);
}
} else /* sparse track */ {
for (int i = 0; i < trackCount; i++) {
if (sampleQueueTrackIds[i] == id) {
return sampleQueues[i];
}
}
if (tracksEnded) {
return createDummyTrackOutput(id, type);
}
to
for (int i = 0; i < trackCount; i++) {
if (sampleQueueTrackIds[i] == id) {
return sampleQueues[i];
}
}
if (tracksEnded) {
Log.w(TAG, "Unmapped track with id " + id + " of type " + type);
return new DummyTrackOutput();
If you are using ExoMedia then you have to change ExoMediaPlayer.java
@Deprecated
public void setSelectedTrack(@NonNull RendererType type, int index) {
setSelectedTrack(type, 0, index);
}
to
@Deprecated
public void setSelectedTrack(@NonNull RendererType type, int index) {
setSelectedTrack(type, index/*0*/, 0/*index*/);
}
Thats works for me.
Thank you, guys.
I've tried this commit https://github.com/Jenjen1324/ExoPlayer/commit/f8d0f5e9ab8674d3c6d40044d9342bef0bdccddf . It's working.
@tipoc123 I created a fork which supports this. It's based on release-v2 and doesn't require any special MODE_ etc.
It's on branch hls-multi-track: https://github.com/Jenjen1324/ExoPlayer/tree/hls-multi-track
Hi,
Did you tried to update the code for 2.10.7 version? It has been changed since 2.10.2.
Thank you.
@tipoc123 I created a fork which supports this. It's based on release-v2 and doesn't require any special MODE_ etc.
It's on branch hls-multi-track: https://github.com/Jenjen1324/ExoPlayer/tree/hls-multi-track
Hi, any chance you could implement these changes for version 2.12.2? Thanks!
@tipoc123 I created a fork which supports this. It's based on release-v2 and doesn't require any special MODE_ etc. It's on branch hls-multi-track: https://github.com/Jenjen1324/ExoPlayer/tree/hls-multi-track
Hi, any chance you could implement these changes for version 2.12.2? Thanks!
@needz I've updated my repo: https://github.com/Jenjen1324/ExoPlayer with a version for 2.12.2.
I've blindly copied over parts of our own modification and just pushed it. Please test if it's even working. If not, open an issue in my repository.
@Jenjen1324 thanks, it is working indeed, since I could figure the solution out myself based on your previous modifications (thanks a lot for them!), it turned out there are not too many changes to make in this specific version. Kindest regards!
Hello, Any change of fixing this issue? I tried the patch above, but it causes some "infinite buffering" bugs to happen for some other streams.
Thanks
Hi, The problem with the stream that contains multiple audio tracks. Ether is broadcast on http, archive by nPVR. Parameters streams (video H264 - MPEG-4 AVC (part 10) (h264) + 7 audio-tracks MPEG Audio layer 1/2 (mpga)) If broadcast by nPVR exoplayer defines only a single track. If broadcast by http exoplayer correctly identifies all 7 tracks. Please tell me why this happens?