使用 Qwen 实现实时语音、视频聊天与屏幕共享:原理、接入流程与工程实践

如今的 AI 交互已经不局限于文字问答。用户可以直接开口说话,让 AI 通过摄像头理解眼前的物体,也可以共享屏幕,让 AI 结合正在显示的内容进行解释。

这类应用看起来像"和 AI 打电话",背后却包含音频采集、视频传输、流式播放、视觉理解、语音打断和会话管理等多个环节。

本文围绕两个模型介绍实现思路:

  • qwen-audio-3.0-realtime-plus:实时语音交流。
  • qwen3.8-omni-flash-realtime:结合音频、摄像头和屏幕画面的实时交流。

文章中的代码为通用实现片段,用于说明关键流程,不包含完整的生产级客户端。

文档核对时间:2026 年 10 月。模型权限、地域、音色、接口参数与价格可能调整,实际接入应以官方文档和控制台为准。

一、两个模型分别负责什么?

1. Qwen-Audio:让 AI 能听、能说

qwen-audio-3.0-realtime-plus 面向实时语音交互,支持音频和文本输入,可返回语音与文字,并支持工具调用。官方模型能力说明

传统语音助手常采用三个服务串接:

复制代码
用户说话
   ↓
ASR:声音转文字
   ↓
LLM:理解问题、生成回答
   ↓
TTS:文字转声音

使用实时语音模型后,应用主要面对的是持续交换音频的接口:

复制代码
输入音频流 → 实时语音模型 → 输出音频流

它适合语音问答、口语交流、语音助手等以声音为主要输入的场景。

不过,模型支持实时语音,不代表浏览器自动拥有完整的通话能力。麦克风采集、音频编码、声音播放和打断控制仍然需要应用实现。

2. Qwen-Omni:让 AI 边听边看

qwen3.8-omni-flash-realtime 面向实时音视频交互,支持文本、音频、图像和视频输入,输出文字和语音。官方实时模型说明

它适合以下交互:

  • 用户打开摄像头,询问眼前物体的特征。
  • 用户展示一份纸质资料,让 AI 结合画面解释。
  • 用户演示一个操作,让 AI 根据可见过程交流。
  • 用户共享屏幕,询问页面、图片或图表的内容。

这里的"视频聊天"是指:

用户提供摄像头画面,AI 理解画面并通过声音或文字回答。

它不等于 AI 自动生成一个真人视频,也不意味着应用已经具备数字人形象。

3. 如何选择?

交互需求 模型选择
只需要实时语音交流 qwen-audio-3.0-realtime-plus
需要 AI 理解摄像头画面 qwen3.8-omni-flash-realtime
需要 AI 理解共享屏幕 qwen3.8-omni-flash-realtime
需要精细读取密集文字或细小数字 在实时交流之外,增加高清截图分析流程

对于视觉场景,重点不仅是"支持图片",还包括画面质量、上传时机,以及画面是否与当前问题对应。

二、整体架构怎么设计?

以浏览器和 WebSocket 为例,可以采用下面的架构:

复制代码
浏览器
 ├─ 麦克风采集
 ├─ 摄像头采集
 ├─ 屏幕共享采集
 ├─ 回复音频播放
 └─ 字幕与通话状态
          ⇅
应用实时网关
 ├─ 用户认证
 ├─ 模型鉴权
 ├─ 音视频事件转发
 ├─ 工具调用执行
 └─ 用量与错误记录
          ⇅
Qwen Realtime 服务

这是服务端转发方案,并非唯一接入方式。它的好处是长期 API Key 保留在服务端,权限、工具调用和用量统计也便于集中管理。

浏览器不应该持有可长期使用的供应商密钥。可以让浏览器先向业务服务申请短期连接凭证,再连接实时网关。

摄像头和屏幕共享可以复用视觉处理链路,但需要明确当前发送的是哪个画面源。

三、实时语音如何接入?

1. 建立持久连接

实时交流需要持续上传音频,同时接收 AI 回复,因此可以通过 WebSocket 长连接交换事件。

常见事件包括:

事件 用途
session.update 配置会话参数
input_audio_buffer.append 上传音频片段
response.audio.delta 接收回复音频片段
response.done 一次回复结束

基本流程是:

复制代码
建立连接 → 配置会话 → 发送音频 → 接收并播放回复 → 关闭连接

这些属于实时接口协议,不能直接用普通 Chat Completions 请求代替。Qwen-Audio 接入指南

