【问题标题】:MediaPlayer with multiple SurfaceViews具有多个 SurfaceView 的 MediaPlayer
【发布时间】:2012-06-11 00:37:49
【问题描述】:

我有一个充当服务的媒体播放器,我想更改显示表面视图并让视频在不同的活动中继续播放。

在文档中,它声明我可以在媒体播放器的任何状态下调用 setDisplay,并且在 ICS 上设置显示时,我会得到一个闪烁的视频图像。我看到视频的唯一方法是稍微拉下通知栏或执行一些导致像素被绘制的动作,比如改变音量。

设置很简单... 活动A |绑定到服务实例化媒体播放器附加表面并播放视频。 单击活动 A 中的链接,打开活动 B... 绑定到服务确保视频当前正在播放并将显示设置为不同的表面视图。

我尝试将表面视图的可见性设置为不可见/在以前的活动中消失...首先调用 setDisplay(null)....暂停然后恢复视频..并关闭绘图缓存。

任何帮助或建议将不胜感激。

编辑: android上的视频绝对可怕。 MediaPlayer 对象应该为可以检查的状态保存一个私有变量。错误代码也非常模糊。 VideoView 本身没有帮助,除非您想播放视频,仅此而已。基本上,操纵表面视图绝非易事,我假设这是因为表面视图的绘制方式与常规视图不同。

【问题讨论】:

  • 对不起,我没有更好的解释,但这似乎已通过仅放置 setDisplay(null) 来解决。我有一个回调,当调用surfaceDestroyed 回调时,我将surfaceview 可见性设置为隐藏。取下它后,闪烁停止了。现在这仅适用于 ICS 和 Galaxy Note(非 ICS)我所拥有的只是黑屏,音频在 bg 中播放。所以如果有人有任何建议,我仍然需要帮助。

标签: android surfaceview android-mediaplayer


【解决方案1】:

您应该使用 TextureView 进行显示,并使用 mediaPlayer.setSurface 而不是 mediaPlayer.setDisplay。

从 Activity A 调用简单的 Activity B 并传递视频位置参数。 在 Activity B 中 - 当表面可用时,将其设置到 MediaPlayer 并点击开始。

我看不出它可能失败的任何原因,除非您丢失的媒体播放器发生了一些事情。

是的,Android 很糟糕(不仅在处理视频方面)。

这是我的 VideoFullScreenActivity 代码

public class FullScreenVideoActivity extends AppCompatActivity implements TextureView.SurfaceTextureListener {

    private EventBus bus = EventBus.getDefault();
    private CustomVideoView mAdapterVideoPlayer;
    private TextureView mFullScreenTextureView;
    private RelativeLayout container;
    private boolean mIsPortrait;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_full_screen_video);

        container = (RelativeLayout) findViewById(R.id.container);

        mFullScreenTextureView = (TextureView) findViewById(R.id.fullscreen_texture_surface);
        mFullScreenTextureView.setSurfaceTextureListener(this);
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (!bus.isRegistered(this))
            bus.register(this);
    }

    @Override
    protected void onStop() {
        super.onStop();
        if (bus.isRegistered(this))
            bus.unregister(this);
    }

    @Override
    public void onBackPressed() {
        super.onBackPressed();
        if (mAdapterVideoPlayer != null)
            mAdapterVideoPlayer.setSeekPosition(PiplMediaPlayer.getInstance().getCurrentPosition());
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void fullscreen(VideFullscreenParams videFullscreenParams) {
        this.mAdapterVideoPlayer = videFullscreenParams.customVideoView;

        mIsPortrait = videFullscreenParams.customVideoView.getWidth() < videFullscreenParams.customVideoView.getHeight();
        if (mIsPortrait)
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    }

    @Override
    public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
        CustomMediaPlayer.getInstance().changeSurface(new Surface(surface));
        CustomMediaPlayer.getInstance().prepareController(container);
        CustomMediaPlayer.getInstance().setControllerTouchView(mFullScreenTextureView);
        CustomMediaPlayer.getInstance().start();
    }

    @Override
    public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
    }

    @Override
    public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
        return false;
    }

    @Override
    public void onSurfaceTextureUpdated(SurfaceTexture surface) {
    }

    public static class VideFullscreenParams {

        private final CustomVideoView customVideoView;

        public VideFullscreenParams(CustomVideoView customVideoView) {
            this.customVideoView = customVideoView;
        }
    }
}

如您所见,我还使用了一个名为 CustomMediaPlayer 的类。这是一个封装 MediaPlayer 并在整个应用程序中管理其生命周期的单例。 如果您在 RecyclerView 或 LinearLayout 中加载多个视频,这是必须的。

【讨论】:

  • 今天我会使用 ExoPlayer(By Google),它比 MediaPlayer 更成熟的 bug
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多