【问题标题】:Texture View video and Bitmap display纹理视图视频和位图显示
【发布时间】:2015-03-12 11:59:57
【问题描述】:

我有一个显示位图(占位符图像)的 TextureView,当用户加载视频时,textureView 应该显示视频。

我设法在纹理视图中播放视频并在纹理视图中显示位图,但是当按顺序完成时,我只是得到一个黑屏。

在我的 onSurfaceTextureAvailable 方法中,我在表面视图上绘制了一个位图,如下所示:

@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
    Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.ic_add_clip);
    Canvas canvas = lockCanvas();
    canvas.drawBitmap(bm, (width/2)-(bm.getWidth()/2), (height/2)-(bm.getHeight()/2), null);
    unlockCanvasAndPost(canvas);
}

当用户从其图库中选择一个视频时,我将 Uri 加载到媒体播放器中并将表面设置为媒体播放器。但仍显示位图。我试图通过清除画布来删除位图,它确实删除了位图,但纹理视图只是黑色,也不会显示视频。

public void setMediaPlayer(MediaPlayer mediaPlayer) {
    // Canvas canvas = lockCanvas();
    // canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
    // unlockCanvasAndPost(canvas);

    Surface s = new Surface(getSurfaceTexture());
    mMediaPlayer = mediaPlayer;
    mMediaPlayer.setSurface(s);
    mMediaPlayer.setOnPreparedListener(this);
}

有些东西告诉我,我用来显示视频的表面视图位于我在 TextureAvailble 中绘制的位图后面。当我尝试清除画布时,我也会清除媒体播放器想要使用的表面。有什么解决办法吗?

【问题讨论】:

    标签: android android-canvas android-bitmap textureview


    【解决方案1】:

    你的方法行不通。

    Surface 是具有生产者-消费者关系的缓冲区队列。一次只能有一个制作人,而您有两个制作人(Canvas 和 MediaPlayer)。当您致电mMediaPlayer.setSurface() 时,它会附加 MediaPlayer;当您致电 lockCanvas() 时,它会附加 Canvas。您需要先分离一个,然后才能连接另一个。

    (检查您的 logcat 输出 - 那里可能有一些“已连接”的投诉。)

    问题是,虽然您应该能够分离 MediaPlayer,但不能分离 Canvas。根本没有电话可以做到这一点。这是 API 中的一个不幸的工件。 (通过 4.4 "KitKat" 得到确认,我怀疑它已经改变了。)

    你有几个选择:

    1. 改为使用 GLES 绘制位图。您可以在 Grafika 的 PlayMovieSurface activity 中看到一个示例——参见 clearSurface() 方法,它只是清除屏幕。使用 GLES,您可以连接和分离表面。
    2. 将您的位图转换为单帧视频并通过 MediaPlayer 播放。
    3. 在带有 FrameLayout 的视频窗口顶部放置一个 ImageView。播放视频时隐藏 ImageView。

    我应该补充一点,我实际上并没有尝试将 MediaPlayer 从 Surface 中分离出来。较低级别的 MediaCodec 以这种方式工作,如 Grafika 播放器所示,所以我假设 MediaPlayer 也会干净地分离。但是,对于您的用例,#3 可能是最简单的解决方案,并且不需要附加/分离体操。

    【讨论】:

    • 非常感谢 Fadden。我选择了选项 3,因为它是最简单的。选择选项 1 或 2 只会增加更多复杂性。
    【解决方案2】:

    您可以使用opengl es 将位图绘制到显示表面,然后以相同的方式绘制视频帧。我就是这样做的,效果很好。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-09-08
      • 1970-01-01
      • 2015-02-09
      • 2016-07-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多