2. 采集麦克风

浏览器端可以这样获取麦克风:

复制代码
const microphoneStream =
  await navigator.mediaDevices.getUserMedia({
    audio: {
      echoCancellation: true,
      noiseSuppression: true,
      autoGainControl: true
    }
  });

回声消除尤其重要。否则扬声器播放的 AI 回复可能再次被麦克风采集,造成错误打断或自问自答。

采集后,还需要根据模型协议进行编码:

复制代码
麦克风音频
   ↓
AudioWorklet 读取采样
   ↓
重采样、声道处理
   ↓
PCM 编码
   ↓
按协议发送

例如,Qwen-Audio 官方文档中的 PCM 接入规格为:输入 16 kHz、16 位、单声道,输出 24 kHz、16 位、单声道。官方音频格式说明

不同模型应分别核对音频要求,不能把某个模型的采样率配置直接套用到所有模型。

也不能把 MediaRecorder 生成的 WebM/Opus 文件片段直接当作 PCM 上传。

四、实时视频聊天如何实现?

1. 同时获取摄像头和麦克风

实时视频聊天可以通过 getUserMedia() 获取音视频流:

复制代码
// 在用户点击"开始视频聊天"后调用。
const cameraStream =
  await navigator.mediaDevices.getUserMedia({
    video: {
      width: { ideal: 1280 },
      height: { ideal: 720 },
      facingMode: "user"
    },
    audio: {
      echoCancellation: true,
      noiseSuppression: true,
      autoGainControl: true
    }
  });

const preview = document.querySelector("#camera-preview");

preview.srcObject = cameraStream;
preview.muted = true;
preview.playsInline = true;

await preview.play();

这里的 muted 是关闭本地预览的声音,避免用户听到自己的延迟回放,不代表停止向模型发送麦克风音频。

如果希望移动端优先使用后置摄像头,可以把 facingMode 设置为 "environment"。实际设备选择仍应允许用户调整。

2. AI 是如何理解视频的?

视频聊天中,用户的问题和画面需要共同参与理解:

复制代码
用户说:"这个物体是什么?"
              ↓
麦克风音频 + 当前摄像头画面
              ↓
Omni 模型结合声音与视觉内容分析
              ↓
返回文字和语音回答

摄像头权限成功、页面出现预览,只能证明浏览器拿到了画面。

要让 AI 真正理解视频,还必须把画面送到模型。仅在页面播放本地预览,模型是看不到的。

3. WebSocket 与 WebRTC 的视频传输方式不同

两种接入方式需要区分:

接入方式 画面传输方式
WebSocket 从视频中提取图像帧,再发送图像事件
WebRTC 通过视频轨道传输画面

在 WebSocket 路径中,Omni 使用 input_image_buffer.append 接收图像帧;在 WebRTC 路径中,应通过视频轨道发送,不使用这个图像事件。官方音视频输入流程

对于 WebSocket,可以将摄像头视频定时绘制到 Canvas,编码后上传:

复制代码
摄像头 MediaStream
        ↓
video 元素
        ↓
Canvas 提取当前帧
        ↓
JPEG 编码
        ↓
Base64
        ↓
input_image_buffer.append

官方推荐视频输入从每秒一帧开始接入。这个频率适合作为起点,但不是所有任务的最佳值。

如果通过低频抽帧理解快速动作,可能遗漏中间过程。因此不能把"看到了若干帧"理解成"完整观察了每一个动作"。

4. 如何提高摄像头识别效果?

摄像头场景需要关注:

  • 光线是否充足。
  • 目标是否对焦清晰。
  • 物体是否足够大。
  • 关键部分是否被遮挡。
  • 用户是否快速移动摄像头。
  • 画面上传时间是否与提问对应。

如果用户展示的是一页纸,应让文字占据足够大的画面面积。远距离拍摄整张纸,再把视频压缩成小图,细节很容易丢失。

关闭摄像头时,还应停止视频轨道和抽帧任务,不能只隐藏预览组件。

五、屏幕共享与视频聊天有什么区别?

摄像头与屏幕共享的视觉理解链路很接近,主要区别在于图像来源。

项目 摄像头视频 屏幕共享
采集接口 getUserMedia() getDisplayMedia()
内容来源 现实场景、物体、纸质资料 窗口、标签页、桌面
常见问题 光线、对焦、抖动、遮挡 小字体、缩放、滚动、旧画面
视觉输入 摄像头帧 屏幕帧

