gods-eye-view 语音验收 WAV 夹具:从假麦克风到 AI 控制真实广播电台的端到端链路
gods-eye-view 语音验收 WAV 夹具从假麦克风到 AI 控制真实广播电台的端到端链路【免费下载链接】gods-eye-viewA spy satellite simulator in your browser, except the data is real. Live open source spatial intelligence on a photorealistic 3D globe.项目地址: https://gitcode.com/GitHub_Trending/go/gods-eye-view导读本篇围绕 scripts/fixtures/voice/README.md 展开剖析 gods-eye-view 仓库中凭据化 AI 语音 → 控制真实网络广播Radio这条端到端验收链路的实现。你将掌握这个所有者生成owner-generated的假麦克风 WAV 夹具为什么存在、它的内嵌元数据与 SHA-256 校验如何充当溯源记录provenance record、qa-voice-wav.mjs是如何用 Puppeteer 把这段音频喂给 Chromium 完成语音命令以及语音会话与 Radio 播放器之间扬声器交接speaker handoff的源码级机制。读完你可以复现两种验收模式点击开启与按住 Space 的 push-to-talk并理解验收通过所依赖的六项状态断言。一、夹具定位一段会说话的WAV 文件scripts/fixtures/voice/目录下只放了两样东西README.md与full-globe-turn-on-radio.wav。前者是本文对应的说明文档后者是一段所有者生成的、用于凭据化 AI 到 Radio 验收测试的假麦克风夹具fake-microphone fixture。之所以叫假麦克风是因为它并不通过真实录音设备录入而是由所有者使用某种语音合成方式生成随后通过 Chromium 的--use-file-for-fake-audio-capture启动参数被浏览器当作麦克风捕获到的音频流来消费。这样验收测试可以在无硬件、无人工发声的条件下完整走一遍真实的语音识别、语义解析、工具调用与音频输出链路从而获得可重复、可审计的确定性结果。夹具文件名full-globe-turn-on-radio本身就是验收场景的浓缩描述语音命令要求相机缩放到全球全貌full globe视角同时执行打开广播turn on the radio。溯源记录WAV 元数据即身份证README 明确指出该 WAV 文件内嵌的元数据就是它的溯源记录记录了生成器generator使用的模型model语音voice念出的文本spoken text使用条款usage terms音频设置audio settings查看方式ffprobe -show_entries format_tags -of json scripts/fixtures/voice/full-globe-turn-on-radio.wav这条命令以 JSON 形式导出 WAV 的format_tags即元数据标签。它把这段音频是谁、用什么模型、哪套语音、照着什么文本生成的固化在文件本身而非依赖仓库外部的说明因此拷贝、迁移、CI 复用都不会丢失来源信息。从代码侧看这个溯源思想同样渗透到校验环节scripts/qa-voice-wav.mjs中硬编码了预期哈希b57af70db1922b72fec2c6c58348ccd3309e10aa1e8edec2890277dff26cc7bb并在启动浏览器前用node:crypto的createHash(sha256)重新计算夹具哈希做比对const expectedFixtureSha256 b57af70db1922b72fec2c6c58348ccd3309e10aa1e8edec2890277dff26cc7bb; const fixtureSha256 createHash(sha256).update(fs.readFileSync(wavPath)).digest(hex); if (fixtureSha256 ! expectedFixtureSha256) { console.error(Unexpected WAV fixture SHA-256: ${fixtureSha256}); process.exit(2); }出处见 scripts/qa-voice-wav.mjs。任何对夹具的篡改或替换都会让验收脚本以退出码 2 拒绝执行——这是凭据化credentialed一词的技术含义不校验来源的音频不允许参与验收。二、运行方式两种验收模式与一条命令README 给出的运行命令node scripts/qa-voice-wav.mjs http://localhost:4189而仓库内的 docs/VOICE-OWNERSHIP.md 补充了针对本地开发服务器的推荐用法默认端口 4173见 scripts/dev-secure.shnode scripts/qa-voice-wav.mjs http://localhost:4173 node scripts/qa-voice-wav.mjs http://localhost:4173 --push-to-talk两条命令对应qa-voice-wav.mjs支持的两种验收模式见 scripts/qa-voice-wav.mjs模式命令交互方式点击模式默认node scripts/qa-voice-wav.mjs URL脚本直接点击页面上的#gev-voice-button开启语音推按说话模式node scripts/qa-voice-wav.mjs URL --push-to-talk脚本聚焦 3D 画布并按住Space模拟真实的 push-to-talk 手势脚本还会自动向目标 URL 追加welcome0查询参数跳过首次运行时的引导焦点变化避免其干扰语音/键盘验收见 scripts/qa-voice-wav.mjs。可选的第二个位置参数qa-voice-wav.mjs还接受第二个位置参数作为自定义 WAV 路径node scripts/qa-voice-wav.mjs http://localhost:4189 /path/to/other.wav未提供时默认使用仓库内的scripts/fixtures/voice/full-globe-turn-on-radio.wav见 scripts/qa-voice-wav.mjs。注意换用自定义文件后若其 SHA-256 与期望值不一致脚本仍会以退出码 2 拒绝所以自定义夹具同样必须通过哈希校验。三、Puppeteer 如何假装麦克风qa-voice-wav.mjs的核心手法是用 Puppeteer 启动一个配置好假媒体设备的 Chromium 实例关键启动参数如下见 scripts/qa-voice-wav.mjsargs: [ --no-sandbox, --disable-setuid-sandbox, --disable-dev-shm-usage, --disable-background-timer-throttling, --disable-renderer-backgrounding, --use-fake-device-for-media-stream, --use-file-for-fake-audio-capture${wavPath}%noloop, --autoplay-policyno-user-gesture-required, --window-size1440,900, ],逐一说明各参数的作用--use-fake-device-for-media-stream让 Chromium 使用虚拟媒体设备而非真实摄像头/麦克风--use-file-for-fake-audio-capturepath%noloop把指定 WAV 文件作为假麦克风的音频源%noloop表示只播放一遍、不循环。README 与脚本注释均注明这段哈希钉死的夹具长约 9.2 秒会在麦克风获取mic acquisition时播放一次见 scripts/qa-voice-wav.mjs--autoplay-policyno-user-gesture-required免除自动播放策略对语音输出AI 播报的限制--disable-background-timer-throttling、--disable-renderer-backgrounding防止后台标签页的定时器/渲染节流影响 75 秒验收窗口内的状态轮询--window-size1440,900与后续的page.setViewport({ width: 1440, height: 900, deviceScaleFactor: 1 })固定视口保证截图/取景一致性。除了启动参数脚本还通过context.overridePermissions(appOrigin, [microphone])预授权麦克风权限从权限模型上消除弹窗见 scripts/qa-voice-wav.mjs。也就是说这段 WAV 在浏览器眼里就是麦克风实时拾音语音识别链路实时 API 会话、语音转文本、意图解析对它一视同仁。四、验收流程从就绪探针到六项状态断言就绪条件脚本打开页面后会等待三个条件同时成立见 scripts/qa-voice-wav.mjs全局桥对象window.__godsEyeView.voiceCommands已初始化页面存在#gev-voice-button语音开关按钮加载屏#loading-screen已隐藏。window.__godsEyeView是仓库暴露的调试/桥接句柄在 src/app/tools.js 中由主流程注入 viewer、dataManager、sceneDirector、annotations 等核心对象initGevVoiceCommands随后把语音命令挂在同一个句柄上见 src/app/tools.js。状态采样与退出条件脚本通过page.evaluate周期性每 500ms读取一组可观测状态见 scripts/qa-voice-wav.mjsvoiceStatus语音控制器的当前状态voiceDetail#gev-voice-detail元素文本cameraHeightM相机椭球面高度米radioEnabled、radioAudioState、radioStationRadio 图层模块经getUIState()暴露的启用状态、音频状态与当前电台名radioVoiceDucked语音会话持麦时是否对 Radio 做了闪避ducking。从 src/layers/radio/playback.js 可以看到 ducking 的物理实现audio.volume layerState._voiceDucked ? 0 : layerState._userVolume——语音持有扬声器期间Radio 音量被强制压到 0避免AI 说话 电台广播同时发声。脚本认为验收成功、提前退出的条件见 scripts/qa-voice-wav.mjsvoiceStatus idle radioAudioState playing radioVoiceDucked false cameraHeightM 10_000_000即语音回归空闲、Radio 正在播放、扬声器已交还给 Radio不再闪避、相机高度达到 1000 万米以上全球视角。75 秒后无论成败都会汇总输出若voiceStatus error也会提前退出。通过判定最终ok为真需同时满足见 scripts/qa-voice-wav.mjs点击模式无条件成立push-to-talk 模式要求手势已开始且麦克风已释放pushToTalkStarted microphoneReleasedvoiceStatus idleradioAudioState playingradioVoiceDucked falsecameraHeightM 10_000_000。脚本还会收集页面console错误与pageerror连同完整状态时间线timeline每次状态签名变化时记录一帧、耗时与退出码一并输出为 JSON。退出码 0 表示通过1 表示失败。timeline的存在让你可以事后逐帧核对语音 → 相机缩放 → Radio 接管每一步的发生顺序。五、语音到 Radio 的底层链路控制流与扬声器交接语音动作control_radio工具夹具念出的turn on the radio在语音侧映射到名为control_radio的函数工具其 schema 定义在 src/voice/actionSchemas.jsaction枚举包含enable / disable / play / resume / pause / stop / next / previous / volume / select / status等并带volumePct0–100、categoryall / news / talk / weather / public-safety / aviation-marine / traffic-transit / music等参数。实际执行在 src/voice/gevActions.js 一带最终把动作转发给 dataManager 中的 Radio 图层模块。control_radio属于语音驱动真实图层的代表它不改变 UI 文本而是真真切切地启动网络广播播放并通过 src/voice/realtimeProtocol.js 的shouldStopVoiceAfterRadioTool决定是否把扬声器交还只有当结果ok且radioAction属于play / resume / select / next / previous时才停掉语音。扬声器交接RealtimeRadio与预播放后移交语音会话侧有一个专门的RealtimeRadio所有者类src/voice/realtimeRadio.js职责是扬声器闪避、预准备的播放、更强动作的预约与播放观察。核心流程语音持麦时静音 RadiopauseRadioForVoice()调用silenceRadioForVoicesrc/voice/realtimeProtocol.js把radioVoiceDucked置真并暂停 Radio确认后预播放startPendingRadioHandoff()先再次置真硬静音再调用startPreparedRadioAfterPlaybackReadysrc/voice/realtimeProtocol.js执行radioLayer.playForVoice()等待播放确实进入playing且仍处于静音状态后才stopVoice()释放语音最终把audioState标为playing失败自愈若播放未启动或会话已过期epoch 变化、用户新指令、通道关闭等则取消播放并让 AI 说一句固定纠正语The Radio station could not start. Voice is still on.见 src/voice/realtimeRadio.js。Radio 图层侧用播放且静音作为交接成功的前提见 src/layers/radio/playback.js 的状态观察逻辑playing playingStationId voiceDucked才算成功一旦出现未闪避却开始播放/缓冲!voiceDucked audioState 属于 loading/buffering/playing则立即判定失败——绝不允许 AI 与电台声音重叠。docs/VOICE-OWNERSHIP.md将这套协调关系总结为Radio 等待口头的确认与验证过的静音播放Radio waits for the spoken confirmation and verified muted playback并把realtimeRadio.js定位为扬声器闪避、预准备的播放、更强动作的预约和播放观察的所有者。相机到达全球视角full globe 由相机动作承担。语音命令通过adjust_camera_zoomdirection 为outamount 可选 little/medium/lot见 src/voice/gevActions.js或zoom_to_globe见 src/voice/gevActions.js实现。adjust_camera_zoom在camera.zoomOut(movementM)前先camera.cancelFlight()取消进行中的飞行防止缩放看起来什么都没发生对应 src/cameraVerbs.js 注释提到的实测问题。验收断言里cameraHeightM 10_000_0001000 万米即全球全景的量化标准。六、为什么需要凭据化夹具工程价值总结把 README、验收脚本与语音/Radio 源码合起来看这套夹具解决的是三类工程问题可重复性录音类验收依赖人、环境与声卡而 WAV 夹具 --use-file-for-fake-audio-capture让 CI 与本地获得完全一致的麦克风输入9.2 秒时长与%noloop语义保证每次只播一遍可审计性WAV 内嵌元数据描述生成器/模型/语音/文本/条款/音频设置脚本侧再以 SHA-256 硬编码校验双保险防止夹具被无声替换——这正是一个以真实数据为卖点的空间情报项目对测试输入本身也必须是真实可信的要求端到端真实性虽然音频是合成的但消费它的链路全部真实真实 Chromium、真实麦克风权限流、真实实时语音会话、真实control_radio工具调用、真实 Radio 播放器接管。唯一被模拟的只有声源本身。如果你想在本地复现完整验收按 scripts/dev-secure.sh 的描述启动配置好密钥的开发服务器默认http://localhost:4173然后依次运行node scripts/qa-voice-wav.mjs http://localhost:4173 node scripts/qa-voice-wav.mjs http://localhost:4173 --push-to-talk两条命令通过则分别证明点击开启语音与Space 推按说话两种交互下从假麦克风音频到全球视角 真实广播播放的整条链路均符合预期。【免费下载链接】gods-eye-viewA spy satellite simulator in your browser, except the data is real. Live open source spatial intelligence on a photorealistic 3D globe.项目地址: https://gitcode.com/GitHub_Trending/go/gods-eye-view创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

