当前位置: 首页 > 知识库问答 >
问题:

Exoplayer 2质量渲染像320p,480p,720p和1080p

郑哲彦
2023-03-14
package com.geoffledak.exoplayerfullscreen;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

private final String STATE_RESUME_WINDOW = "resumeWindow";
private final String STATE_RESUME_POSITION = "resumePosition";
private final String STATE_PLAYER_FULLSCREEN = "playerFullscreen";

private SimpleExoPlayerView mExoPlayerView;
private MediaSource mVideoSource;
private boolean mExoPlayerFullscreen = false;
private FrameLayout mFullScreenButton;
private ImageView mFullScreenIcon;
private ImageButton btn_settings;
private ExoPlayer player;

private Dialog mFullScreenDialog;

private int mResumeWindow;
private long mResumePosition;

@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    btn_settings = (ImageButton) findViewById(R.id.btn_settings);

    btn_settings.setOnClickListener(this);


    if (savedInstanceState != null) {
        mResumeWindow = savedInstanceState.getInt(STATE_RESUME_WINDOW);
        mResumePosition = savedInstanceState.getLong(STATE_RESUME_POSITION);
        mExoPlayerFullscreen = savedInstanceState.getBoolean(STATE_PLAYER_FULLSCREEN);
    }
}

@Override
public void onSaveInstanceState(Bundle outState) {

    outState.putInt(STATE_RESUME_WINDOW, mResumeWindow);
    outState.putLong(STATE_RESUME_POSITION, mResumePosition);
    outState.putBoolean(STATE_PLAYER_FULLSCREEN, mExoPlayerFullscreen);

    super.onSaveInstanceState(outState);
}

private void initFullscreenDialog() {

    mFullScreenDialog = new Dialog(this, android.R.style.Theme_Black_NoTitleBar_Fullscreen) {
        public void onBackPressed() {
            if (mExoPlayerFullscreen)
                closeFullscreenDialog();
            super.onBackPressed();
        }
    };
}

 private void openFullscreenDialog() {

    ((ViewGroup) mExoPlayerView.getParent()).removeView(mExoPlayerView);
    mFullScreenDialog.addContentView(mExoPlayerView, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
    mFullScreenIcon.setImageDrawable(ContextCompat.getDrawable(MainActivity.this, R.drawable.ic_fullscreen_shrink));
    mExoPlayerFullscreen = true;
    mFullScreenDialog.show();
   setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}


private void closeFullscreenDialog() {

    ((ViewGroup) mExoPlayerView.getParent()).removeView(mExoPlayerView);
    ((FrameLayout) findViewById(R.id.main_media_frame)).addView(mExoPlayerView);
    mExoPlayerFullscreen = false;
    mFullScreenDialog.dismiss();
    mFullScreenIcon.setImageDrawable(ContextCompat.getDrawable(MainActivity.this, R.drawable.ic_fullscreen_expand));
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}

private void initFullscreenButton() {
    PlaybackControlView controlView = mExoPlayerView.findViewById(R.id.exo_controller);
    mFullScreenIcon = controlView.findViewById(R.id.exo_fullscreen_icon);
    mFullScreenButton = controlView.findViewById(R.id.exo_fullscreen_button);
    mFullScreenButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (!mExoPlayerFullscreen)
                openFullscreenDialog();
            else
                closeFullscreenDialog();
        }
    });
}

private void initExoPlayer() {

    BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
    TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveTrackSelection.Factory(bandwidthMeter);
    TrackSelector trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory);
    LoadControl loadControl = new DefaultLoadControl();
    SimpleExoPlayer player = ExoPlayerFactory.newSimpleInstance(new DefaultRenderersFactory(this), trackSelector, loadControl);
    mExoPlayerView.setPlayer(player);

    boolean haveResumePosition = mResumeWindow != C.INDEX_UNSET;

    if (haveResumePosition) {
        mExoPlayerView.getPlayer().seekTo(mResumeWindow, mResumePosition);
    }
    mExoPlayerView.getPlayer().prepare(mVideoSource);
    mExoPlayerView.getPlayer().setPlayWhenReady(true);
}


