Search code examples
androidandroid-recyclerviewandroid-video-playerexoplayer2.x

Exoplayer error in Recyclerview, Source error None of the available extractors


I am using ExoPlayer to stream videos in a RecyclerView.

I am implementing the ExoPlayer inside my RecyclerView Adapter's bind method inside my ViewHolder.

The video format I am using is m3u8 and the URL I am using works in a browser. So I know that the video link is valid. I've also testing a youtube link in there.

Here is the code from the Recyclerview adapter's ViewHolder ->

class ViewHolder private constructor(val binding: FeedRowBinding) :
    RecyclerView.ViewHolder(binding.root) {

    fun bind(context: Activity){
        if (entity.content.videolink != null) {
            setupVideoPlayer(entity.content.videolink, context)
        }
    }
}

private fun setupVideoPlayer(url: String, context: Activity) {
    val videoExoPlayer = SimpleExoPlayer.Builder(binding.videoView.context).build()
    videoExoPlayer.prepare(createUrlMediaSource(url, context))

    binding.play.setOnClickListener {
        videoExoPlayer.playWhenReady = true
    }

    binding.pause.setOnClickListener {
        videoExoPlayer.playWhenReady = false
    }
}

private fun createUrlMediaSource(url: String, context: Activity): MediaSource {
    val userAgent = Util.getUserAgent(context, context.getString(R.string.about))
    return ProgressiveMediaSource
           .Factory(DefaultDataSourceFactory(context, userAgent), DefaultExtractorsFactory())
           .createMediaSource(Uri.parse(url))
}

When loading my recyclerview and get to the row with the video I get the following error:

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'm not sure what am I doing wrong, any ideas on how to fix this issue?


Solution

  • You need to modify your createUrlMediaSource

    private fun createUrlMediaSource(url: String, context: Activity): MediaSource {
        val userAgent = Util.getUserAgent(context, context.getString(R.string.about))
        return ProgressiveMediaSource
               .Factory(DefaultDataSourceFactory(context, userAgent), DefaultExtractorsFactory())
               .createMediaSource(Uri.parse(url))
    }
    

    as stated in https://exoplayer.dev

    • DashMediaSource for DASH.
    • SsMediaSource for SmoothStreaming.
    • HlsMediaSource for HLS (this is your format => .m3u8).
    • ProgressiveMediaSource for regular media files.

    So you need to replace your function to this:

    private fun createUrlMediaSource(url: String, context: Activity): MediaSource {
        val userAgent = Util.getUserAgent(context, context.getString(R.string.about))
        return HlsMediaSource
               .Factory(DefaultDataSourceFactory(context, userAgent), DefaultExtractorsFactory())
               .createMediaSource(Uri.parse(url))
    }