【问题标题】:How to use android exoplayer如何使用android exoplayer
【发布时间】:2015-12-25 14:31:55
【问题描述】:

我希望在我的应用中实现 Google 的 ExoPlayer。他们的文档对我来说似乎很模糊,我所寻找的只是从 URL 播放视频,没有复杂的自定义设置或类似的东西。还没有找到任何关于如何做到这一点的教程。他们在 git 上的示例对于我的需要来说太复杂了,而且由于我是视频流的新手,所以我不太了解。到目前为止,我所做的只是显示com.google.android.exoplayer.AspectRatioFrameLayout

基本上,我有一个 URL。我需要播放视频,并在用户翻转屏幕时处理onConfigurationChanged

谁能帮忙?

【问题讨论】:

  • 在主要搜索引擎上搜索exoplayer tutorial 会出现davekb.com/…youtube.com/watch?v=6VjF638VObA。 ExoPlayer 开发者recommend reviewing their demo app.
  • 我查看了他们的演示应用程序,但我什么都不懂。正如我所说,我是视频流的新手。我还查看了 davekb 的示例,不仅不推荐使用 FrameworkSampleSource 类,而且我没有他似乎拥有的相同构造函数。他有FrameworkSampleSource(mContext, uri, /* headers */ null, numRenderers),我有一个没有渲染器数量的构造函数
  • 好的,只要确保你尝试了那里的东西。我还没有玩过 ExoPlayer(虽然它实际上在我的短名单上),而且我不觉得它是针对简单场景的。
  • 我只需要自定义外观。我知道经典方式不提供这样做的方法,但 exoplayer 提供。希望有人会发布一个例子
  • 我正在创建一个允许您执行此操作的库。敬请期待;)

标签: android video-streaming exoplayer


【解决方案1】:

ExoMedia 库将 exoplayer 包装在更简单的 api 中,并提供用于布局的视频视图。见github上的用法示例:https://github.com/brianwernick/ExoMedia/

【讨论】:

  • 我可以确认我在我的项目中成功地使用了这个库来替换 VideoView,并且效果很好。
  • 这个库易于使用,但显示的视频略微倾斜。 github.com/brianwernick/ExoMedia/issues/318
  • 这个库也不支持无缝循环,所以如果你需要这个功能,你应该试试别的!
  • 即使 ExoMedia 包装器使使用 exoplayer 变得更容易,但如果您计划动态调整视频大小并附加或分离播放器,这将是一场噩梦,因为它不处理表面调整大小并且手动完成最终会释放表面视图
  • 这个库有问题!我不会推荐它!
【解决方案2】:

Exoplayer 是一个非常先进的库。即使写一个最低限度的代码也需要 40-50 行代码。所以如果你真的想用刀切洋葱,这里有一个直接复制的意大利面:

//manifest.xml 

<manifest ...>
  <uses-permission android:name="android.permission.INTERNET"/>
  <application
    android:usesCleartextTraffic="true"
    ...>

    ...

  </application>
</manifest>
//app/build.gradle
apply plugin: 'com.android.application'

android {
    ...
    compileOptions {
        sourceCompatibility = 1.8
        targetCompatibility = 1.8
    }
}

dependencies {
    ...
    implementation 'com.google.android.exoplayer:exoplayer:2.10.4'
}



    protected void onCreate(Bundle savedInstanceState) {
        ...

        Context ctx =this;
        String CONTENT_URL = "https://www.radiantmediaplayer.com/media/bbb-360p.mp4";
        int playerID=R.id.pv_main;
        int appNameStringRes = R.string.app_name;
        startPlayingVideo(this,CONTENT_URL,playerID,appNameStringRes);


    }

    //
    private void startPlayingVideo(Context ctx , String CONTENT_URL, int playerID, String appNameRes) {

        PlayerView pvMain = ctx.findViewById(playerID);

        //BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
        //TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveTrackSelection.Factory(bandwidthMeter);        
        //TrackSelector trackSelectorDef = new DefaultTrackSelector(videoTrackSelectionFactory);
        TrackSelector trackSelectorDef = new DefaultTrackSelector();

        SimpleExoPlayer absPlayerInternal = ExoPlayerFactory.newSimpleInstance(ctx, trackSelectorDef);

        String userAgent = Util.getUserAgent(ctx, ctx.getString(appNameRes));

        DefaultDataSourceFactory defdataSourceFactory = new DefaultDataSourceFactory(ctx,userAgent);
        Uri uriOfContentUrl = Uri.parse(CONTENT_URL);
        MediaSource mediaSource = new ProgressiveMediaSource.Factory(defdataSourceFactory).createMediaSource(uriOfContentUrl);

        absPlayerInternal.prepare(mediaSource);
        absPlayerInternal.setPlayWhenReady(true);

        pvMain.setPlayer(absPlayerInternal);

    }

    private void stopPlayer(PlayerView pv,SimpleExoPlayer absPlayer){
        pv.setPlayer(null);
        absPlayer.release();
        absPlayer = null;
    }

只需在活动布局中添加player view,在onCreate() 中调用startPlayingVideo(...),在onStop() 中调用stopPlayer()。我不是专家,但是如果您愿意,我可以尝试解释一下,但是您没有要求任何复杂的东西,所以这里只是代码