@Override
protected void onResume() {
    super.onResume();
    if (mExoPlayerView == null) {
        mExoPlayerView = (SimpleExoPlayerView) findViewById(R.id.exoplayer);
        initFullscreenDialog();
        initFullscreenButton();
        String streamUrl = "http://playertest.longtailvideo.com/adaptive/bbbfull/bbbfull.m3u8";
        String userAgent = Util.getUserAgent(MainActivity.this, getApplicationContext().getApplicationInfo().packageName);
        DefaultHttpDataSourceFactory httpDataSourceFactory = new DefaultHttpDataSourceFactory(userAgent, null, DefaultHttpDataSource.DEFAULT_CONNECT_TIMEOUT_MILLIS, DefaultHttpDataSource.DEFAULT_READ_TIMEOUT_MILLIS, true);
        DefaultDataSourceFactory dataSourceFactory = new DefaultDataSourceFactory(MainActivity.this, null, httpDataSourceFactory);
        Uri daUri = Uri.parse(streamUrl);

        mVideoSource = new HlsMediaSource(daUri, dataSourceFactory, 1, null, null);
    }

    initExoPlayer();

    if (mExoPlayerFullscreen) {
        ((ViewGroup) mExoPlayerView.getParent()).removeView(mExoPlayerView);
        mFullScreenDialog.addContentView(mExoPlayerView, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
        mFullScreenIcon.setImageDrawable(ContextCompat.getDrawable(MainActivity.this, R.drawable.ic_fullscreen_shrink));
        mFullScreenDialog.show();
    }
}


@Override
protected void onPause() {

    super.onPause();

    if (mExoPlayerView != null && mExoPlayerView.getPlayer() != null) {
        mResumeWindow = mExoPlayerView.getPlayer().getCurrentWindowIndex();
        mResumePosition = Math.max(0, mExoPlayerView.getPlayer().getContentPosition());

        mExoPlayerView.getPlayer().release();
    }

    if (mFullScreenDialog != null)
        mFullScreenDialog.dismiss();
}

@Override
public void onClick(View view) {
}

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);

    // Checks the orientation of the screen
    if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
        Toast.makeText(this, "Landscape", Toast.LENGTH_SHORT).show();
    } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
        Toast.makeText(this, "Portrait", Toast.LENGTH_SHORT).show();
    }
}

}

共有1个答案

宣煜
2023-03-14

您需要研究的核心问题是轨道选择(通过TrackSelector)以及TrackSelectionHelper。我将在下面包括重要的代码示例,希望这些示例足以让您开始学习。但最终,只要在演示应用程序中遵循类似的内容,就会让你到达你需要的地方。

您将保留您初始化播放器的曲目选择器,并使用它进行几乎所有的操作。

