ExoPlayer - play local mp4 file in SD card
Asked Answered
W

8

19

I am using the Exoplayer Demo app and want to preload a MP4 video from SD card. I have tried out the implementation from this post, but it does not work. There is no such class called DemoUtil.java in my exoplayer Demo. Instead used:

public static final Sample[] LOCAL_VIDEOS = new Sample[] {
new Sample("Some User friendly name of video 1",
"/mnt/sdcard/video1.mp4", Util.TYPE_OTHER),
};

I also could not use the their snippet of code mentioned for SampleChooserActivity.java. (Kept giving me errors)

I instead used :

group = new SampleGroup("Local Videos");
group.addAll(Samples.LOCAL_VIDEOS);
sampleGroups.add(group);

What am I doing wrong? Does the path of the file change for every device?

Wonderment answered 27/2, 2016 at 20:32 Comment(1)
github.com/HamidrezaAmz/MagicalExoPlayerCoreen
H
30

Haven't tried the demo app, but I have managed to create my own example of playing local audio files and have posted it here: https://github.com/nzkozar/ExoplayerExample

Here is the main part that does all the work of preparing the player from a file Uri:

private void prepareExoPlayerFromFileUri(Uri uri){
        exoPlayer = ExoPlayerFactory.newSimpleInstance(this, new DefaultTrackSelector(null), new DefaultLoadControl());
        exoPlayer.addListener(eventListener);

        DataSpec dataSpec = new DataSpec(uri);
        final FileDataSource fileDataSource = new FileDataSource();
        try {
            fileDataSource.open(dataSpec);
        } catch (FileDataSource.FileDataSourceException e) {
            e.printStackTrace();
        }

        DataSource.Factory factory = new DataSource.Factory() {
            @Override
            public DataSource createDataSource() {
                return fileDataSource;
            }
        };
        MediaSource audioSource = new ExtractorMediaSource(fileDataSource.getUri(),
                factory, new DefaultExtractorsFactory(), null, null);

        exoPlayer.prepare(audioSource);
    }

You can get the Uri like this: Uri.fromFile(file)

After you have prepared your file for playback as shown above, you only need to call exoPlayer.setPlayWhenReady(true); to start playback.

For a video file you'd probably only need to attach a surface view to your exoPlayer object, but I haven't really done this with ExoPlayer2 yet.

Happen answered 11/3, 2017 at 23:33 Comment(3)
All these code just to pass the file path to the ExoPlayer, which could be done with one line for VideoView? My god, the designers of ExoPlayer must be crazy or sadistic. Also AS says ExtractorMediaSource is deprecated (SDK 29).Paugh
I know right. I was getting angry and upset when looking at this solution. Also, I was frustrated not to find a simple one line API to play a media file like we did with MediaPlayer. I think I might just look for an alternative, uggh.Drachm
this is now deprecatedBossuet
U
11

For those who want to play a video from assets using ExoPlayer 2 here is a way:

String playerInfo = Util.getUserAgent(context, "ExoPlayerInfo");
DefaultDataSourceFactory dataSourceFactory = new DefaultDataSourceFactory(
        context, playerInfo
);
MediaSource mediaSource = new ExtractorMediaSource.Factory(dataSourceFactory)
    .setExtractorsFactory(new DefaultExtractorsFactory())
    .createMediaSource(Uri.parse("asset:///your_video.mov"));
player.prepare(mediaSource);
Unsavory answered 29/8, 2018 at 13:52 Comment(0)
C
5

This worked for me.Try these steps:

Get path of the file and start the player

File myFile = new File(extStore.getAbsolutePath() + "/folder/videos/" + video_name);  
videoUrl= String.valueOf(Uri.fromFile(myFile));  
initializePlayer(videoUrl);

Initializing player

private void initializePlayer(String videoUrl) {
    player = ExoPlayerFactory.newSimpleInstance(
            new DefaultRenderersFactory(getActivity()),
            new DefaultTrackSelector(), new DefaultLoadControl());

    playerView.setPlayer(player);

    player.setPlayWhenReady(playWhenReady);
    player.seekTo(currentWindow, playbackPosition);

    Uri uri = Uri.parse(videoUrl);
    MediaSource mediaSource = buildMediaSource(uri);
    player.prepare(mediaSource, resetPositionBoolean, false);
}   

Building media source

  private MediaSource buildMediaSource(Uri uri) {
    return new ExtractorMediaSource.Factory(
            new DefaultDataSourceFactory(getActivity(),"Exoplayer-local")).
            createMediaSource(uri);
}
Clavus answered 17/4, 2019 at 7:24 Comment(2)
So complicated :/Drachm
There is no such class called "ExoPlayerFactory" in version 2.18.1Surrounding
G
1

For those looking to load from the assets folder:

assets/xyz.mp4

it works by loading the file with:

"file:/android_asset/xyz.mp4"

and using the DefaultDataSourceFactory. Checked on exoplayer 2.4.4.

Gran answered 28/6, 2019 at 9:32 Comment(1)
The question was about accessing from the SD card.Bloodshot
D
0

In some devices you could directly used this path '/sdcard/nameoffile.mp4".

Definiens answered 28/2, 2016 at 2:32 Comment(0)
P
0

If you need to get data from the assets field this will work. THIS WON'T WORK FOR DATA TAKEN FROM THE SD CARD

