【问题标题】:Draw overlay (HUD) on Android VideoView?在 Android VideoView 上绘制叠加层(HUD)?
【发布时间】:2023-03-12 11:07:02
【问题描述】:

我有一个绘制 HUD 的自定义视图:

这是我的布局:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout  xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <VideoView
        android:id="@+id/videoView1"
        android:layout_gravity="center"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <com.widgets.HUD
            android:id="@+id/hud"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent" />

</FrameLayout>
public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.hud_fragment, container, false);

    frameLayout = (FrameLayout) view.findViewById(R.id.frameLayout);

    hudWidget = (HUD) view.findViewById(R.id.hudWidget);

    videoView = (VideoView) view.findViewById(R.id.videoView1);
    videoView.setVideoURI(Uri.parse("http://88.150.210.138:5001/spor"));
    videoView.start();

    frameLayout.removeView(hudWidget);
    frameLayout.addView(hudWidget);
    hudWidget.bringToFront();

    return view;
}

视频一开始播放,我就在我的 VideoView 上播放 RTSP 流,它看起来像这样:

如何强制 HUD 在 VideoView 上绘制? HUD extends SurfaceView

项目

  • 我正在尝试添加 VideoView 的项目是DroidPlanner 您可以尝试克隆并查看问题。 (需要手动添加 VideoView,因为它不在 repo 中)。

【问题讨论】:

  • 如果您的小部件扩展了 View,您是否尝试过 view.bringtoFront()。您的布局定义似乎正确。
  • @Slartibartfast 试过了,检查我的更新。还是一样。
  • 我试图重新创建您的问题,但实际上失败了。这是我制作的项目:github.com/andrask/androidhud 它重现了您使用视频视图、按钮和自定义视图创建的相同类型的界面。视频开始时,所有元素都停留在顶部,没有任何反应。唯一的区别是它不使用片段。您是否尝试过使用单个活动或静态链接片段?
  • 你能告诉我结果吗:adb shell dumpsys SurfaceFlinger
  • @allprog 我的 HUD 视图是 SurfaceView 也许是这样?您需要将com1 的文件夹名称更改为com,这会导致Windows 上的Git 出现路径问题。

标签: android video-streaming android-videoview rtsp ondraw


【解决方案1】:

我找到了您问题的答案:VideoView on top of SurfaceView SurfaceView 和 VideoView 都是表面视图,在旧版本的 Android 中不支持重叠这些视图,但从 2.0 开始可用。

你需要做什么:

  1. 将像素格式设置为透明,以便让视频在界面中闪耀

hudWidget.getHolder().setFormat(PixelFormat.TRANSPARENT);

  1. 将 HUD 表面设置为媒体叠加层。

hudWidget.setZOrderMediaOverlay(true);

  1. 创建一个新表面并将其设置为播放视频的 MediaPlayer 的显示器。

有一个拉取请求,您可以在其中尝试这些。 https://github.com/arthurbenemann/droidplanner/pull/247

带来解决方案的线程:https://groups.google.com/forum/?fromgroups#!msg/android-developers/nDNQcceRnYA/ps9wTBfXIyEJ

【讨论】:

  • 你的答案看起来不错!我对其进行了测试,但我遇到了问题,流在 1-3 帧后卡住了……你也有这个问题吗?还是它一直在你身边玩?
  • 是的,它有时也发生在我身上,因为主线程被阻塞太久。我很高兴它现在可以工作了。
【解决方案2】:

来自FrameLayout 上的文档:Link

子视图绘制在堆栈中,最近添加的子视图 在上面

id 添加到布局文件中的FrameLayout。在你的onCreate(Bundle),你会有类似的东西:

// find your framelayout
frameLayout = (FrameLayout) findViewById(....);

videoView = (VideoView) findViewById(R.id.videoView1);

hudView = (com.widgets.HUD) findViewById(R.id.hud);

视频开始后,执行以下操作:

frameLayout.removeView(hudView);

frameLayout.addView(hudView);

【讨论】:

  • 还是什么都没有...我更新了原始项目的链接。
【解决方案3】:

每隔 50 或 100 毫秒创建一个 Handler invalidate 你的 hudView

像这样:

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.hud_fragment, container, false);

        frameLayout = (FrameLayout) view.findViewById(R.id.frameLayout);

        hudWidget = (HUD) view.findViewById(R.id.hudWidget);

        videoView = (VideoView) view.findViewById(R.id.videoView1);
        videoView.setVideoURI(Uri.parse("http://88.150.210.138:5001/spor"));
        videoView.start();

        frameLayout.removeView(hudWidget);
        frameLayout.addView(hudWidget);
        hudWidget.bringToFront();

        //The Handler which invalidate your (hudWidget) every 50 milliseconds 

        new Handler() {
            public void handleMessage(android.os.Message msg) {
                super.handleMessage(msg);
                hudWidget.invalidate();
                sendEmptyMessageDelayed(0, 50);

            };
        }.sendEmptyMessage(0);

        return view;
    }

【讨论】:

  • 还是什么都没有...我更新了原始项目的链接。
【解决方案4】:

测试 FrameLayout 以替换 RelativeLayout。

也许效果不错。

【讨论】:

    【解决方案5】:

    扩展VideoView 并在其构造函数中调用setWillNotDraw(false)。这样你就可以在onDraw(Canvas)中画图了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-04-10
      • 1970-01-01
      • 2013-11-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-25
      相关资源
      最近更新 更多