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.71k stars 6.02k forks source link

URL redirect in HLS stream breaks MediaSource/MimeType recognition #11025

Closed JaroslavHerber closed 1 year ago

JaroslavHerber commented 1 year ago

ExoPlayer Version

2.18.3

Devices that reproduce the issue

All

Devices that do not reproduce the issue

No response

Reproducible in the demo app?

Yes

Reproduction steps

Use this URL that redirects to a HLS stream: https://m3u-ip.tv/test-redirect.php

Simple example code:

DefaultRenderersFactory renderersFactory =
    new DefaultRenderersFactory(this).forceEnableMediaCodecAsynchronousQueueing();

// Build a HttpDataSource.Factory with cross-protocol redirects enabled.
HttpDataSource.Factory httpDataSourceFactory =
    new DefaultHttpDataSource.Factory().setAllowCrossProtocolRedirects(true);
DefaultDataSource.Factory dataSourceFactory =
    new DefaultDataSource.Factory(this, httpDataSourceFactory);

ExoPlayer oPlayer = new ExoPlayer.Builder(this, renderersFactory)
    .setMediaSourceFactory(new DefaultMediaSourceFactory(dataSourceFactory))
    .build();

MediaItem mediaItem = new MediaItem.Builder()
    .setUri("https://m3u-ip.tv/test-redirect.php")
 // .setMimeType(MimeTypes.APPLICATION_M3U8) // works with that, but other stream types won't work anymore
    .build();

oPlayer.setMediaItem(mediaItem);
oPlayer.prepare();
oPlayer.play();

Expected result

Redirect is done, MediaSource/MimeType is recognized as a HLS stream (HlsMediaSource) and stream is playing.

Actual result

Stream is not playing. Looks like stream is recognized as ProgressiveMediaSource... Error: Caused by: com.google.android.exoplayer2.source.UnrecognizedInputFormatException: None of the available extractors (FlvExtractor, FlacExtractor, WavExtractor, FragmentedMp4Extractor, Mp4Extractor, AmrExtractor, PsExtractor, OggExtractor, TsExtractor, MatroskaExtractor, AdtsExtractor, Ac3Extractor, Ac4Extractor, Mp3Extractor, AviExtractor, JpegExtractor) could read the stream. at com.google.android.exoplayer2.source.BundledExtractorsAdapter.init(BundledExtractorsAdapter.java:92) at com.google.android.exoplayer2.source.ProgressiveMediaPeriod$ExtractingLoadable.load(ProgressiveMediaPeriod.java:1017) at com.google.android.exoplayer2.upstream.Loader$LoadTask.run(Loader.java:412) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) at java.lang.Thread.run(Thread.java:919)

Note: If URL has no redirect, the stream plays. Also if ...setMimeType(MimeTypes.APPLICATION_M3U8) is used, the stream is played after redirect.

Media

Use this URL: https://m3u-ip.tv/test-redirect.php It redirects to a German public channel.

Bug Report

christosts commented 1 year ago

I can't test the content, the redirect url returns 403.

Note: If URL has no redirect, the stream plays.

I'm actually surprised that the stream works when there's no redirect and no explicit setting of the MIME type, I'd expect the player to always assume the content is progressive.

Also if ...setMimeType(MimeTypes.APPLICATION_M3U8) is used, the stream is played after redirect.

I'd expect setting the MIME type to be needed always since the player cannot figure out from the url that the content is HLS and therefore resorts to progressive.

@tonihei were there plans to have a media source that sniffs HLS playlists/DASH manifests at runtime?

tonihei commented 1 year ago

Yes, this issue can be solved once https://github.com/google/ExoPlayer/issues/3165 is implemented. Until then, you just need to provide the MIME type via setMimeType if the file extension doesn't match the standard one.

JaroslavHerber commented 1 year ago

I can't test the content, the redirect url returns 403.

Might be a geo block. I changed the destination URL. Should work now :)