package com.studio.mattiaferigutti.exoplayertest

import android.annotation.SuppressLint
import android.net.Uri
import android.os.Bundle
import android.util.Log
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import com.google.android.exoplayer2.*
import com.google.android.exoplayer2.source.ProgressiveMediaSource
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector
import com.google.android.exoplayer2.upstream.*
import com.google.android.exoplayer2.upstream.DataSource.Factory
import com.google.android.exoplayer2.util.Util
import kotlinx.android.synthetic.main.activity_main.*


class MainActivity : AppCompatActivity(), Player.EventListener {

    private var player: SimpleExoPlayer? = null
    private var playWhenReady = true
    private var currentWindow = 0
    private var playbackPosition: Long = 0

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }

    public override fun onStart() {
        super.onStart()
        if (Util.SDK_INT > 23) {
            initializePlayer("assets:///your_file.your_extension")
        }
    }

    public override fun onResume() {
        super.onResume()
        hideSystemUi()
        if (Util.SDK_INT <= 23 || player == null) {
            initializePlayer("assets:///your_file.your_extension")
        }
    }

    public override fun onPause() {
        super.onPause()
        if (Util.SDK_INT <= 23) {
            releasePlayer()
        }
    }

    public override fun onStop() {
        super.onStop()
        if (Util.SDK_INT > 23) {
            releasePlayer()
        }
    }

    private fun initializePlayer(path: String) {
        if (player == null) {
            val trackSelector = DefaultTrackSelector(this)
            trackSelector.setParameters(
                trackSelector.buildUponParameters().setMaxVideoSizeSd())
            player = SimpleExoPlayer.Builder(this)
                .setTrackSelector(trackSelector)
                .build()
        }
        video_view?.player = player
        video_view?.requestFocus()

        val dataSourceFactory = Factory { AssetDataSource(this@MainActivity) }

        val videoSource = ProgressiveMediaSource.Factory(dataSourceFactory)
            .createMediaSource(Uri.parse(path))

        player?.playWhenReady = playWhenReady
        player?.seekTo(currentWindow, playbackPosition)
        player?.addListener(this)
        player?.prepare(videoSource)
    }

    private fun releasePlayer() {
        if (player != null) {
            playbackPosition = player?.currentPosition!!
            currentWindow = player?.currentWindowIndex!!
            playWhenReady = player?.playWhenReady!!
            player?.removeListener(this)
            player?.release()
            player = null
        }
    }

    /**
     * set fullscreen
     */
    @SuppressLint("InlinedApi")
    private fun hideSystemUi() {
        video_view?.systemUiVisibility = (View.SYSTEM_UI_FLAG_LOW_PROFILE
                or View.SYSTEM_UI_FLAG_FULLSCREEN
                or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
                or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION)
    }

    override fun onPlayerError(error: ExoPlaybackException) {
        super.onPlayerError(error)

        //handle the error
    }

    override fun onPlayerStateChanged(playWhenReady: Boolean, playbackState: Int) {
        val stateString: String = when (playbackState) {
            ExoPlayer.STATE_IDLE -> "ExoPlayer.STATE_IDLE      -"
            ExoPlayer.STATE_BUFFERING -> "ExoPlayer.STATE_BUFFERING -"
            ExoPlayer.STATE_READY -> "ExoPlayer.STATE_READY     -"
            ExoPlayer.STATE_ENDED -> "ExoPlayer.STATE_ENDED     -"
            else -> "UNKNOWN_STATE             -"
        }
        Log.d(TAG, "changed state to " + stateString
                + " playWhenReady: " + playWhenReady)
    }

    companion object {
        private val TAG = MainActivity::class.java.name
    }
}
Polypropylene answered 20/8, 2020 at 13:59 Comment(0)
L
-1

For those who trying to play a video file from res/raw* folder, here is the solution. Keep in mind that i used the **2.8.0 version of the ExoPlayer.

public class MainActivity extends AppCompatActivity {

PlayerView playerView;
SimpleExoPlayer simpleExoPlayer;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    playerView=findViewById(R.id.playerView);
}

@Override
protected void onStart() {
    simpleExoPlayer= ExoPlayerFactory.newSimpleInstance(this,new DefaultTrackSelector());
    DefaultDataSourceFactory defaultDataSourceFactory=new DefaultDataSourceFactory(this, Util.getUserAgent(this,"YourApplicationName"));
    simpleExoPlayer.setPlayWhenReady(true);
    ExtractorMediaSource extractorMediaSource=new ExtractorMediaSource.Factory(defaultDataSourceFactory).createMediaSource(RawResourceDataSource.buildRawResourceUri(R.raw.video));
    simpleExoPlayer.prepare(extractorMediaSource);
    playerView.setPlayer(simpleExoPlayer);

    super.onStart();
}

@Override
protected void onStop() {
    playerView.setPlayer(null);
    simpleExoPlayer.release();
    simpleExoPlayer=null;
    super.onStop();
}

}

Lang answered 5/5, 2020 at 7:5 Comment(0)
B
-2

Video playback from sd card worked with following code. My test file is in Videos directory in sdcard.

public static final Sample[] LOCAL_VIDEOS = new Sample[] {
        new Sample("test",
            Environment.getExternalStorageDirectory()+"/Videos/test.mp4", Util.TYPE_OTHER),
};
Briticism answered 6/3, 2016 at 11:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.