屏幕共享的浏览器调用示例:

复制代码
// 由用户点击按钮触发。
const screenStream =
  await navigator.mediaDevices.getDisplayMedia({
    video: true,
    audio: false
  });

浏览器会要求用户选择共享内容。应用不能绕过选择过程读取任意窗口;该接口还要求安全上下文及用户操作触发。MDN:getDisplayMedia

如果共享屏幕时仍要与 AI 说话,可以继续使用单独的麦克风流。共享画面的音轨与麦克风音轨不是同一个概念,也不能假定所有浏览器都能采集共享窗口的声音。

六、摄像头与共享屏幕可以共用抽帧代码

对 WebSocket 方案来说,只要 <video> 已经在播放有效画面,就可以复用同一套抽帧逻辑:

复制代码
// video:正在播放摄像头或屏幕流的 HTMLVideoElement。
// sendFrame:应用自己的上传函数。
// 此片段只演示抽帧,不包含完整协议与错误处理。
function startFrameCapture(video, sendFrame) {
  const canvas = document.createElement("canvas");
  const ctx = canvas.getContext("2d");

  let stopped = false;
  let sending = false;

  const timer = setInterval(async () => {
    if (
      stopped ||
      sending ||
      !video.videoWidth ||
      !video.videoHeight
    ) {
      return;
    }

    sending = true;

    try {
      // 示例尺寸,应根据模型限制与识别需求调整。
      const scale = Math.min(1, 1280 / video.videoWidth);

      canvas.width = Math.round(video.videoWidth * scale);
      canvas.height = Math.round(video.videoHeight * scale);

      ctx.drawImage(video, 0, 0, canvas.width, canvas.height);

      const image = canvas
        .toDataURL("image/jpeg", 0.85)
        .split(",")[1];

      if (!stopped) {
        await sendFrame(image);
      }
    } finally {
      sending = false;
    }
  }, 1000);

  return function stopFrameCapture() {
    stopped = true;
    clearInterval(timer);
  };
}

协议适配层发送:

复制代码
upstream.send(JSON.stringify({
  type: "input_image_buffer.append",
  image: base64Image
}));

需要注意发送顺序:官方 WebSocket 流程要求先发送至少一次音频追加事件,再发送图像;画面还要进入正确的对话轮次。不是定时上传图片后,模型就一定会主动分析并持续播报。官方实时接口说明

生产环境还需要补充:

  • 根据连接状态决定是否发送。
  • 处理 WebSocket 缓冲区积压。
  • 丢弃过时帧,避免延迟不断增加。
  • 切换画面源时取消旧采集任务。
  • 用户停止共享时立即停止发送。
  • 对上传大小和格式进行服务端校验。

七、看得到画面,为什么还是可能理解错误?

模型接收到的是经过采集、缩放和编码后的视觉信息。

例如,一张桌面截图中同时包含浏览器工具栏、侧边栏和正文,真正需要分析的文字可能只占很小区域。经过缩放之后,数字、小数点和上下标可能已经无法分辨。

摄像头同样如此:如果纸面反光、文字失焦,即使模型能力很强,也缺少可靠的输入证据。

建议将处理分为两条路径:

复制代码
实时交流路径
连续语音 + 低频画面
→ 保持交流,理解当前场景

精细分析路径
固定高清截图 + 明确分析区域
→ 读取细节,输出可核对的结论

精细分析时,可以保留整体上下文,同时提供局部高清区域。

还应让模型区分:

  1. 实际识别到的内容。
  2. 基于识别内容作出的判断。
  3. 缺失或看不清的信息。

对于不完整的画面,应要求补充条件,而不是猜测被遮挡或未显示的内容。

八、自然打断为什么容易出现"串音"?

AI 的回复通常分块生成、传输和播放。

当用户开始说话时,系统可能仍有:

  • 正在生成的旧回复。
  • 网络中尚未到达的旧音频。
  • 已经解码但尚未播放的音频。
  • 扬声器正在播放的片段。

因此,打断不能只做"停止生成",还需要处理客户端播放状态:

复制代码
用户开始说话
      ↓
停止当前播放
      ↓
清空待播放队列
      ↓
取消仍在生成的旧回复
      ↓
丢弃旧回复迟到的音频

Qwen-Audio 提供 response.cancel 取消当前推理,但应用需要判断是否存在正在进行的响应,不能无条件重复发送取消事件。官方客户端事件说明

