Search code examples
javaandroid-studioexceptionexoplayer2.xmedia-source

how to handle exoplayer2 exception when mediasource uri is unavailable?


I am using Exoplayer 2.11.* to make an audio streaming app on Android. The audio is hosted on a remote server and the streaming is done using Icecast. The problem is, the server is down sometimes and when the user opens the app that time, I want to show toast about it. At first, I was doing it as :

final ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();

DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(
                getContext(),
                Util.getUserAgent(getContext(), "SUSTCast"),
                defaultBandwidthMeter);

Mediasource mediaSource = new ExtractorMediaSource(
                Uri.parse(iceURL),
                dataSourceFactory,
                extractorsFactory,
                new Handler(), error -> {
                 //shows a toast here
                }
        );

but in this way, the toast is shown 3-4 times, as I think exoplayer tries to reload the URI. Alternatively, I tried to fix this problem using try/catch block too...but that just couldn't catch the error. Can anybody tell me what else I could try or what I am doing wrong here? This is a stacktrace of the exception thrown during the server down state :

ExoPlayerImplInternal: Source error.
    com.google.android.exoplayer2.upstream.HttpDataSource$InvalidResponseCodeException: Response code: 404
        at com.google.android.exoplayer2.upstream.DefaultHttpDataSource.open(DefaultHttpDataSource.java:300)
        at com.google.android.exoplayer2.upstream.DefaultDataSource.open(DefaultDataSource.java:177)
        at com.google.android.exoplayer2.upstream.StatsDataSource.open(StatsDataSource.java:83)
        at com.google.android.exoplayer2.source.ProgressiveMediaPeriod$ExtractingLoadable.load(ProgressiveMediaPeriod.java:956)
        at com.google.android.exoplayer2.upstream.Loader$LoadTask.run(Loader.java:391)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
        at java.lang.Thread.run(Thread.java:761)

Solution

  • You should handle errors using event listeners that are attached to exoplayer itself.

    exoPlayer.addListener(object: Player.EventListener {
                            override fun onPlayerError(error: ExoPlaybackException) {
                                super.onPlayerError(error)
                                //show toast
                            }
                        })