关系边界管理:用信息流动与权责溯源构建清晰的关系操作系统

关系边界管理:用信息流动与权责溯源构建清晰的关系操作系统

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/19 14:34:31 阅读更多 →
PlatformIO串口乱码终极排查:波特率三层校准法

PlatformIO串口乱码终极排查:波特率三层校准法

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/19 14:34:31 阅读更多 →
SAP SD定价过程详解:从条件类型到存取顺序的配置与排错

SAP SD定价过程详解:从条件类型到存取顺序的配置与排错

简介:这是一份深入讲解SAP SD模块定价逻辑的Word文档,适合SAP SD顾问、实施人员及需要理解销售订单价格计算原理的ERP从业者。文档从R/3系统如何根据物料金额计算净价值与总金额切入,完整梳理了定价过程的确定框架、客户定价过程与单据定价过…

2026/9/19 14:33:30 阅读更多 →

最新新闻

spinner 默认值不显示:把 Codex 的 Base URL 改到 TaoToken 后排查 setSelection

spinner 默认值不显示:把 Codex 的 Base URL 改到 TaoToken 后排查 setSelection

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/20 19:31:32 阅读更多 →
CAT 与 Logback 集成实战:通过 CatLogbackAppender 将业务日志无缝上报至 CAT

CAT 与 Logback 集成实战:通过 CatLogbackAppender 将业务日志无缝上报至 CAT

CAT 与 Logback 集成实战:通过 CatLogbackAppender 将业务日志无缝上报至 CAT 【免费下载链接】cat CAT 作为服务端项目基础组件,提供了 Java, C/C, Node.js, Python, Go 等多语言客户端,已经在美团点评的基础架构中间件框架(MVC框…

2026/9/20 19:31:32 阅读更多 →
深入解析 TanStack Table React 的 Renderable 类型别名:ReactNode 与组件渲染器的统一

深入解析 TanStack Table React 的 Renderable 类型别名:ReactNode 与组件渲染器的统一

前端UI组件 【免费下载链接】table 🤖 Headless UI for building powerful tables & datagrids for TS/JS - React-Table, Vue-Table, Solid-Table, Svelte-Table 项目地址: https://gitcode.com/gh_mirrors/ta/table 点击查看 免费下载 导读 Rend…

2026/9/20 19:31:32 阅读更多 →
MXNet npx 模块完全指南:NumPy 神经网络扩展(NPX)API 详解

MXNet npx 模块完全指南:NumPy 神经网络扩展(NPX)API 详解

MXNet npx 模块完全指南:NumPy 神经网络扩展(NPX)API 详解 【免费下载链接】mxnet Lightweight, Portable, Flexible Distributed/Mobile Deep Learning with Dynamic, Mutation-aware Dataflow Dep Scheduler; for Python, R, Julia, Scala,…

2026/9/20 19:31:32 阅读更多 →
三款开源AI网关横向测评:LiteLLM、New API与1Panel AI网关

三款开源AI网关横向测评:LiteLLM、New API与1Panel AI网关

最近两周我一直在折腾AI网关,起因特别朴实:手上模型API越来越多,OpenAI、Claude、DeepSeek、通义、豆包、智谱,各家接口风格还不一样,代码里到处是硬编码的base_url和密钥,管理混乱不说,项目交给…

2026/9/20 19:31:32 阅读更多 →
手把手教你用AI Skills打造论文写作与LaTeX排版技能包

手把手教你用AI Skills打造论文写作与LaTeX排版技能包

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/20 19:30:31 阅读更多 →

日新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/20 0:00:46 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/20 0:00:46 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/20 0:00:46 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/20 0:00:46 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/20 0:00:46 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/20 0:00:46 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/19 23:01:36 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/19 17:50:38 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/19 23:35:34 阅读更多 →