实现时可以结合响应 ID 和本地播放代次,避免已经被取消的音频重新进入播放队列。

还要区分两个状态:

  • 模型已经生成结束。
  • 客户端已经播放结束。

收到 response.done,不代表用户已经听完全部声音。

九、字幕为什么应该与音频分开管理?

字幕事件和音频事件的到达时间可能不同。如果简单按照收到事件的先后顺序追加消息,就容易出现顺序错乱。

建议按轮次组织数据:

复制代码
一个用户轮次
 ├─ 用户转写
 └─ AI 响应
     ├─ 回复文字
     ├─ 回复音频
     └─ 完成或打断状态

字幕负责展示,音频队列负责播放。

已经播放模型原生音频时,不应再把同一份字幕送入 TTS 播放,否则可能出现重复声音。

因此,删除字幕组件通常不能修复串音。真正需要检查的是响应归属、播放队列和打断逻辑。

十、语音升级为视频时,如何保持上下文?

如果应用最初使用 Audio 模型进行纯语音交流,用户随后开启摄像头,就需要切换到能够处理视觉输入的模型。

一种可行的设计是:

复制代码
暂停旧连接的输入与播放
        ↓
建立 Omni 会话
        ↓
传入必要的文字上下文
        ↓
开始发送麦克风与画面
        ↓
恢复交流

上下文可以包括近期问题、必要背景和未完成事项,但不应假设两个模型连接会自动共享记忆。

应用应明确显示"正在切换",避免用户以为画面已经送达,而实际上新连接尚未就绪。

如果一开始就使用 Omni,则可以围绕同一个视觉模型会话管理摄像头和共享屏幕。无论采用哪种方案,都应清晰显示 AI 当前正在查看哪个来源。

十一、上线前应该验证什么?

建议分别验证模型能力、媒体链路和交互体验:

验证项 关注点
麦克风输入 设备正确、音量正常、编码符合协议
回复播放 连续、无明显丢帧、无重复播放
摄像头理解 问题与当前画面一致
屏幕理解 文字清晰、范围明确、不使用旧画面
打断 旧语音及时停止,不再续播
画面切换 摄像头与屏幕不串源
网络恢复 不重放旧音频、不重复执行操作
识别质量 用人工标注样例检查,而不只看请求成功
用量记录 分别观察音频、视觉和额外分析请求

成本优化也应结合任务。静态页面反复上传相同画面,未必比按需提交清晰截图更有效;快速变化的场景则需要评估采样频率是否足以保留关键信息。

结语

使用 qwen-audio-3.0-realtime-plus,可以构建以声音为核心的实时交流;使用 qwen3.8-omni-flash-realtime,可以进一步让 AI 理解摄像头和共享屏幕中的内容。

摄像头视频聊天与屏幕共享,虽然采集入口不同,但都需要把视觉信息与当前语音问题正确关联。

实现一个稳定的实时 AI 应用,需要同时做好音频处理、画面采集、协议传输、响应管理和识别验证。模型负责理解与生成,应用则负责让输入可信、输出有序,并让用户清楚知道 AI 此刻听到了什么、看到了什么。

14:32

相关推荐
福芯微电子有限公司nfc1 小时前
国产收音芯片 FSV4755:多波段调谐与高集成设计,赋能多种音频终端
网络协议·网络安全·音视频·信息与通信·信号处理
奈落241 小时前
Anthropic 收购 Vercept:Claude 的“计算机使用”要补感知与交互这一课,团队该盯什么
microsoft·api·agent·ai 编程
x10n91 小时前
微软 VC++ 运行库合集VCRedistPack
开发语言·c++·microsoft·vc++运行库·dll报错
疯狂成瘾者2 小时前
海康威视 WSS 视频取流原理:6014/559 端口、Nginx 代理与 TLS 证书问题
运维·nginx·音视频
企业数字化笔记2 小时前
AI视频怎么做超分辨率增强?逐帧处理、画幅控制与音画验收
网络·人工智能·音视频
编码者卢布2 小时前
【Azure Storage Account】Azure Queue指标中的Transactions 高,真实业务处理的消息就多吗?
microsoft·flask·azure
Liuruping043 小时前
建筑项目 VR 安全体验馆采购,如何评估厂商交付与售后能力?
安全·microsoft·vr
2601_9654542313 小时前
做新闻视频没素材?AI按文稿语义自动配画面的工作流
音视频
一只游鱼13 小时前
MCP \
人工智能·microsoft