Skip to content

About

🎼 一个运行在浏览器中的双手手势虚拟吉他。打开网页并授权摄像头后,用户可以在镜像画面的左侧选择和弦,通过右手“握拳后张开”完成拨弦,无需安装客户端或连接外部乐器。

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

AirString Studio|在线手势虚拟吉他

AirString Studio 是一个运行在浏览器中的双手手势虚拟吉他。打开网页并授权摄像头后,用户可以在镜像画面的左侧选择和弦,通过右手“握拳后张开”完成拨弦,无需安装客户端或连接外部乐器。

项目基于 MediaPipe Hand Landmarker、Web Audio API、React 与 TypeScript 构建,界面使用 Tailwind CSS 与 shadcn/ui 风格的 Radix UI 组件。摄像头画面和手部关键点均在浏览器本地处理,不会由本应用上传;模型、WASM 运行时和字体也随站点一起发布,不依赖境外 CDN。

功能亮点

  • 双手同时识别:按照镜像画面区域分配左右手职责,避免依赖容易翻转的 handedness 标签。
  • 六个常用和弦:支持 C、G、Am、F、Em、Dm,使用对应的吉他开放和弦音高。
  • 稳定的手势选择:滑动投票与置信度阈值共同减少手势跳变。
  • 明确的拨弦动作:右手只有从闭合手掌变为张开手掌时才会触发,不会因上下移动误触。
  • 两种演奏方式:支持扫弦和分解和弦,可调节速度、音量并开启自动分解。
  • 实时视觉反馈:默认显示手部关键点,拨弦时展示当前和弦名称。
  • 跟弹练习:内置三组原创和弦练习,提供当前进度和下一和弦提示。
  • 中英文界面:可在页面顶部即时切换语言。
  • 响应式布局:适配桌面和移动端浏览器。
  • 识别调试面板:可查看 FPS、推理耗时、置信度、手势和右手状态。

手势说明

摄像头预览是镜像画面,区域以用户在屏幕中看到的位置为准:

  • 画面左侧:选择和弦。
  • 画面右侧:控制拨弦。

左手和弦

手势编号 手势 和弦
1 食指 C
2 食指 + 中指 G
3 食指 + 中指 + 无名指 Am
4 食指 + 中指 + 无名指 + 小指 F
5 五指张开 Em
6 拇指 + 小指 Dm

三指手势允许拇指因掌心朝向产生轻微误判,因此掌心或手背朝向摄像头时都能正常使用。

右手拨弦

  1. 在画面右侧握拳。
  2. 张开手掌。
  3. 每次“闭合 → 张开”触发一次拨弦。

右手的位置移动不会触发声音。触发后存在短暂冷却时间,以避免同一个动作被连续识别多次。

快速开始

环境要求

  • Node.js 22 或更高版本
  • pnpm 10 或更高版本
  • 支持摄像头和 WebGL 的现代浏览器,推荐 Chrome 或 Edge
  • 摄像头权限需要 localhost 或 HTTPS 安全环境

安装与启动

pnpm install
pnpm dev

开发服务器启动后,打开终端显示的本地地址,通常为:

http://localhost:5173

点击“开始演奏”并允许浏览器访问摄像头。演奏过程中可点击画面底部的“停止演奏”关闭摄像头和手势识别。

常用命令

# 启动开发服务器
pnpm dev

# 运行全部测试
pnpm test

# ESLint 检查
pnpm lint

# TypeScript 类型检查
pnpm typecheck

# 构建生产版本
pnpm build

# 本地预览生产构建
pnpm preview

生产文件会输出到 dist/ 目录。

技术栈

  • React 19
  • TypeScript(严格模式)
  • Vite 6
  • Tailwind CSS 3
  • shadcn/ui 组件架构(Radix UI、CVA、Tailwind Merge)
  • MediaPipe Tasks Vision / Hand Landmarker
  • Web Audio API + Meta Open Sound 尼龙吉他采样(CC0)
  • Web Audio API
  • Lucide React
  • Vitest 与 Testing Library
  • ESLint 与 Prettier

项目结构