【讨论】:

    【解决方案3】:

    如果您只想显示视频 URL,则使用 VideoView 会更好。 ExoPlayer 需要一些开发工作,即使是调用它的简单实例也是如此。但是,在活跃的开源社区的支持下,播放速度更快、效率更高。 This link 提供了一个很好的实施过程,提供了切换到 ExoPlayer 的充分理由。 当然,请查看official developer guide,更新版本具有拆分模块以便于实现。

    【讨论】:

      【解决方案4】:
      //Add dependency in manifest file 
          implementation 'com.google.android.exoplayer:exoplayer:2.7.3'
      
      
      // Add exoplayer in your layout(xml) file 
       <RelativeLayout
              android:id="@+id/rl_video"
              android:layout_width="match_parent"
              android:layout_height="wrap_content">
      
          <com.google.android.exoplayer2.ui.PlayerView
              android:id="@+id/videoFullScreenPlayer"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:background="#A6000000"
              app:controller_layout_id="@layout/exo_playback_control_view"
              app:player_layout_id="@layout/exo_simple_player_view"
              app:repeat_toggle_modes="none"
              app:show_timeout="45000"
              app:surface_type="texture_view"
              />
              <ProgressBar
                  android:id="@+id/spinnerVideoDetails"
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:layout_centerInParent="true"
                  android:layout_marginStart="8dp"
                  android:layout_marginTop="8dp"
                  android:layout_marginEnd="8dp"
                  android:layout_marginBottom="8dp"
                  android:indeterminate="true"/>
          </RelativeLayout>
      
      
      
      
      // open video with below code
      
      // initialise varible 
       PlayerView videoFullScreenPlayer;
          SimpleExoPlayer player;
          ProgressBar spinnerVideoDetails;
      
      
      // find Id 
       videoFullScreenPlayer = findViewById(R.id.videoFullScreenPlayer);
              spinnerVideoDetails = findViewById(R.id.spinnerVideoDetails);
      
      // open video method 
      private void setUp() {
              initializePlayer();
              if (videoUrl == null) {
                  return;
              }
              buildMediaSource(Uri.parse(videoUrl ));
          }
          private void initializePlayer() {
              if (player == null) {
      
                  BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
                  TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveTrackSelection.Factory(bandwidthMeter);
                  TrackSelector trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory);
                  // 1. Create a default TrackSelector
                  DefaultLoadControl loadControl = new DefaultLoadControl.Builder().setBufferDurationsMs(32*1024, 64*1024, 1024, 1024).createDefaultLoadControl();
                  // 2. Create the player
                  player = ExoPlayerFactory.newSimpleInstance(this, trackSelector, loadControl);
                  videoFullScreenPlayer.setPlayer(player);
              }
          }
      
          private void buildMediaSource(Uri mUri) {
              // Measures bandwidth during playback. Can be null if not required.
              DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
              // Produces DataSource instances through which media data is loaded.
              DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(this,
                      Util.getUserAgent(this, getString(R.string.app_name)), bandwidthMeter);
              // This is the MediaSource representing the media to be played.
              MediaSource videoSource = new ExtractorMediaSource.Factory(dataSourceFactory).createMediaSource(mUri);
              // Prepare the player with the source.
              player.prepare(videoSource);
              player.setPlayWhenReady(true);
              player.addListener(this);
          }
      
          private void releasePlayer() {
              if (player != null) {
                  player.release();
                  player = null;
              }
          }
      
          private void pausePlayer() {
              if (player != null) {
                  player.setPlayWhenReady(false);
                  player.getPlaybackState();
              }
          }
      
          private void resumePlayer() {
              if (player != null) {
                  player.setPlayWhenReady(true);
                  player.getPlaybackState();
              }
          }
      
          @Override
          protected void onPause() {
              super.onPause();
              pausePlayer();
             /* if (mRunnable != null) {
                  mHandler.removeCallbacks(mRunnable);
              }*/
          }
      
          @Override
          protected void onRestart() {
              super.onRestart();
              resumePlayer();
          }
      
          @Override
          protected void onDestroy() {
              super.onDestroy();
              releasePlayer();
          }
      
          @Override
          public void onTimelineChanged(Timeline timeline, Object manifest, int reason) {
          }
      
          @Override
          public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
          }
      
          @Override
          public void onLoadingChanged(boolean isLoading) {
          }
      
          @Override
          public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
              switch (playbackState) {
                  case Player.STATE_BUFFERING:
                      spinnerVideoDetails.setVisibility(View.VISIBLE);
                      break;
                  case Player.STATE_ENDED:
                      // Activate the force enable
                      break;
                  case Player.STATE_IDLE:
                      break;
                  case Player.STATE_READY:
                      spinnerVideoDetails.setVisibility(View.GONE);
                      break;
                  default:
                      // status = PlaybackStatus.IDLE;
                      break;
              }
          }
      
          @Override
          public void onRepeatModeChanged(int repeatMode) {
          }
      
          @Override
          public void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) {
          }
      
          @Override
          public void onPlayerError(ExoPlaybackException error) {
          }
      
          @Override
          public void onPositionDiscontinuity(int reason) {
          }
      
          @Override
          public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {
          }
      
          @Override
          public void onSeekProcessed() {
          }
      

      【讨论】:

        【解决方案5】:

        这是一个名为 MagicalExoPlayer 的新 Github 库,它基于 ExoPlayer。

        支持 MP4HLSDash

        支持自定义纵横比

        支持全屏

        【讨论】:

        • 全屏功能在 Kotlin 中不起作用。提醒 Kotlin 开发人员
        猜你喜欢
        • 1970-01-01
        • 2016-01-26
        • 1970-01-01
        • 1970-01-01
        • 2017-04-12
        • 1970-01-01
        • 1970-01-01
        • 2020-04-13
        • 1970-01-01
        相关资源
        最近更新 更多