MediaController 的默认 SeekBar 不同步

Posted

技术标签:

【中文标题】MediaController 的默认 SeekBar 不同步【英文标题】:MediaController's default SeekBar not in sync 【发布时间】:2017-04-26 06:45:07 【问题描述】:

我正在添加一个带有 VideoView 和 MediaController 的基本视频播放器。

MediaController 提供的 SeekBar 在视频播放到结束时的 0:02 分钟停止。 我已经在 3 种具有不同视频长度的不同设备上进行了尝试。

如何确保 SeekBar 的进度和时间与视频同步?

以下是相关代码:

VideoPlayerDialog.java

videoView.setVisibility(View.VISIBLE);
MediaController mediaController = new MediaController(getContext());

FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT);
lp.gravity = Gravity.BOTTOM;
mediaController.setLayoutParams(lp);

((ViewGroup) mediaController.getParent()).removeView(mediaController);
((FrameLayout) findViewById(R.id.videoViewWrapper)).addView(mediaController);

videoView.setMediaController(mediaController);
videoView.setVideoURI(imageUri);
videoView.requestFocus();

dialog_image_preview.xml

    <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_
    android:layout_
    android:background="@color/black87">

    <uk.co.senab.photoview.PhotoView
        android:id="@+id/photo_view"
        android:layout_
        android:layout_
        android:layout_centerInParent="true" />

    <FrameLayout
        android:layout_
        android:layout_
        android:id="@+id/videoViewWrapper"
        android:layout_centerInParent="true"
        android:layout_margin="30dp">

        <VideoView
            android:id="@+id/videoplayer"
            android:layout_
            android:layout_ />
    </FrameLayout>

    <ImageButton
        android:id="@+id/close"
        android:layout_
        android:layout_
        android:layout_alignParentEnd="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:background="@drawable/circular_button_material"
        android:elevation="10dp"
        android:padding="5dp"
        android:src="@drawable/ic_close" />
</RelativeLayout>

【问题讨论】:

【参考方案1】:

我找到了答案。在您的 MediaController 构造函数上,覆盖它的 hide() void 并在其中使用 this.show() 以便 MediaController 在隐藏时显示。 这样做的原因,是因为 MediaController 默认在 3 秒后自动隐藏自身,即使是 show(0)。所以,如果你强制显示 MediaController,它仍然会在 3 秒后隐藏起来(seekbar 停止同步,播放/暂停按钮不更新)。覆盖 hide() void 以显示 MediaController 可以解决此问题。

您还可以创建一个自定义类,将 MediaPlayer 扩展为 ovverride hide()

示例代码:

final MediaController mediaController =  new MediaController(context)
    @Override
    public void hide() 
        this.show();
    
;

【讨论】:

这看起来是个不错的答案。但是,我找到了另一种使用此代码的方法。无法自己测试答案。如果有人确认,我会将其标记为正确答案。 @HarishVishwakarma - 你的其他方式是什么?您可以随时发表评论。 我测试过它真的有效!!但问题是我在对话框中播放视频,按后退按钮后它会冻结屏幕,如果我删除此行视频对话框关闭得很好,后按也没有问题,但搜索栏在 2 秒后停止 @AnshulKhare 已经有一段时间了,但是您可以尝试创建 MediaController 的子类,添加字段 private bool shouldSync = false;,为 shouldSync 添加 getter 和 setter,然后覆盖 hide 并编写if (shouldSync) show();。现在您可以在对话框打开时执行mMediaCtrl.setShouldSync(true);,在对话框关闭时执行mMediaCtrl.setShouldSync(false);【参考方案2】:

您可以尝试使用

自动将媒体控制器连接到视频视图

MediaController mediaController = new MediaController(this); mediaController.setAnchorView(videoView); videoView.setMediaController(mediaController);

【讨论】:

谢谢,但这不起作用。它只是隐藏了 videoview 下方的播放控件,但搜索栏更新没有任何变化。【参考方案3】:

根据here 的参考,我能够解决搜索栏在 2 秒后停止的问题以及屏幕冻结的后按问题。

我使用 dispatchkeyevent 检测后按并在视频开始后显示媒体控制器。

        videoView.setOnPreparedListener  mp ->

        progressBar.visibility = View.GONE

        mc = object : MediaController(mContext) 

            override fun dispatchKeyEvent(event: KeyEvent): Boolean 

                if (event.keyCode == KeyEvent.KEYCODE_BACK) 
                    super.hide()//Hide mediaController
                    scoreDialog.dismiss()//Close this dialog/activity

                    return true//If press Back button, finish here
                
                //If not Back button, other button work as usual.
                return super.dispatchKeyEvent(event)
            

        
        videoView.setMediaController(mc)
        mc.setAnchorView(videoView)

        (mc.parent as ViewGroup).removeView(mc)

        (scoreDialog.findViewById(R.id.videoViewWrapper) as FrameLayout).addView(mc)
        
        mp.start()
        mc.show(0)
    

【讨论】:

以上是关于MediaController 的默认 SeekBar 不同步的主要内容,如果未能解决你的问题,请参考以下文章

将 MediaController 定位在 VideoView 上

以编程方式更改 MediaController 图标

VideoView - MediaController 未显示

来自 MediaController 的 android ActiveSessions

音频文件不与 mediaController 一起播放?

(Context, Token) 在实例化 MediaController