PhilBlais
PhilBlais

Reputation: 1176

Exoplayer for android, trying to stream a m3u8 file and getting error: None of the available extractors could read the stream

I am trying to stream an m3u8 file and I am getting an error. The url I am using is the following: http://storage.googleapis.com/videos.siku.org/10005/dash/master.m3u8 This streaming video does work in a browser. I am getting the following error at runtime:

ExoPlayerImplInternal: Source error. com.google.android.exoplayer2.source.UnrecognizedInputFormatException: None of the available extractors (MatroskaExtractor, FragmentedMp4Extractor, Mp4Extractor, Mp3Extractor, AdtsExtractor, Ac3Extractor, TsExtractor, FlvExtractor, OggExtractor, PsExtractor, WavExtractor, AmrExtractor, Ac4Extractor, FlacExtractor) could read the stream. at com.google.android.exoplayer2.source.ProgressiveMediaPeriod$ExtractorHolder.selectExtractor(ProgressiveMediaPeriod.java:1090) at com.google.android.exoplayer2.source.ProgressiveMediaPeriod$ExtractingLoadable.load(ProgressiveMediaPeriod.java:969) at com.google.android.exoplayer2.upstream.Loader$LoadTask.run(Loader.java:391) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636) at java.lang.Thread.run(Thread.java:764)

I am using the class ExoPlayerHelper (which was taken from a stackoverflow question, although I did implement this the recommended way and I was getting the same error)

Here is the class I am using:

class ExoPlayerHelper(
    private val playerView: PlayerView,
    onError: (ExoPlaybackException) -> Unit,
    onPlayerBuffer: (Boolean) -> Unit
) {
    private var exoPlayer: ExoPlayer? = null
    private var mediaSource: ProgressiveMediaSource? = null
    private val playerListener = object : Player.EventListener {
        override fun onPlayerError(error: ExoPlaybackException) {
            super.onPlayerError(error)
            onError(error)
        }

        override fun onPlayerStateChanged(playWhenReady: Boolean, playbackState: Int) {
            super.onPlayerStateChanged(playWhenReady, playbackState)
            onPlayerBuffer(playbackState == Player.STATE_BUFFERING)
        }
    }

    fun initializePlayer(url: String) {
        exoPlayer = SimpleExoPlayer.Builder(playerView.context).build()
        exoPlayer!!.repeatMode = Player.REPEAT_MODE_ALL
        exoPlayer!!.addListener(playerListener)
        playerView.player = exoPlayer

        val userAgent =
            Util.getUserAgent(playerView.context, playerView.context.getString(R.string.app_name))
        mediaSource = ProgressiveMediaSource
            .Factory(
                DefaultDataSourceFactory(playerView.context, userAgent),
                DefaultExtractorsFactory()
            )
            .createMediaSource(Uri.parse(url))
            exoPlayer!!.prepare(mediaSource!!, true, false)
            exoPlayer!!.playWhenReady = true
        }
    }
}

I do get a blank com.google.android.exoplayer2.ui.PlayerView with the controls appearing. When pressing the play button I get the same error message:

com.google.android.exoplayer2.ExoPlaybackException: com.google.android.exoplayer2.source.UnrecognizedInputFormatException: None of the available extractors (MatroskaExtractor, FragmentedMp4Extractor, Mp4Extractor, Mp3Extractor, AdtsExtractor, Ac3Extractor, TsExtractor, FlvExtractor, OggExtractor, PsExtractor, WavExtractor, AmrExtractor, Ac4Extractor, FlacExtractor) could read the stream.

Any clues as to why I am getting this error UnrecognizedInputFormatException?

Upvotes: 18

Views: 19155

Answers (3)

Marvel Alvarez
Marvel Alvarez

Reputation: 57

For global format support don't set te MimeType, instead set the player like this:

override fun prepare(uri: String, playWhenReady: Boolean) {
        val context = context.get() ?: return
        player.apply {
            this.playWhenReady = playWhenReady
            videoScalingMode = C.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING
            repeatMode = Player.REPEAT_MODE_OFF
// this is the IMPORTANT part ****
            setMediaSource(prepareMediaSource(context, uri))
            prepare()
        }
    }
// set the DefaultMediaSourceFactory that englobes all formats ***

https://developer.android.com/media/media3/exoplayer/media-sources

private fun prepareMediaSource(context: Context, uri: String) =
        DefaultMediaSourceFactory(DefaultDataSource.Factory(context))
            .createMediaSource(
                MediaItem.Builder()
                    .setUri(uri)
                    .build()
            )

Note/ Include all the dependencies for the ExoPlayer: https://developer.android.com/jetpack/androidx/releases/media3

Upvotes: 0

Trusted Support
Trusted Support

Reputation: 11

Use This method you have to use HlsMediaSource

 Uri uri = Uri.parse(urlStream);
 //MediaSource mediaSource = buildMediaSource(uri);
 DataSource.Factory dataSourceFactory =
         new DefaultHttpDataSourceFactory(Util.getUserAgent(this, "app-name"));
 HlsMediaSource hlsMediaSource =
         new HlsMediaSource.Factory(dataSourceFactory).createMediaSource(uri);
 player = ExoPlayerFactory.newSimpleInstance(this);
 player.setPlayWhenReady(playWhenReady);
 player.seekTo(currentWindow, playbackPosition);

 // Create a player instance.

 // Prepare the player with the media source.
 //player.prepare(mediaSource);
 player.prepare(hlsMediaSource, false, false);

Upvotes: 1

Gautam
Gautam

Reputation: 3362

Since you are trying to play m3u8 file, you need to create HLS media source. So just make this below change -

mediaSource =HlsMediaSource.Factory(DefaultHttpDataSourceFactory(userAgent))
                .createMediaSource(uri)

Upvotes: 26

Related Questions