You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android端推流至Ant Media Server出现绿屏问题求助

解决Android隐藏摄像头推流至Ant Media Server的绿屏问题

我之前也碰到过类似的隐藏摄像头推流绿屏的坑,结合你给出的代码细节,大概率是NV21数据处理或格式匹配环节出了问题,咱们一步步来排查解决:

1. 先砍掉多余的中间转换环节

你当前把NV21数据转成YuvImage再提取YuvData,接着又转成IntBuffer塞到GL缓冲区里,这中间每一步都可能引入数据错位。其实Yasea的编码器本身是支持直接接收NV21原始数据的,完全可以跳过这些冗余步骤,直接在onPreviewFrame里把摄像头输出的原始数据传给回调:

@Override
public void onPreviewFrame(byte[] data, Camera camera) {
    Camera.Size previewSize = camera.getParameters().getPreviewSize();
    // 直接传摄像头输出的原始NV21数据,跳过YuvImage和GLBuffer转换
    mPrevCb.onGetNV21Frame(data, previewSize.width, previewSize.height);
}

很多时候绿屏就是中间转换时颜色空间或数据格式被破坏导致的,先简化流程试试。

2. 确认摄像头预览格式与编码器输入格式匹配

一定要确保摄像头输出的格式确实是NV21,有些设备默认可能输出YV12(和NV21的U/V分量顺序相反),这会直接导致编码器解析出异常颜色:

// 在初始化摄像头时检查并强制设置预览格式
Camera.Parameters params = camera.getParameters();
// 先确认设备是否支持NV21
List<Integer> supportedFormats = params.getSupportedPreviewFormats();
if (supportedFormats.contains(ImageFormat.NV21)) {
    params.setPreviewFormat(ImageFormat.NV21);
}
camera.setParameters(params);

同时检查Yasea编码器的配置,确保它的视频输入格式也是NV21,避免格式不兼容。

3. 检查分辨率是否完全匹配

如果编码器期望的分辨率和摄像头实际输出的预览分辨率不一致,也会出现绿屏、拉伸或花屏的情况。初始化编码器时,强制绑定摄像头的预览尺寸:

Camera.Size previewSize = camera.getParameters().getPreviewSize();
// 设置编码器的视频尺寸与摄像头预览尺寸一致
mEncoder.setVideoSize(previewSize.width, previewSize.height);

4. 手动计算YuvImage的Strides参数(如果必须用YuvImage的话)

如果你确实需要保留YuvImage的处理逻辑,千万不要给strides参数传null。很多摄像头的实际数据 stride 会对齐到16字节(比如宽度是1080的话,stride可能是1088),默认按宽度计算会导致数据错位:

int previewWidth = camera.getParameters().getPreviewSize().width;
int previewHeight = camera.getParameters().getPreviewSize().height;
// NV21的strides规则:Y分量stride为宽度,U/V分量各为宽度的一半(或实际对齐后的值)
int[] strides = new int[]{previewWidth, previewWidth / 2, previewWidth / 2};
YuvImage yuv = new YuvImage(data, ImageFormat.NV21, previewWidth, previewHeight, strides);

5. 测试U/V分量顺序是否颠倒

如果以上步骤都没用,可能是你的设备输出的是YV12格式(和NV21的U/V顺序相反),可以尝试交换U/V分量再传给编码器测试:

public void onGetNV21Frame(byte[] data, int width, int height) {
    calcSamplingFps();
    if (!sendAudioOnly) {
        int ySize = width * height;
        byte[] convertedData = new byte[data.length];
        // 复制Y分量
        System.arraycopy(data, 0, convertedData, 0, ySize);
        // 交换U和V分量(把NV21转成YV12)
        System.arraycopy(data, ySize + ySize/4, convertedData, ySize, ySize/4);
        System.arraycopy(data, ySize, convertedData, ySize + ySize/4, ySize/4);
        mEncoder.onGetYuvNV21Frame(convertedData, width, height, new Rect(0, 0, width, height));
    }
}

如果这样绿屏消失了,说明设备实际输出的是YV12,需要调整摄像头预览格式或编码器的输入格式。

内容的提问来源于stack exchange,提问作者Mir Saman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 07:47:06