如何获取 ExoPlayer 的本地视频 Uri 2.x

How to get local video Uri for ExoPlayer 2.x

我在 res/raw 文件夹中有一个 dog.mp4 视频文件,我想用 ExoPlayer 播放它。我正在尝试弄清楚如何从 ExoPlayer 开发人员指南 (https://google.github.io/ExoPlayer/guide.html):

中获取这行代码的视频 Uri
MediaSource videoSource = new ExtractorMediaSource(mp4VideoUri,
    dataSourceFactory, extractorsFactory, null, null);

为了得到它,我使用了这一行:

Uri mp4VideoUri = Uri.parse("android.resources://"+getPackageName()+"/"+R.raw.dog);

也试过这种语法:android.resource://[package]/[res type]/[res name]

但是 SimpleExoPlayerView 保持黑色,我得到以下错误:

com.google.android.exoplayer2.upstream.HttpDataSource$HttpDataSourceException: Unable to connect to android.resources://lt.wilkas.deleteexoplayer/2131099648

我做错了什么?

我发现 res/raw 文件夹不能用于存储 ExoPlayer 的本地视频。它们应该放在 assets 文件夹中。

不要将您的视频从 raw 移动到任何其他文件夹

使用此代码播放视频:

    PlayerView playerView = findViewById(R.id.player_view);

    SimpleExoPlayer player = ExoPlayerFactory.newSimpleInstance(this);

    // Bind the player to the view.
    playerView.setPlayer(player);

    // Produces DataSource instances through which media data is loaded.
    DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(this, Util.getUserAgent(this, "yourApplicationName"));

    // This is the MediaSource representing the media to be played.
    MediaSource firstSource = new ExtractorMediaSource.Factory(dataSourceFactory).createMediaSource(RawResourceDataSource.buildRawResourceUri(R.raw.dog));

    // Prepare the player with the source.
    player.prepare(firstSource);

res/raw 文件夹可用于通过其 URI 访问 ExoPlayer 的本地视频文件。这是不会给出 格式错误 URL 异常 的解决方案,它对我有用。您必须使用 RawResourceDataSource.buildRawResourceUri(R.raw.video) 方法 RawResourceDataSource class。请记住,我使用的是 2.8.0 版本的 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();
}

}

这里是使用 ExoPlayer 从 res/raw 加载 video/audio 文件的示例:

val player = ExoPlayerFactory.newSimpleInstance(context,DefaultTrackSelector())

val rawDataSource = RawResourceDataSource(context)

rawDataSource.open(DataSpec(RawResourceDataSource.buildRawResourceUri(R.raw.brown)))

val mediaSource = ExtractorMediaSource.Factory(DataSource.Factory { rawDataSource })
    .createMediaSource(rawDataSource.uri)

player.playWhenReady = true
player.prepare(mediaSource)

sample copied from

这段代码适合我。

fun buildMediaSourceRaw() : MediaSource{
        val dataSourceFactory = DefaultDataSourceFactory(context, "exoPlayer")
        val uri = RawResourceDataSource.buildRawResourceUri(R.raw.my_video)
        return ProgressiveMediaSource.Factory(dataSourceFactory).createMediaSource(uri)
    }

然后

player?.prepare(buildMediaSourceRaw())

根据 ExoPlayer 2.12,它更易于使用 MediaItem。 要创建它,我们需要可以从 RawResourceDataSource.buildRawResourceUri 生成的 Uri。 就是这样。只需设置此 MediaItem 执行 prepare() 并在准备好后播放:

SimpleExoPlayer.Builder(view.context).build().apply {
    val uri = RawResourceDataSource.buildRawResourceUri(R.raw.video)
    setMediaItem(MediaItem.fromUri(uri))
    prepare()
    playWhenReady = true
}