简体   繁体   English

ExoPlayer - 在 SD 卡中播放本地 mp4 文件

[英]ExoPlayer - play local mp4 file in SD card

I am using the Exoplayer Demo app and want to preload a MP4 video from SD card.我正在使用 Exoplayer 演示应用程序并希望从 SD 卡预加载 MP4 视频。 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.在我的 exoplayer 演示中没有名为 DemoUtil.java 的类。 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.我也无法使用他们为 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?每个设备的文件路径都会改变吗?

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还没有尝试过演示应用程序,但我已经设法创建了自己的播放本地音频文件的示例并将其发布在此处: https : //github.com/nzkozar/ExoplayerExample

Here is the main part that does all the work of preparing the player from a file Uri:这是完成从文件 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)您可以像这样获取 Uri: Uri.fromFile(file)

After you have prepared your file for playback as shown above, you only need to call exoPlayer.setPlayWhenReady(true);如上所示准备好播放文件后,您只需调用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.对于视频文件,您可能只需要将表面视图附加到 exoPlayer 对象,但我还没有真正使用 ExoPlayer2 完成此操作。

For those who want to play a video from assets using ExoPlayer 2 here is a way:对于那些想要使用ExoPlayer 2从资产播放视频的人,这里有一种方法:

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

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

For those looking to load from the assets folder:对于那些希望从资产文件夹加载的人:

assets/xyz.mp4资产/xyz.mp4

it works by loading the file with:它通过加载文件来工作:

"file:/android_asset/xyz.mp4" “文件:/android_asset/xyz.mp4”

and using the DefaultDataSourceFactory.并使用 DefaultDataSourceFactory。 Checked on exoplayer 2.4.4.在 exoplayer 2.4.4 上检查。

在某些设备中,您可以直接使用此路径“/sdcard/namefile.mp4”。

If you need to get data from the assets field this will work.如果您需要从assets字段获取数据,这将起作用。 THIS WON'T WORK FOR DATA TAKEN FROM THE SD CARD这不适用于从 SD 卡中获取的数据

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

Video playback from sd card worked with following code.从 SD 卡播放视频使用以下代码。 My test file is in Videos directory in sdcard.我的测试文件在 sdcard 的 Videos 目录中。

public static final Sample[] LOCAL_VIDEOS = new Sample[] {
        new Sample("test",
            Environment.getExternalStorageDirectory()+"/Videos/test.mp4", Util.TYPE_OTHER),
};

For those who trying to play a video file from res/raw* folder, here is the solution.对于那些试图从res/raw* 文件夹播放视频文件的人,这里是解决方案。 Keep in mind that i used the **2.8.0 version of the ExoPlayer .请记住,我使用ExoPlayer的 **2.8.0版本。

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

} }

For Exo player 2.13.3 :对于Exo 播放器 2.13.3

implementation 'com.google.android.exoplayer:exoplayer:2.13.3'

Place your video in assets folder:将您的视频放在资产文件夹中:

const val VIDEO_URL = "asset:///sample.mkv"

Initialize player:初始化播放器:

val mediaItem: MediaItem = MediaItem.fromUri(VIDEO_URL)
player.setMediaItem(mediaItem)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM