简体   繁体   English

通过“资产”文件夹中的文件夹使用 ExoPlayer 播放视频

[英]Play video with ExoPlayer through a folder in the "assets" folder

I'm trying to play a video with the use of ExoPlayer API and by using the exoplayer library of version: 'com.google.android.exoplayer:exoplayer:2.8.1' .我正在尝试使用ExoPlayer API 并使用版本的 exoplayer 库播放视频: 'com.google.android.exoplayer:exoplayer:2.8.1' I want to play a video called video.mp4 which is in a folder called folder1 and this folder in inside the folder assets in the res ( res/assets/folder1/video.mp4 ).我想播放一个名为video.mp4的视频,该视频位于名为folder1的文件夹中,该文件夹位于resres/assets/folder1/video.mp4 )的文件夹assets中。 I cannot get my code to play the video.我无法获取播放视频的代码。 Please help me.请帮我。

My MainActivity.java :我的MainActivity.java

package com.example.amandeep.example2;

import android.content.pm.ActivityInfo;
import android.net.Uri;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ArrayAdapter;

import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ExoPlayerFactory;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.source.ConcatenatingMediaSource;
import com.google.android.exoplayer2.source.ExtractorMediaSource;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.source.MergingMediaSource;
import com.google.android.exoplayer2.source.SingleSampleMediaSource;
import com.google.android.exoplayer2.trackselection.AdaptiveTrackSelection;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.ui.PlayerView;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
import com.google.android.exoplayer2.util.MimeTypes;
import com.google.android.exoplayer2.util.Util;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity
{
    SimpleExoPlayer video_player;
    PlayerView player_screen;
    DefaultTrackSelector track_selector;
    DefaultBandwidthMeter band_width_meter = new DefaultBandwidthMeter();

    MediaSource mediaSource;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

        player_screen = findViewById (R.id.player_screen);
        player_screen.requestFocus();

        TrackSelection.Factory video_track_selection_factory = new AdaptiveTrackSelection.Factory(band_width_meter);
        track_selector = new DefaultTrackSelector(video_track_selection_factory);
        video_player = ExoPlayerFactory.newSimpleInstance(this, track_selector);

        player_screen.setPlayer(video_player);
        video_player.setPlayWhenReady(true);

        DataSource.Factory data_source_factory = new DefaultDataSourceFactory(this, Util.getUserAgent(this, "Application Name"), new DefaultBandwidthMeter());
        Uri url = Uri.parse("file:///android_asset/folder/video.mp4");
        mediaSource = new ExtractorMediaSource.Factory(data_source_factory).createMediaSource(url);

        video_player.prepare(mediaSource);
    }
}

My activity_main.xml :我的activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <com.google.android.exoplayer2.ui.PlayerView
        android:id="@+id/player_screen"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_gravity="center"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:use_controller="true" />

</android.support.constraint.ConstraintLayout>

Note: I want to use the Uri.parse method.注意:我想使用Uri.parse方法。

IF SOMEONE CANNOT UNDERSTAND MY QUESTION PROPERLY, PLEASE COMMENT BELOW.如果有人不能正确理解我的问题,请在下方评论。

IF URI.PARSE METHOD CANNOT USE FILES FROM ASSETS THEN PLEASE TELL ME如果 URI.PARSE 方法不能使用资产中的文件,请告诉我

This is my code to play audio file, hope it helps you.这是我播放音频文件的代码,希望对您有所帮助。

    private void prepareExoPlayerFromAssetResourceFile(int current_file) {
    exoPlayer = ExoPlayerFactory.newSimpleInstance(this, new DefaultTrackSelector((TrackSelection.Factory) null), new DefaultLoadControl());
    exoPlayer.addListener(eventListener);

    //DataSpec dataSpec = new DataSpec(uri);
    //DataSpec dataSpec = new DataSpec(Uri.parse("asset:///001.mp3"));
    DataSpec dataSpec = new DataSpec(Uri.parse("asset:///" + current_file +".mp3"));
    final AssetDataSource assetDataSource = new AssetDataSource(this);
    try {
        assetDataSource.open(dataSpec);
    } catch (AssetDataSource.AssetDataSourceException e) {
        e.printStackTrace();
    }

    DataSource.Factory factory = new DataSource.Factory() {
        @Override
        public DataSource createDataSource() {
            //return rawResourceDataSource;
            return assetDataSource;
        }
    };

    MediaSource audioSource = new ExtractorMediaSource(assetDataSource.getUri(),
            factory, new DefaultExtractorsFactory(), null, null);

    exoPlayer.prepare(audioSource);
    initMediaControls();

}

ExoPlayer 2.12 introduces the MediaItem class so you can do: ExoPlayer 2.12 引入了MediaItem类,因此您可以执行以下操作:

val firstVideoUri = Uri.parse("asset:///localfile.mp4")
val firstItem = MediaItem.fromUri(firstVideoUri)
player.addMediaItem(firstItem)

Note that the URI should start with asset:/// not assets:///请注意,URI 应该以asset:///开头,而不是assets:///

Try a uri of this format:尝试使用这种格式的 uri:

file:///android_asset/

For your example that would need to be:对于您需要的示例:

Uri url = Uri.parse("file:///android_asset/folder1/video.mp4");

I'm using similar code for playing video from my assets folder with ExoPlayer and it works good.我正在使用类似的代码通过 ExoPlayer 播放我的资产文件夹中的视频,并且效果很好。
But I noticed you mentioned diferent folders in description and code.但是我注意到您在描述和代码中提到了不同的文件夹。 You are saying the folder in assets is named folder1 but in code you have folder .您是说资产中的文件夹名为folder1但在代码中您有folder
So make sure you have correct path to video.因此,请确保您有正确的视频路径。

This may be useful:这可能很有用:

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") //"assets:///pillwheel_pills.mp4"
        }
    }

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

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

You can find the full source code on GitHub您可以在GitHub 上找到完整的源代码

I write this answer because some methods on old answers deprecated:我写这个答案是因为不推荐使用旧答案的一些方法:

fun prepareExoPlayerFromAssetResource(
 uri: String = "asset://example.mp3") 
{
  val dataSourceFactory = DataSource.Factory {AssetDataSource(context)}
  val mediaSource = ProgressiveMediaSource
                     .Factory(dataSourceFactory)
                     .createMediaSource(MediaItem.fromUri(Uri.parse(uri)))
        
  exoPlayer.addMediaSource(audioSource)
  exoPlayer.prepare()
  exoPlayer.play()
}

I hope this is useful for someone:)我希望这对某人有用:)

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

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