下面是一个代码块,理想地涵盖了您试图做什么的要点,因为演示确实看起来过于复杂。我还没有运行代码,但已经足够接近了。

    // These two could be fields OR passed around
    int videoRendererIndex;
    TrackGroupArray trackGroups;

    // This is the body of the logic for see if there are even video tracks
    // It also does some field setting
    MappedTrackInfo mappedTrackInfo = trackSelector.getCurrentMappedTrackInfo();
    for (int i = 0; i < mappedTrackInfo.length; i++) {
      TrackGroupArray trackGroups = mappedTrackInfo.getTrackGroups(i);
      if (trackGroups.length != 0) {
        switch (player.getRendererType(i)) {
          case C.TRACK_TYPE_VIDEO:
            videoRendererIndex = i;
            return true;
        }
      }
    }

    // This next part is actually about getting the list. It doesn't include
    // some additional logic they put in for adaptive tracks (DASH/HLS/SS),
    // but you can look at the sample for that (TrackSelectionHelper#buildView())
    // Below you'd be building up items in a list. This just does
    // views directly, but you could just have a list of track names (with indexes)
    for (int groupIndex = 0; groupIndex < trackGroups.length; groupIndex++) {
      TrackGroup group = trackGroups.get(groupIndex);
      for (int trackIndex = 0; trackIndex < group.length; trackIndex++) {
        if (trackIndex == 0) {
          // Beginning of a new set, the demo app adds a divider
        }
        CheckedTextView trackView = ...; // The TextView to show in the list
        // The below points to a util which extracts the quality from the TrackGroup
        trackView.setText(DemoUtil.buildTrackName(group.getFormat(trackIndex)));
    }

    // Assuming you tagged the view with the groupIndex and trackIndex, you
    // can build your override with that info.
    Pair<Integer, Integer> tag = (Pair<Integer, Integer>) view.getTag();
    int groupIndex = tag.first;
    int trackIndex = tag.second;
    // This is the override you'd use for something that isn't adaptive.
    override = new SelectionOverride(FIXED_FACTORY, groupIndex, trackIndex);
    // Otherwise they call their helper for adaptives, which roughly does:
    int[] tracks = getTracksAdding(override, trackIndex);
    TrackSelection.Factory factory = tracks.length == 1 ? FIXED_FACTORY : adaptiveTrackSelectionFactory;
    override = new SelectionOverride(factory, groupIndex, tracks);

    // Then we actually set our override on the selector to switch the quality/track
    selector.setSelectionOverride(rendererIndex, trackGroups, override);
 类似资料:
  • 基本图像渲染 外部资源渲染 摄像机 材质系统 材质资源 Effect 渲染组件参考 Sprite 组件参考 Label 组件参考 LabelOutline 组件参考 LabelShadow 组件参考 Mask 组件参考 MotionStreak 组件参考 ParticleSystem 组件参考 TiledMap 组件参考 TiledTile 组件参考 Spine 组件参考 DragonBones

  • 问题内容: 我正在为我的第一个深度Pyglet项目开发2D Minecraft克隆,但遇到了一个问题。每当我在屏幕上有相当数量的块时,帧速率都会急剧下降。 这是我的渲染方法:我使用字典,键为元组(代表块的坐标),项为纹理。 我遍历整个字典并渲染每个块: PS sx和sy是屏幕滚动的坐标偏移 我想知道是否有一种方法可以更有效地渲染每个块。 问题答案: 我将尽力解释为什么以及如何在不真正了解代码外观的

  • 渲染模式 一个具有默认参数并且未分配值和纹理的标准着色器材质。参数『渲染模式』被突出显示。 标准着色器的第一个参数是 渲染模式。该参数描述对象是否透明。 不透明 — 默认值,适用于没有透明区域的常规固态物体。 镂空 — 允许你创建在不透明和透明区域之间具有硬边缘的透明效果。在该模式下,没有半透明区域,纹理或者 100% 不透明,或者不可见。当创建带有透明区域的材质时,例如叶子、带孔衣服和碎布这类形

  • 这是来自物料界面的模板。我从GitHub的注册中选择了这个模板,我只导入了useState并尝试使用它。 它抛出“太多的重新渲染。React限制渲染数量以防止无限循环材质”, 我尝试过使用反应钩子,因为我不能实现类。

  • 问题内容: 有没有一种方法可以将html渲染为PNG图片?我知道画布是可能的,但我想呈现例如div之类的标准html元素。 问题答案: 我知道这是一个很老的问题,已经有了很多答案,但是我仍然花了几个小时来尝试做自己想做的事情: 给定一个html文件,从命令行生成具有 透明 背景的(png)图像 使用无头的Chrome(此响应的版本为74.0.3729.157),实际上很容易: 命令说明: 您可以从

  • 问题内容: 有没有一种方法可以将html渲染为PNG图片?我知道画布是可能的,但我想呈现例如div之类的标准html元素。 问题答案: 我知道这是一个很老的问题,已经有了很多答案,但是我仍然花了几个小时来尝试做自己想做的事情: 给定一个html文件,从命令行生成具有 透明 背景的(png)图像 使用无头的Chrome(此响应的版本为74.0.3729.157),实际上很容易: 命令说明: 您可以从