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

回眸只為那壹抹淺笑 提交于 2020-04-13 08:06:09

问题


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?


回答1:


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))
}



回答2:


I don't think m3u8 is a video format but rather a playlist format. I think Exoplayer is lower level than handling playlists; probably you need to read the m3u8 file yourself and then pass in the links in the playlist yourself.

Luckily the file format isn't complicated and it shouldn't be too difficult to parse. It seems it's pretty well documented. There's even some examples on Wikipedia: https://en.wikipedia.org/wiki/M3U




回答3:


On Android 4.1+, you can use this library https://github.com/brianwernick/ExoMedia/ . The example mentioned on the Read-me page should be sufficient to get you started. I have reproduced that code snippet with a few additions/modifications.

private void setupVideoView() {
            EMVideoView emVideoView = (EMVideoView)findViewById(R.id.video_play_activity_video_view);
            emVideoView.setOnPreparedListener(this);

            //Enter your m3u8 URL below
            emVideoView.setVideoURI(Uri.parse("http://SOMESERVER/playlist.m3u8"));
        }

        @Override
        public void onPrepared(MediaPlayer mp) {
            //Starts the video playback as soon as it is ready
            emVideoView.start();
        }

        @Override
        public void onPause() {
            super.onPause();
            //Pause Video Playback
            emVideoView.pause();
        }



回答4:


For streaming .m3u8 file use below code while initializing Exoplayer:-

BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();

TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveTrackSelection.Factory(bandwidthMeter);

TrackSelector trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory);

//Create the player using ExoPlayerFactory
videoPlayer = ExoPlayerFactory.newSimpleInstance(context,trackSelector);

Handler mHandler = new Handler();

String userAgent = Util.getUserAgent(context, "Exo Player");

DataSource.Factory dataSourceFactory = new DefaultHttpDataSourceFactory(
                userAgent, null,
                DefaultHttpDataSource.DEFAULT_CONNECT_TIMEOUT_MILLIS,
                1800000,
                true);

HlsMediaSource mediaSource = new HlsMediaSource(Uri.parse(mediaUrl),dataSourceFactory, 1800000,mHandler, null);

if (mediaUrl != null) {
    videoPlayer.prepare(mediaSource);
    videoPlayer.setPlayWhenReady(true);
}


来源:https://stackoverflow.com/questions/60583183/exoplayer-error-in-recyclerview-source-error-none-of-the-available-extractors

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!