src/
├── components/          # 相机、和弦、练习和教程界面
├── config/              # 手势识别与 MediaPipe 配置
├── hooks/               # 摄像头、音频和手部追踪 Hooks
├── i18n/                # 中文与英文文案
├── lib/
│   ├── audio/           # 吉他音色与 Web Audio 调度
│   ├── mediapipe/       # 手势、左右区域与拨弦识别
│   └── music/           # 和弦定义与练习数据
├── App.tsx              # 主应用状态与功能编排
└── styles.css           # Tailwind 入口与少量全局基础规则

public/mediapipe/
├── models/              # 本地 Hand Landmarker 模型
└── wasm/                # 本地 MediaPipe WASM 运行时

public/audio/guitar/     # 本地尼龙吉他 OGG 采样

吉他音色

应用优先加载 public/audio/guitar/ 中的 17 个真实尼龙吉他采样,并按照六根吉他的实际弦位映射到开放和弦。相同琴弦再次触发时会自然停止上一声,避免不真实的无限叠音;采样加载失败时才会使用内置合成音色兜底。

采样来自 Meta Open Sound 的 Meta Nylon Guitar Vel01Finger 层,使用 CC0 1.0 公共领域许可。项目仅保留当前六组和弦实际用到的音高,并以 OGG 格式随站点本地部署,运行时不依赖第三方音频 CDN。

识别参数

手势稳定帧数、置信度、冷却时间和推理帧率位于:

src/config/gesture.ts

默认推理上限为 30 FPS。MediaPipe 使用 GPU delegate,并通过 import.meta.env.BASE_URL 从本站的 public/mediapipe/ 加载 WASM 运行时与官方 Hand Landmarker 模型,因此同时兼容根路径部署和 GitHub Pages 的 /air-string/ 子路径。

模型与 WASM 会使生产包增加约 41 MB。部署时请完整上传 dist/mediapipe/,不要只上传 JavaScript 和 CSS 文件。

仓库中的 hand_landmarker.task SHA-256 为 fbc2a30080c3c557093b5ddfc334698132eb341044ccee322ccf8bcf3607cde1,升级模型时应同步更新并重新验证该值。

应用会在页面空闲时提前初始化 Hand Landmarker,并使用 Service Worker 长期缓存实际用到的模型与 WASM。首次访问仍需要下载资源,后续访问会直接使用本地缓存。

调试

在右侧控制面板展开“识别调试”,可以查看:

  • 实时 FPS
  • 单帧推理耗时
  • 左手识别置信度
  • 原始手势与稳定结果
  • 手指伸展状态
  • 右手闭合/张开状态

调试面板为页面内嵌布局,不会覆盖摄像头或其他操作区域。

常见问题

摄像头无法启动

  • 确认浏览器已经授予摄像头权限。
  • 检查摄像头是否正在被其他应用占用。
  • 线上访问时确认页面使用 HTTPS。
  • 修改权限后刷新页面,再次点击“开始演奏”。

手势识别不稳定

  • 保持手掌完整进入画面,不要遮挡指尖和手腕。
  • 使用均匀的正面光源,避免强烈逆光。
  • 左右手分别放在画面的左右区域,中间留出一定距离。
  • 将手与摄像头保持适中距离,避免手掌过小或超出画面。

没有声音

  • 必须先点击“开始演奏”,浏览器才允许创建音频上下文。
  • 检查页面音量、系统音量以及浏览器标签页是否静音。
  • Safari 用户可尝试再次点击和弦卡片以激活音频。

隐私说明

本应用直接在浏览器中完成摄像头帧和手部关键点分析。项目代码不包含上传、存储或发送摄像头画面的逻辑。MediaPipe 模型、WASM 运行时和界面字体均由当前站点本地提供,不会在运行时请求 Google Storage、jsDelivr 或 Google Fonts。

许可证

本项目采用 MIT License,详见 LICENSE。

About

🎼 一个运行在浏览器中的双手手势虚拟吉他。打开网页并授权摄像头后,用户可以在镜像画面的左侧选择和弦,通过右手“握拳后张开”完成拨弦,无需安装客户端或连接外部乐器。

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages