Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions .github/workflows/docker-build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
name: Build and Push Docker Image

on:
push:
branches: [ main ]
tags:
- 'v*'
workflow_dispatch:

permissions:
contents: read

jobs:
docker:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: gmij/audio3a
tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=sha,prefix={{branch}}-
type=raw,value=latest,enable={{is_default_branch}}

- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
file: ./samples/Audio3A.WebApi/Dockerfile
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max

- name: Image digest
run: echo ${{ steps.docker_build.outputs.digest }}
Comment on lines +55 to +56

Copilot AI Nov 23, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

步骤引用了 steps.docker_build.outputs.digest,但构建步骤的 id 没有设置为 docker_build。第 44 行的 "Build and push Docker image" 步骤需要添加 id: docker_build,否则这个输出步骤会失败。

Copilot uses AI. Check for mistakes.
296 changes: 296 additions & 0 deletions docs/AUDIO_RECORDING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,296 @@
# 音频录制和下载功能说明

## 概述

在通话界面新增了音频录制和下载功能,用户可以录制整个通话过程,并分别下载原声和经过 3A 处理后的音频。

## 功能特性

### 录制功能
- ✅ 实时录制通话音频
- ✅ 同时录制原声和处理后音频
- ✅ 可随时开始/停止录制
- ✅ 录制状态可视化(脉冲动画)

### 下载功能
- ✅ 下载原声音频(麦克风直接输入)
- ✅ 下载净化后音频(经过 3A 处理)
- ✅ 自动生成带时间戳的文件名
- ✅ WebM 格式(Opus 编解码器)

## 使用指南

### 1. 进入通话

首先创建或加入一个房间,进入通话界面。

### 2. 开始录制

点击控制栏中的**录制按钮**(摄像机图标):
- 按钮会变为红色
- 显示脉冲动画表示正在录制
- 此时会同时录制两路音频流

### 3. 停止录制

再次点击录制按钮停止录制:
- 按钮恢复正常颜色
- 动画停止
- 录制的音频已保存在浏览器内存中

### 4. 下载音频

点击**下载按钮**(向下箭头图标),从下拉菜单选择:

**选项 1:下载原声音频**
- 文件名:`input-audio-YYYYMMDD-HHmmss.webm`
- 内容:麦克风直接采集的原始音频
- 包含:环境噪声、回声、音量波动等

**选项 2:下载净化后音频**
- 文件名:`processed-audio-YYYYMMDD-HHmmss.webm`
- 内容:经过 3A 处理的音频
- 效果:回声消除、噪声抑制、自动增益控制

## 界面说明

### 控制按钮布局

通话界面底部控制栏(从左到右):

1. **静音按钮** 🎤
- 功能:切换麦克风静音
- 状态:静音时显示红色

2. **录制按钮** 📹
- 功能:开始/停止录制
- 状态:录制中显示红色脉冲动画

3. **挂断按钮** 📞
- 功能:结束通话
- 样式:红色大按钮

4. **下载按钮** ⬇️
- 功能:下载录制的音频
- 状态:未录制时禁用(灰色)

5. **设置按钮** ⚙️
- 功能:预留(暂未实现)
- 状态:禁用

### 视觉反馈

**录制中**:
- 录制按钮背景变红
- 脉冲动画(淡入淡出效果)
- 清晰提示正在录制状态

**录制完成**:
- 下载按钮从禁用变为可用
- 可以重复录制(会覆盖之前的录音)

## 技术实现

### 架构

```
麦克风输入
Web Audio API
├─→ 原始音频流 → MediaRecorder → 原声录音
└─→ 3A 处理 → MediaStreamDestination → MediaRecorder → 净化后录音
```

### 使用的 API

1. **MediaRecorder API**
- 用途:录制音频流
- 编码:audio/webm (Opus codec)
- 参数:每 100ms 收集一次数据

2. **Web Audio API**
- 用途:创建音频处理图
- ScriptProcessor:处理音频数据
- MediaStreamDestination:导出处理后的音频流

3. **JavaScript Interop**
- Blazor 与 JavaScript 通信
- 控制录制状态
- 触发下载操作

### 文件格式

- **格式**:WebM
- **编解码器**:Opus
- **采样率**:取决于浏览器和麦克风设置
- **声道**:单声道(Mono)
- **比特率**:自动调整

