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

Zoom Probe SDK音视频诊断功能异常排查求助

Zoom Probe SDK音视频诊断功能异常排查求助

大家好,我最近在开发一款基于Zoom Video SDK的应用,需要实现带虚拟背景和降噪的录屏功能,同时还要做一个用户预览模块——让用户能选择麦克风、摄像头设备,并且用Zoom Probe SDK检测网络、麦克风和摄像头的状态。我按照官方文档的示例写了React组件,但在音视频诊断部分遇到了问题,只有网络诊断能正常工作,想请教下大家有没有类似的经验,或者我哪里写得不对?

音频诊断的问题

我试了几种调用diagnoseAudio的方式,结果都不正常:

  • 以下两种写法完全没有任何反应,既不返回结果也不报错:
    const audioResult = prober.diagnoseAudio(audioInputConstraint, audioOutputConstraint, 5000)
    
    或者
    const audioResult = prober.diagnoseAudio(audioInputConstraint, audioOutputConstraint, 5000, '')
    
  • 按照文档说明「如果第三个参数设为0,会默认使用5000ms超时」,我试了下面两种写法,结果直接报错:
    const audioResult = prober.diagnoseAudio(audioInputConstraint, audioOutputConstraint, 0, '')
    
    或者
    const audioResult = prober.diagnoseAudio(audioInputConstraint, audioOutputConstraint, 0)
    
    错误信息(我用了craco配置跨域头):
    blob:http://localhost:3001/95af1d79-d503-432d-a933-f563ac65eec9:1 GET blob:http://localhost:3001/95af1d79-d503-432d-a933-f563ac65eec9 net::ERR_REQUEST_RANGE_NOT_SATISFIABLE
    localhost/:1 Uncaught (in promise) NotSupportedError: Failed to load because no supported source was found.
    

视频诊断的问题

视频诊断能正常唤起摄像头,但完全不会返回诊断结果——只有当我调用prober.stopToDiagnoseVideo时才会返回true,而且初始的diagnosticResult自始至终没有任何更新。我的视频诊断代码逻辑如下:

const previewVideo = document.getElementById('videout');
const videoConstraints = {
  video: { width: previewVideo.width, height: previewVideo.height, deviceId: videoInputId || 'default' },
};
const videoOptions = {
  rendererType: 1, // 1 = video tag
  target: previewVideo,
};
let diagnosticResult = await prober.diagnoseVideo(videoConstraints, videoOptions);
console.log(diagnosticResult);
setTimeout(() => {
  let finalresult = prober.stopToDiagnoseVideo(diagnosticResult.stream);
  console.log(finalresult);
  console.log(diagnosticResult);
}, 3000)

我的完整React组件代码

import React, { useEffect, useMemo, useState } from 'react';
import { Prober } from '@zoom/probesdk';

const DiagnosticsPanel = () => {
  const [devices, setDevices] = useState([]);
  const [audioInputId, setAudioInputId] = useState('');
  const [audioOutputId, setAudioOutputId] = useState('');
  const [videoInputId, setVideoInputId] = useState('');
  const [results] = useState({});

  const prober = useMemo(() => new Prober(), []);

  useEffect(() => {
    const init = async () => {
      await prober.requestMediaDevicePermission({ audio: true, video: true });
      const { devices } = await prober.requestMediaDevices();
      setDevices(devices);
    };
    init();
  }, [prober]);

  const runDiagnostics = async () => {
    const audioInputConstraint = {
      audio: { deviceId: audioInputId || 'default' },
      video: false,
    };
    const audioOutputConstraint = {
      audio: { deviceId: audioOutputId || 'default' },
      video: false,
    };

    try {
      const audioResult = prober.diagnoseAudio(audioInputConstraint, audioOutputConstraint, 0)
      console.log('Audio diagnostics:', audioResult);
      results.audio = audioResult;
    } catch (err) {
      console.error('Audio diagnostics failed:', err);
    }

    const previewVideo = document.getElementById('videout');
    const videoConstraints = {
      video: { width: previewVideo.width, height: previewVideo.height, deviceId: videoInputId || 'default' },
    };
    const videoOptions = {
      rendererType: 1, // 1 = video tag
      target: previewVideo,
    };
    let diagnosticResult = await prober.diagnoseVideo(videoConstraints, videoOptions);
    console.log(diagnosticResult);
    setTimeout(() => {
      let finalresult = prober.stopToDiagnoseVideo(diagnosticResult.stream);
      console.log(finalresult);
      console.log(diagnosticResult);
    }, 3000)

    // This works fine!
    const jsUrl = '/prober.js';
    const wasmUrl = '/prober.wasm';
    const config = { probeDuration: 120000, connectTimeout: 20000, domain: 'zoom.us' };
    prober.startToDiagnose(jsUrl, wasmUrl, config, undefined).then(report => {
      console.log('Final report:', report);
    }).catch(err => {
      console.error('Network diagnostics failed:', err);
    });
  };

  const renderDeviceOptions = (kind) => devices
    .filter((d) => d.kind === kind)
    .map((d) => (
      <option key={d.deviceId} value={d.deviceId}>
        {d.label || d.deviceId}
      </option>
    ));

  return (
    <div style={{ padding: '1rem', fontFamily: 'Arial' }}>
      <h2>Zoom Diagnostics</h2>
      <label>Microphone:</label>
      <select onChange={(e) => setAudioInputId(e.target.value)} value={audioInputId}>
        <option value="">Select a mic</option>
        {renderDeviceOptions('audioinput')}
      </select>
      <label>Speaker:</label>
      <select onChange={(e) => setAudioOutputId(e.target.value)} value={audioOutputId}>
        <option value="">Select a speaker</option>
        {renderDeviceOptions('audiooutput')}
      </select>
      <label>Camera:</label>
      <select onChange={(e) => setVideoInputId(e.target.value)} value={videoInputId}>
        <option value="">Select a camera</option>
        {renderDeviceOptions('videoinput')}
      </select>
      <video id="videout" width="640" height="480" muted autoPlay playsInline></video>
      <button onClick={runDiagnostics}>Run Diagnostics</button>
    </div>
  );
};

export default DiagnosticsPanel;

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.08 14:37:59