Search code examples
javaandroiduriexoplayer

Exoplayer not playing local file on local storage


I am trying to play local file in device like this

String filePath="/storage/emulated/0/MyFiles/Media/Video/Xvid1509401908940.mp4"
File file=new File(filePath);
Uri localUri=Uri.fromFile(file);
exoPlayer_main.initializePlayer(localUri);

Getting ClassCastException

11-01 04:45:23.356 27145-29468/com.example.com.pro_working1 E/LoadTask: Unexpected exception loading stream
                                                                         java.lang.ClassCastException: libcore.net.url.FileURLConnection cannot be cast to java.net.HttpURLConnection
                                                                             at com.google.android.exoplayer2.upstream.DefaultHttpDataSource.makeConnection(DefaultHttpDataSource.java:393)
                                                                             at com.google.android.exoplayer2.upstream.DefaultHttpDataSource.makeConnection(DefaultHttpDataSource.java:350)
                                                                             at com.google.android.exoplayer2.upstream.DefaultHttpDataSource.open(DefaultHttpDataSource.java:192)
                                                                             at com.google.android.exoplayer2.source.ExtractorMediaPeriod$ExtractingLoadable.load(ExtractorMediaPeriod.java:692)
                                                                             at com.google.android.exoplayer2.upstream.Loader$LoadTask.run(Loader.java:315)
                                                                             at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
                                                                             at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
                                                                             at java.lang.Thread.run(Thread.java:818)
11-01 04:45:23.357 27145-29468/com.example.com.pro_working1 E/LoadTask: Unexpected exception loading stream
                                                                         java.lang.ClassCastException: libcore.net.url.FileURLConnection cannot be cast to java.net.HttpURLConnection
                                                                             at com.google.android.exoplayer2.upstream.DefaultHttpDataSource.makeConnection(DefaultHttpDataSource.java:393)
                                                                             at com.google.android.exoplayer2.upstream.DefaultHttpDataSource.makeConnection(DefaultHttpDataSource.java:350)
                                                                             at com.google.android.exoplayer2.upstream.DefaultHttpDataSource.open(DefaultHttpDataSource.java:192)
                                                                             at com.google.android.exoplayer2.source.ExtractorMediaPeriod$ExtractingLoadable.load(ExtractorMediaPeriod.java:692)
                                                                             at com.google.android.exoplayer2.upstream.Loader$LoadTask.run(Loader.java:315)
                                                                             at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
                                                                             at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
                                                                             at java.lang.Thread.run(Thread.java:818)

My ExoPlayer Methods which used to initialize exoplayer

 public void initializePlayer(Uri uri){
        Log.d(TAG,"Init Player Calling");

        if (player==null){
            Log.d(TAG,"Player Is Null Setting Up Player");
            player= ExoPlayerFactory.newSimpleInstance(
                    new DefaultRenderersFactory(context),
                    new DefaultTrackSelector(),
                    new DefaultLoadControl());
            playerView.setPlayer(player);
            player.addListener(componentListener);
            player.setPlayWhenReady(playWhenReady);
            player.seekTo(currentWindow,playbackPosition);

            MediaSource mediaSource=buildMediaSource(uri);
            player.prepare(mediaSource,true,false);
        }
    }

    private MediaSource buildMediaSource(Uri uri){
        return new ExtractorMediaSource(uri,
                new DefaultHttpDataSourceFactory("ua"),
                new DefaultExtractorsFactory(),null,null);

    }

I tried to Uri.parse(path) and file way as above but it still giving me ClassCastException . Please guide me how to play local storage file in exoplayer.


Solution

  • I got the answer from google official Exoplayer repository that

    The DefaultDataSource supports both local and Http sources. It automatically detects which one to use.

    So i changed

    private MediaSource buildMediaSource(Uri uri){
            return new ExtractorMediaSource(uri,
                    new DefaultHttpDataSourceFactory("ua"),
                    new DefaultExtractorsFactory(),null,null);
    
        }
    

    to this

    private MediaSource buildMediaSource(Uri uri){    
            return new ExtractorMediaSource(uri,
                    new DefaultDataSourceFactory(context,"ua"),
                    new DefaultExtractorsFactory(),null,null);
    
        }
    

    DefaultDataSourceFactory detect streaming or local storage file automatically where DefaultHttpDataSourceFactory only works on streaming request.

    UPDATE: As new version introduced (2.9.0). Some classes are deprecated also media sources. I am using new version of media source which plays almost every type of files (MP3,MP4,AVI and more)

     private MediaSource buildMediaSourceNew(Uri uri,int buildType){    
                    DataSource.Factory datasourceFactroy = new DefaultDataSourceFactory(context, Util.getUserAgent(context,"Your App Name"));
                    return new ExtractorMediaSource.Factory(datasourceFactroy).createMediaSource(uri);
    }