## 浏览器兼容性

### 支持的浏览器

| 浏览器 | 版本要求 | MediaRecorder | Web Audio API |
|--------|---------|---------------|---------------|
| Chrome | 49+ | ✅ | ✅ |
| Edge | 79+ | ✅ | ✅ |
| Firefox | 25+ | ✅ | ✅ |
| Safari | 14.1+ | ✅ | ✅ |
| Opera | 36+ | ✅ | ✅ |

### 已知限制

1. **iOS Safari**
- 需要用户手势才能开始录制
- WebM 支持可能受限(Safari 14.1+)

2. **移动浏览器**
- 可能需要额外的权限请求
- 某些设备可能不支持 Opus 编码

3. **隐私模式**
- 某些浏览器在隐私模式下可能限制音频录制

## 使用场景

### 1. 会议记录
- 录制完整会议内容
- 对比 3A 处理效果
- 事后回顾讨论内容

### 2. 音频质量测试
- 测试 3A 算法效果
- 对比原声和处理后的差异
- 优化音频处理参数

### 3. 培训和演示
- 录制演示内容
- 提供清晰的音频材料
- 展示 3A 处理能力

### 4. 故障诊断
- 记录音频问题
- 分析噪声来源
- 测试不同环境下的表现

## 性能考虑

### 内存使用

- 录制时音频数据存储在浏览器内存
- 长时间录制会占用较多内存
- 建议录制时长不超过 30 分钟

### 文件大小

估算公式(Opus @ 48kHz):
- 比特率:约 24-32 kbps(单声道)
- 1 分钟:约 180-240 KB
- 10 分钟:约 1.8-2.4 MB
- 30 分钟:约 5.4-7.2 MB

### 优化建议

1. **定期下载**
- 长时间通话时分段录制
- 及时下载释放内存

2. **监控内存**
- 注意浏览器内存警告
- 必要时停止录制

3. **网络影响**
- 录制在本地进行,不占用网络
- 下载也是本地操作

## 故障排查

### 无法开始录制

**症状**:点击录制按钮无反应

**解决方法**:
1. 检查麦克风权限是否已授予
2. 确认已成功进入通话
3. 查看浏览器控制台错误信息
4. 尝试刷新页面重新进入

### 下载按钮禁用

**症状**:无法点击下载按钮

**原因**:未进行过录制

**解决方法**:
1. 先点击录制按钮开始录制
2. 等待一段时间
3. 停止录制
4. 下载按钮会变为可用

### 下载的文件无法播放

**症状**:下载的 WebM 文件播放失败

**解决方法**:
1. 使用支持 WebM 的播放器(VLC、Chrome)
2. 转换为 MP3 格式(使用 FFmpeg):
```bash
ffmpeg -i input-audio.webm -codec:a libmp3lame output.mp3
```
3. 检查文件大小(如果为 0 说明录制失败)

### 音频质量问题

**症状**:录制的音频质量差

**解决方法**:
1. 检查麦克风质量
2. 确保良好的网络环境
3. 启用 3A 处理功能
4. 调整麦克风音量和位置

## 隐私和安全

### 数据存储

- ✅ 所有录制在浏览器本地完成
- ✅ 音频数据不会上传到服务器
- ✅ 下载后立即从内存清除
- ✅ 关闭页面会丢失未下载的录音

### 权限要求

- 麦克风访问权限
- 文件下载权限(某些浏览器)

### 最佳实践

1. **告知参与者**
- 在开始录制前通知其他参与者
- 遵守隐私法规(如 GDPR)

2. **安全存储**
- 下载后的文件妥善保管
- 考虑加密敏感内容

3. **及时删除**
- 不需要的录音及时删除
- 避免长期保存敏感对话

## 未来改进

计划中的功能:

- [ ] 支持更多音频格式(MP3、AAC)
- [ ] 云端存储集成
- [ ] 自动分段录制
- [ ] 录音质量设置
- [ ] 音频编辑功能
- [ ] 转录服务集成

## 参考资料

- [MediaRecorder API](https://developer.mozilla.org/en-US/docs/Web/API/MediaRecorder)
- [Web Audio API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API)
- [WebM 格式规范](https://www.webmproject.org/)
- [Opus 编解码器](https://opus-codec.org/)
Loading
Loading