Skip to main content
Glama
glasscast

glasscast

by Edint386

glasscast

把电脑屏幕投到千问 AI 眼镜 S1,用语音开始和停止。适合瞄一眼终端、构建进度或文档,不适合看视频、玩游戏。

非官方个人项目,与阿里巴巴、千问团队和千问 AI 硬件开放平台没有任何关联。

它怎么工作

眼镜没有给第三方开放视频流,所以 glasscast 用连续换图来代替视频。一次投屏分三段:

  1. 电脑截屏。 glasscast serve 不停截屏,按推荐配置缩到 480×218,压成约 2.6 KB 的灰度 JPEG。它只保留最新一帧,放在你自己的公网 HTTPS 域名下。

  2. 眼镜取图。 眼镜上的页面不停换图片地址,比如 …/screen.jpg/0101120000_1.jpg、…/0101120000_2.jpg。地址一变,手机 App 就下载一次,拿到的总是最新一帧,再经蓝牙传给眼镜解码显示。

  3. 语音控制。 你对眼镜说「开始投屏」,千问平台的大模型调用 glasscast 的 MCP 工具,再打开投屏页面。MCP 只管开始、停止和查询,不参与逐帧刷新。

一张图从手机下载到眼镜显示,固定要约 0.65 秒,和图片是 2.5 KB 还是 4 KB 关系不大。这决定了这条链路的速度上限。

Related MCP server: openowl

实际效果

下面是在 S1 真机上测到的结果:

普通模式(默认)

流畅模式

速度

约每秒 1 帧

最高约每秒 1.5 帧

眼镜页面

cast-image

cast-emit

特点

最稳

稍快,档位太高时会卡住

  • 普通模式延迟约 1~2 秒,流畅模式没有单独测过。

  • 单色绿屏,没有声音,也不能在眼镜上操作电脑。

  • 画面在视野左上角,页面里改不了。整屏缩小后小字看不清,看代码时建议只投一块区域(GLASSCAST_REGION)。

  • 只在 macOS 上测过。

流畅模式的实现思路

流畅模式要同时做到两件事:换图比每秒一次快,并且每张图都来得及显示。

普通模式为什么快不起来

普通模式用 <tick> 换图。页面里所有 tick 共用一个 1 秒定时器,所以最快每秒 1 帧。我们也试过用 <frame-set> 帧合集当定时器,模拟器里能跑,但平台保存时的校验(URI-001)不放行,放不到真机上。

用事件倒数当定时器

页面可以给自己发 emit:// 事件。emit 是异步的,事件要等下一轮消息循环才送达,真机上每一步约 13 毫秒。收到事件后再发一个,页面就有了一个比 tick 快得多的节拍。

难点在于节拍不能写进 data。每写一次 data 就刷新一次绑定,而绑定一刷新,还没加载完的 <image> 就要从头加载。早期版本每一圈都连写两三次 data,真机上每张图被请求 3~6 次,最后只显示出一张图。

所以计数放在事件参数里,只有换图时才写 data。页面的核心就是下面这些(完整代码见 pages/cast-emit/template.xml):

<data s="0" g="0" m="75"/>

<!-- 打开页面:写入每轮的步数 m,开始倒数 -->
<lifecycle-event a:if="{{hops != 0}}" on-load="data://update?m={{hops * 3}}" on-new-intent="data://update?m={{hops * 3}}"/>
<lifecycle-event on-load="emit://event/d10?n=10"/>

<!-- 倒数:d1 到 d9 共九条规则,动作相同,都是把 n 减一再发出去 -->
<event match="event://d1" action="emit://event/d{{e:n - 1}}?n={{e:n - 1}}"/>
<event match="event://d9" action="emit://event/d{{e:n - 1}}?n={{e:n - 1}}"/>

<!-- 倒到 0:写一次换图编号 g,再从 m 开始下一轮 -->
<event match="event://d0?" action="data://update?g={{d:g + 1}}"/>
<event match="event://d0?" action="emit://event/d{{d:m}}?n={{d:m}}"/>

