androidXP
androidXP

Reputation: 1719

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.

Upvotes: 2

Views: 10975

Answers (2)

TimothyP
TimothyP

Reputation: 21745

At the time of writing, ExtractorMediaSource is also deprecated.

The following solution works for me:

private MediaSource buildMediaSource(Uri uri) {
        MediaItem mediaItem = MediaItem.fromUri(uri);
        return new ProgressiveMediaSource.Factory(new DefaultDataSource.Factory(context)).createMediaSource(mediaItem);
    }

Example usage:

MediaSource mediaSource = buildMediaSource(Uri.parse(source));
exoPlayer.setMediaSource(mediaSource);
exoPlayer.setRepeatMode(repeat ? Player.REPEAT_MODE_ALL : Player.REPEAT_MODE_OFF);
exoPlayer.prepare();
exoPlayer.setPlayWhenReady(true);

Where source is the full path to a file in the private app data folder of my application, for example:

/data/data/com.example.someapp/files/demo.mp4

For me it does not work for files on the sdcard, for example: /mnt/sdcard/Movies/demo.mp4.

Upvotes: 0

androidXP
androidXP

Reputation: 1719

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

Upvotes: 18

Related Questions