【问题标题】:ExoPlayer - play local mp4 file in SD cardExoPlayer - 在 SD 卡中播放本地 mp4 文件
【发布时间】:2016-06-11 01:10:43
【问题描述】:

我正在使用 Exoplayer Demo 应用程序并想从 SD 卡预加载 MP4 视频。 我已经从this post 尝试了实现,但它不起作用。在我的 exoplayer Demo 中没有名为 DemoUtil.java 的类。 改为使用:

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

我也无法使用他们为 SampleChooserActivity.java 提到的代码的 sn-p。 (不断给我错误)

我改为使用:

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

我做错了什么?每个设备的文件路径都会改变吗?

【问题讨论】:

标签: java android android-sdcard exoplayer


【解决方案1】:

尚未尝试演示应用程序,但我设法创建了自己的播放本地音频文件的示例并将其发布在此处: https://github.com/nzkozar/ExoplayerExample

这是完成从文件 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);
    }

你可以这样获取 Uri:Uri.fromFile(file)

如上图所示准备好播放文件后,只需拨打exoPlayer.setPlayWhenReady(true);即可开始播放。

对于视频文件,您可能只需要将表面视图附加到 exoPlayer 对象,但我还没有真正使用 ExoPlayer2 完成此操作。

【讨论】:

  • 完美答案...毫无疑问:)
  • 所有这些代码只是为了将文件路径传递给ExoPlayer,这可以通过VideoView的一行来完成吗?我的天,ExoPlayer 的设计者一定是疯了或虐待狂。 AS 还说 ExtractorMediaSource 已弃用(SDK 29)。
  • 我知道是对的。看到这个解决方案时,我感到愤怒和不安。此外,我很沮丧没有找到一个简单的单行 API 来播放媒体文件,就像我们使用 MediaPlayer 所做的那样。我想我可能只是寻找一个替代方案,呃。
  • 现在已弃用
【解决方案2】:

对于那些想要使用 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);

【讨论】:

    【解决方案3】:

    这对我有用。请尝试以下步骤:

    获取文件路径并启动播放器

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

    正在初始化播放器

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

    构建媒体源

      private MediaSource buildMediaSource(Uri uri) {
        return new ExtractorMediaSource.Factory(
                new DefaultDataSourceFactory(getActivity(),"Exoplayer-local")).
                createMediaSource(uri);
    }
    

    【讨论】:

    • 这么复杂:/
    【解决方案4】:

    对于那些希望从资产文件夹加载的人:

    资产/xyz.mp4

    它通过加载文件来工作:

    “文件:/android_asset/xyz.mp4”

    并使用 DefaultDataSourceFactory。在 exoplayer 2.4.4 上检查。

    【讨论】:

    • 问题是关于从 SD 卡访问。
    【解决方案5】:

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

    【讨论】:

      【解决方案6】:

      如果您需要从assets 字段获取数据,这将起作用。这不适用于从 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
          }
      }
      

      【讨论】:

        【解决方案7】:

        对于那些试图从 res/raw* 文件夹播放视频文件的人来说,这里是解决方案。请记住,我使用的是 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();
        }
        

        }

        【讨论】:

          【解决方案8】:

          从 sd 卡播放视频可以使用以下代码。我的测试文件在 sdcard 的 Videos 目录中。

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

          【讨论】:

            猜你喜欢
            • 2018-01-15
            • 2015-04-23
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-01-12
            • 1970-01-01
            • 2019-01-12
            相关资源
            最近更新 更多