<image a:if="{{d:s != 0}}" src="{{url}}{{structuredContent.url}}/{{d:s}}_{{d:g}}.jpg" width="640" height="290" image-fit="stretch"/>

以档位 4 为例,m 是 36,一张图的过程是:

  1. 倒数到 0,g 加一。这是一轮里唯一一次写 data,图片地址随之变成 …/<会话>_<g>.jpg。

  2. 手机下载最新一帧,经蓝牙传给眼镜,眼镜解码显示。

  3. 这段时间里页面继续倒数 36、35……1,全程不写 data,图片不会被打断。

  4. 又倒到 0,回到第 1 步。

还有两个写法上的细节:

  • 九条规则就能倒任意步数。 每页不同的 match 数量有限(最多 32 个),而 match 是前缀匹配:event://d3 能命中 d3、d30、d36。所以 d1~d9 按 n 的首位数字分流,只有 n 到 0 时才命中 d0?。

  • 地址每次都不一样。 data 里的数超过 2147483647 会被卡住,时间戳存不进去。所以 s 只取打开页面时的月日时分秒,g 是从 0 开始的小计数器,两者拼成的地址不会溢出,每次打开页面也不会命中缓存。地址还必须以 .jpg 结尾,用 ?ts= 防缓存的地址能下载,但眼镜不显示。

档位和真实帧数

start_cast 的 fps 参数是速度档位,不是眼镜上的帧数。它决定两件事:

  • 电脑每秒截几张图。 档位 4 时电脑每秒截 4 张,眼镜只来得及显示约 1.5 帧,手机每次取到的都是最新一张。

  • 页面每轮倒数多少步。 hops = round(1000 / 档位 / 20)(Python 的 round,12.5 取 12;20 是 GLASSCAST_EMIT_HOP_MS 的默认值),限制在 1~25,m = hops × 3。hops 由 start_cast 算好,模型打开页面时传进去,所以换档不用改页面。

档位

每轮步数

换图间隔

真实帧数

表现

1~2

75

约 1 秒(估算)

约每秒 1 帧(估算)

没有直接测过

3~4

36~51

正常时 630~720 毫秒

约每秒 1.5 帧

图小时稳定,见下

4.5 及以上

33 及以下

不固定,4.5 档卡住时约 405 毫秒

时好时坏

容易卡住(只实测过 4.5 档)

3~4.5 档是实测的,1~2 档是按步数估算的。3、3.3 档用约 4.1 KB 的图,4 档的 630~720 毫秒和 4.5 档用约 2.5 KB 的图。图越小越不容易卡:约 4.1 KB 的图到 3.5 档就开始不稳,3.8 档约 500 毫秒、时好时坏,4 档不行;约 2.5 KB 的图到 4 档还算稳。

上限和卡住是怎么来的

每张图有约 0.65 秒的固定开销,所以倒数再短,真实帧数也基本停在每秒 1.5 帧左右。

档位 4 的 36 步按每步 13 毫秒算只要约 470 毫秒,比 0.65 秒还短,正常时实测却是 630~720 毫秒。这是因为眼镜处理图片时,事件循环也被拖慢了。

问题在于倒数并不知道图片显示完了没有。只要有一张图没显示出来,眼镜就不再被拖慢,循环回到全速(每步约 12.5 毫秒),下一张来得更快,也就更显示不出来。真机日志里这种状态能持续几十秒,换图间隔只有 405~450 毫秒,画面却不动。档位越高越容易掉进去,4 是实测能稳住的最高档,但也不是绝对不会卡。

想再快,只能一次下载里装多帧,在眼镜本地播放,这条路还在实验中。现在传的始终是一张张普通 JPEG,不是视频流,也不是 GIF:<gif> 的 src 在模拟器里只在创建时取一次,换不了内容(真机没测过),GIF 输出只是默认关闭的实验开关,现有页面都没用它。

