Android 两个surfaceView覆盖不显示,视频小窗被遮挡有声音无画面

17 篇文章 0 订阅

背景:

在如今的社交中,短视频和直播的占比还是比较靠前,我们正常使用的有单窗口短视频和支持小窗的多窗口,多窗口理想的状态是大的窗口在底,小窗口在上面,类似微信视频。

问题:

我们在开发中,按图层布局来安排,经常是把大的视频放在最底部,小的视频窗口放在大窗口上面。这样避免小窗口被大窗口遮挡,但是有些机型和我们想的不一样。

1.我们在处理连麦中,特别是视频连麦或者视频通话,是一个大的窗口和一个小的窗口,在调试过程中,发现小窗口有声音但是无画面或者不显示,只有大窗口surfaceView正常显示,是因为部分设备的surfaceView的大窗口把小窗口遮挡住了。

原因:

是因为surfaceView是独立的window窗口,即使你在layout中设置好显示的层级关系,但是surfaceView不受Activity的窗口控制,所以在这种情况,在显示的时候要需要我们代码设置,指定哪个优先在上层。

private void initSetSurFaceViewHolder(SurfaceView surfaceView) {
    SurfaceHolder holder = surfaceView.getHolder();
    if (holder == null)
        return;
    holder.setKeepScreenOn(true);
    holder.setFormat(PixelFormat.TRANSPARENT);
    surfaceView.setZOrderOnTop(true);
    surfaceView.setZOrderMediaOverlay(true);

}

SurfaceView提供了图层管理,可以将自己所在的系统窗口提到top。这样手动处理完,我们就可以

控制小窗一直浮在大的窗口上方。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要在AndroidSurfaceView显示MJPEG视频流解码,你可以按照以下步骤进行操作: 1. 首先,在你的Android项目中添加必要的依赖项,如OpenCV或其他MJPEG解码库。 2. 创建一个自定义的SurfaceView类,并在其中实现SurfaceHolder.Callback接口。这将允许你监听SurfaceView的生命周期事件。 ```java public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback { private MJPEGDecoder mjpegDecoder; public MySurfaceView(Context context) { super(context); getHolder().addCallback(this); } @Override public void surfaceCreated(SurfaceHolder holder) { // 在Surface创建时初始化解码器 mjpegDecoder = new MJPEGDecoder(holder.getSurface()); mjpegDecoder.startDecoding(); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { // 在Surface尺寸发生变化时更新解码器 mjpegDecoder.updateSurface(holder.getSurface()); } @Override public void surfaceDestroyed(SurfaceHolder holder) { // 在Surface销毁时停止解码器 mjpegDecoder.stopDecoding(); } } ``` 3. 创建一个MJPEGDecoder类,该类负责接收MJPEG视频流数据并进行解码。你可以使用OpenCV或其他MJPEG解码库来实现这个类。 ```java public class MJPEGDecoder { private Surface surface; private boolean isDecoding; public MJPEGDecoder(Surface surface) { this.surface = surface; isDecoding = true; } public void startDecoding() { // 开始解码线程 new Thread(new Runnable() { @Override public void run() { while (isDecoding) { // 从MJPEG视频流中获取数据并解码 byte[] frameData = getFrameDataFromStream(); // 使用解码库进行解码 Mat frame = decodeMJPEG(frameData); // 将解码后的帧绘制到Surface上 drawFrameToSurface(frame); } } }).start(); } public void updateSurface(Surface surface) { this.surface = surface; } public void stopDecoding() { isDecoding = false; } private byte[] getFrameDataFromStream() { // 从网络或其他来源获取MJPEG视频流数据 // 返回帧的字节数组 } private Mat decodeMJPEG(byte[] frameData) { // 使用OpenCV或其他MJPEG解码库解码帧数据 // 返回解码后的帧(Mat对象) } private void drawFrameToSurface(Mat frame) { Canvas canvas = surface.lockCanvas(null); // 在Surface上绘制解码后的帧 // 可以使用Canvas.drawBitmap()等方法 surface.unlockCanvasAndPost(canvas); } } ``` 4. 在你的Activity中使用自定义的SurfaceView显示MJPEG视频流。 ```java public class MainActivity extends AppCompatActivity { private MySurfaceView surfaceView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); surfaceView = findViewById(R.id.surface_view); } } ``` 确保在布局文件中添加一个SurfaceView元素: ```xml <com.example.MySurfaceView android:id="@+id/surface_view" android:layout_width="match_parent" android:layout_height="match_parent" /> ``` 这样,你就可以在AndroidSurfaceView显示解码后的MJPEG视频流了。记得根据你使用的MJPEG解码库进行必要的调整和配置。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值