【问题标题】:Vertical Stripes on Screen with VideoView on top of SurfaceView屏幕上的垂直条纹,SurfaceView 上的 VideoView
【发布时间】:2015-10-17 00:32:03
【问题描述】:

我正在编写一个显示过场动画的应用程序。目前,它的工作方式是(因为表面视图/视频视图通常不能相互叠加)我在应用程序运行时从布局中删除了 VideoView。然后,当我想显示一个过场动画时,我将 VideoView 添加回布局中,一旦动画准备好播放,删除 SurfaceView(如果操作正确,在视频开始之前没有“黑色闪光”。这个工作成功。)但是,当视频结束时,我可以做以下两件事之一:

  • 删除 VideoView,然后将 SurfaceView 添加回布局。这会导致在重新添加 SurfaceView 时屏幕上出现黑色闪烁。
  • 重新添加 SurfaceView,然后在 SurfaceView 准备好呈现后移除 VideoView。

同样,我选择了第二个选项来消除屏幕上的黑色闪光。但是,这会导致不同的问题。出于某种原因,在 VideoView 开始播放后,如果在其画布上添加 SurfaceView 的顶部,则会出现从上到下沿屏幕向下延伸的深色垂直条纹。

移除 VideoView 后,条纹就会消失。然而,可以理解的是,在 SurfaceView 被添加回来和 VideoView 被从布局中删除之间大约有四分之一秒左右的延迟时间。在此期间,条纹清晰可见。

有没有办法解决这个问题?

请注意,我正在使用 Vitamio 渲染 AVI 视频。

【问题讨论】:

    标签: android surfaceview android-videoview vitamio


    【解决方案1】:

    如文档中所述,VideoView 是 SurfaceView 的子类。如果你尝试让两个 SurfaceView 同时占据同一个空间,结果有些难以预料。 (好吧,我预测它们会很糟糕。)

    如果你想让它们重叠,你需要把它们放在不同的 Z 深度。例如,您可以在 SurfaceView 上使用 setZOrderMediaOverlay() 和 Canvas 将其置于 VideoView 之上,但仍位于 View UI 层之下。

    您确实需要确保基于 Canvas 的 SurfaceView 通常是透明的。有关三个重叠 SurfaceView 的示例,请参阅 Grafika 的“multi-surface test”。 drawCircleSurface() 使用 Canvas 渲染。

    更多详情请见graphics architecture document

    【讨论】:

    • 即使使用 setZOrderMediaOverlay(),垂直条纹仍然存在。还尝试了 setZOrderOnTop(true)。这些都没有占上风。正如我所说,它可能只是某种 Vitamio 错误。我找到的唯一解决方案是停止播放,这会立即删除条纹。但是,当使用这两种方法时,它可以完美地工作。谢谢。
    • 很难理解这怎么可能,因为单独的 Surface 彼此之间的交互为零。它们由系统合成器 SurfaceFlinger 组合,而不是应用程序;他们没有理由相互了解或有任何相互干扰的能力(除非设备特定的驱动程序错误)。请注意,Z-order 调用必须在onCreate() 中进行;一旦创建了 Surface,它们将不起作用。
    • 如果它是特定于设备的硬件编写器错误,探测问题的一种方法是使用screenrecord 命令在出现故障时捕获视频。如果录制的视频中没有出现故障,则很有可能是设备驱动程序问题。 (您也可以使用此答案中的 adb 命令暂时禁用 HWC:stackoverflow.com/questions/30328373/…)我不知道您对进一步追求这一点有多感兴趣,因为您似乎有一个解决方法。
    【解决方案2】:

    经过一番思考和反复试验,我找到了解决方案。

    这似乎是一个 android 或 Vitamio 错误。

    如果在当前布局中还存在VideoView 时绘制了SurfaceView's canvas,并且在没有随后调用stopPlayback() 的情况下调用了VideoView's start() 方法,则通常会出现图形错误.

    即使VideoView 已播放结束,仍必须调用stopPlayback() 以避免这种图形错误。

    编辑:请注意,即使调用setZOrderMediaOverlay()setZOrderOnTop() 也可能发生这种情况。但是,如上所述,调用 stopPlayback() 似乎可以解决问题。

    【讨论】:

      猜你喜欢
      • 2011-07-22
      • 1970-01-01
      • 2020-12-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多