需要准备

  • 千问 AI 眼镜 S1 和手机 App「千问AI穿戴」

  • 千问 AI 硬件开放平台账号

  • 一台装好 uv 的 Mac,投屏时不能锁屏或睡眠

  • 一个指向这台电脑的公网 HTTPS 域名,必须是真证书

快速开始

先在本机试一下,不需要眼镜:

git clone https://github.com/Edint386/glasscast.git
cd glasscast
uv sync
GLASSCAST_TOKEN=local-test-token-123456 GLASSCAST_CAST_KEY=localtest123 \
  uv run glasscast serve --source synthetic --public-url http://127.0.0.1:8766 --autostart image

用浏览器打开 http://127.0.0.1:8766/s/localtest123/screen.jpg,合成画面约每秒更新一帧,隔一秒以上刷新就能看到新画面。

接到眼镜上:

  1. 运行 cp .env.example .env,填好域名和 token(用 openssl rand -hex 24 生成)。

  2. 给启动 glasscast 的终端打开「屏幕录制」权限。

  3. 把服务暴露到公网 HTTPS,见 公网部署。

  4. 启动服务:. ./.env && uv run glasscast serve。

  5. 在平台上建 MCP 插件、技能和两个页面,见 平台配置。

  6. 对眼镜说「开始投屏」。

语音命令

你说

效果

开始投屏

用普通模式投屏,约每秒 1 帧

用流畅模式投屏

用流畅模式投屏,最高约每秒 1.5 帧

最流畅

调到 4 档,约每秒 1.5 帧

最省流量

调到 1 档,约每秒 1 帧

投屏调到 N 档

N 取 1~10。档位不等于帧数,见上面的表,建议不超过 4 档

投屏状态

查询是否在投、电脑多久前截过图。看不出眼镜上的画面是否卡住

停止投屏

电脑停止截屏,再用眼镜的返回手势离开页面

安全

  • 图片地址里的 KEY 等于看屏口令,拿到完整地址的人就能看到你的屏幕。

  • 投屏会投出屏幕上的一切,包括通知和密码框。

  • Token 只填在平台的插件配置和本机的 .env 里,不要写进技能或页面。

详见 使用手册的安全一节。

文档

  • 使用手册:完整部署步骤、命令行和环境变量、HTTP 和 MCP 接口、排错、已知问题

  • 公网部署:反向 SSH 隧道、nginx、1Panel、cloudflared

  • 平台配置:在千问平台上建插件、技能和页面

  • 眼镜页面:每个页面是什么、改页面前要知道的限制

  • 本地模拟器:不用眼镜预览页面

  • 实验记录:带日期的调研和真机测试笔记

许可

代码以 MIT 许可证 发布。「千问」「Qwen」等名称和商标归其各自所有者。模拟器用到的官方渲染内核不包含在本仓库里,由脚本从官方 CDN 下载。使用时请遵守平台的开发者协议,投屏内容和公网暴露的风险由使用者自行承担。

English: glasscast mirrors a Mac screen to Qwen AI glasses S1 by serving small grayscale JPEGs over your own HTTPS domain, at about 1 to 1.5 images per second. Setup docs are in Simplified Chinese. This is an unofficial personal project.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      A
      quality
      D
      maintenance
      A small Model Context Protocol (MCP) server that gives an LLM eyes on your desktop without burning context. It can take one-off screenshots, crop a region around the mouse cursor, and run timed streaming sessions that save frames to disk and only return image bytes when explicitly asked.
      8
      MIT
    • A
      license
      Not graded
      quality
      B
      maintenance
      An MCP server that gives any AI assistant eyes and hands on your desktop — screenshots, clicking, typing, OCR, window management, accessibility-tree queries, workflow recording.
      5
      Apache 2.0
    • A
      license
      A
      quality
      F
      maintenance
      Provides an MCP server for local low-power screen vision, enabling AI agents to perform OCR and UI detection on inaccessible screens (games, remote desktops) using NPU acceleration and system OCR.
      5
      1
      MIT