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

Unity中用UDesktopDuplication向Agora推送视频帧遇灰屏问题求助

Agora Windows屏幕共享灰屏问题排查与解决

你遇到的灰屏问题,核心原因大概率是BGRA转RGBA的格式转换没真正生效,再加上可能的纹理数据读取、参数配置问题,导致Agora无法正确解析视频帧。下面是具体排查点和解决办法:

一、格式转换的核心问题

你只是修改了externalVideoFrame.format为RGBA,但实际传入的_shareData还是BGRA格式的字节数据,Agora收到后按RGBA解析自然会显示异常。必须手动交换每个像素的B和R通道:

// 在获取nativeByteArray之后,添加BGRA转RGBA的逻辑
for (int i = 0; i < nativeByteArray.Length; i += 4)
{
    // 交换B和R通道:BGRA -> RGBA
    byte temp = nativeByteArray[i];
    nativeByteArray[i] = nativeByteArray[i + 2];
    nativeByteArray[i + 2] = temp;
}
nativeByteArray.CopyTo(_shareData);

二、纹理数据的有效性检查

UDesktopDuplication插件返回的texture可能未就绪,或者格式不是预期的BGRA32,先加日志确认:

Debug.Log("UDD Texture Format: " + _texture.format);
// 确保纹理格式是BGRA32,否则转换逻辑不生效
if (_texture.format != TextureFormat.BGRA32)
{
    Debug.LogError("Unsupported texture format, expected BGRA32");
    yield break;
}

三、Stride参数的正确设置

Stride(步长)应该是一行像素的总字节数,不是宽度。对于BGRA/RGBA格式,Stride = 宽度 × 4:

externalVideoFrame.stride = _texture.width * 4;

之前直接用_texture.width会导致Agora读取数据时错位,也是灰屏的常见原因。

四、时间戳与旋转参数的修正

  • 时间戳建议用Unity的Time.realtimeSinceStartup,避免DateTime.Now.Ticks的精度问题:
    externalVideoFrame.timestamp = (long)(Time.realtimeSinceStartup * 1000000); // 微秒级
    
  • 旋转180度如果不是必要的,先注释掉,排除旋转导致的显示异常。

五、视频轨道的初始化验证

确保_videoTrack是正确创建的自定义采集轨道,初始化代码要类似:

_videoTrack = rtc.CreateCustomVideoTrack(true);

修改后的完整代码

private IEnumerator ShareScreen()
{
    yield return new WaitForEndOfFrame();
    IRtcEngine rtc = Agora.Rtc.RtcEngine.Instance;
    if (rtc == null) yield break;

#if UNITY_EDITOR_OSX
    _texture.ReadPixels(_rect, 0, 0);
    _texture.Apply();
#else
    // 从UDD插件获取纹理
    _texture = Manager.GetMonitor(displayIndex).texture; 
#endif

    // 检查纹理有效性和格式
    if (_texture == null)
    {
        Debug.LogError("UDD returned null texture");
        yield break;
    }
    Debug.Log("UDD Texture Format: " + _texture.format);
    if (_texture.format != TextureFormat.BGRA32)
    {
        Debug.LogError("Unsupported texture format, expected BGRA32");
        yield break;
    }

#if UNITY_2018_1_OR_NEWER
    NativeArray<byte> nativeByteArray = _texture.GetRawTextureData<byte>();
    if (_shareData == null || _shareData.Length != nativeByteArray.Length)
    {
        _shareData = new byte[nativeByteArray.Length];
    }

    // BGRA转RGBA:交换B和R通道
    for (int i = 0; i < nativeByteArray.Length; i += 4)
    {
        byte temp = nativeByteArray[i];
        nativeByteArray[i] = nativeByteArray[i + 2];
        nativeByteArray[i + 2] = temp;
    }
    nativeByteArray.CopyTo(_shareData);
#else
    _shareData = _texture.GetRawTextureData();
    // 旧版本Unity需要手动处理转换,逻辑同上
#endif

    ExternalVideoFrame externalVideoFrame = new ExternalVideoFrame();
    externalVideoFrame.type = VIDEO_BUFFER_TYPE.VIDEO_BUFFER_RAW_DATA;
    externalVideoFrame.format = VIDEO_PIXEL_FORMAT.VIDEO_PIXEL_RGBA; // 现在格式匹配了
    externalVideoFrame.buffer = _shareData;
#if UNITY_EDITOR_OSX
    externalVideoFrame.stride = (int)_rect.width * 4;
    externalVideoFrame.height = (int)_rect.height;
#else
    externalVideoFrame.stride = _texture.width * 4;
    externalVideoFrame.height = _texture.height;
#endif
    // 先注释裁剪,排除裁剪导致的问题
    // externalVideoFrame.cropLeft = 10;
    // externalVideoFrame.cropTop = 10;
    // externalVideoFrame.cropRight = 10;
    // externalVideoFrame.cropBottom = 10;
    // externalVideoFrame.rotation = 180; // 先禁用旋转
    externalVideoFrame.timestamp = (long)(Time.realtimeSinceStartup * 1000000); // 微秒级时间戳

    var ret = rtc.PushVideoFrame(externalVideoFrame, _videoTrack);
    if (pushVideoFrame_Result != ret)
    {
        pushVideoFrame_Result = ret;
        Debug.Log($"PushVideoFrame ret = {pushVideoFrame_Result} time: {System.DateTime.Now.Millisecond}");
    }
}

额外排查点

  • 检查PushVideoFrame的返回值,如果不是0(成功),对照Agora错误码文档排查具体问题;
  • 确保UDD插件的权限正常,Windows下需要屏幕录制权限;
  • 在Web端测试时,用Agora官方的Web Demo验证,排除Web端自身的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 22:49:53