# FunASR WebSocket服务

## 简介
本项目基于FunASR实现了一个WebSocket语音识别服务，支持实时语音流的在线和离线识别。利用ModelScope开源语音模型，该服务可以进行高精度的中文语音识别，并支持语音活动检测(VAD)和自动添加标点符号。

## 项目结构
```
.
├── src/                          # 源代码目录
│   ├── __init__.py               # 包初始化文件
│   ├── server.py                 # WebSocket服务器实现
│   ├── config.py                 # 配置处理模块
│   ├── models.py                 # 模型加载模块
│   ├── service.py                # ASR服务实现
│   └── client.py                 # 测试客户端
├── tests/                        # 测试目录
│   ├── __init__.py               # 测试包初始化文件
│   └── test_config.py            # 配置模块测试
├── requirements.txt              # Python依赖
├── Dockerfile                    # Docker配置
├── docker-compose.yml            # Docker Compose配置
├── .gitignore                    # Git忽略文件
└── README.md                     # 项目说明
```

## 功能特性

- **多模式识别**：支持离线(offline)、在线(online)和两阶段(2pass)识别模式
- **语音活动检测**：自动检测语音开始和结束
- **标点符号**：支持自动添加标点符号
- **WebSocket接口**：基于二进制WebSocket提供实时语音识别
- **Docker支持**：提供容器化部署支持

## 安装与使用

### 环境要求
- Python 3.8+
- CUDA支持 (若需GPU加速)
- 内存 >= 8GB

### 安装依赖

```bash
pip install -r requirements.txt
```

### 运行服务器

```bash
python src/server.py
```

常用启动参数:
- `--host`: 服务器监听地址，默认为 0.0.0.0
- `--port`: 服务器端口，默认为 10095
- `--device`: 设备类型(cuda或cpu)，默认为 cuda
- `--ngpu`: GPU数量，0表示使用CPU，默认为 1

### 测试客户端

```bash
python src/client.py --audio_file path/to/audio.wav
```

常用客户端参数:
- `--audio_file`: 要识别的音频文件路径
- `--mode`: 识别模式，可选 2pass/online/offline，默认为 2pass
- `--host`: 服务器地址，默认为 localhost
- `--port`: 服务器端口，默认为 10095

## Docker部署

### 构建镜像

```bash
docker build -t funasr-websocket .
```

### 使用Docker Compose启动

```bash
docker-compose up -d
```

## API说明

### WebSocket消息格式

1. **客户端配置消息**:
```json
{
  "mode": "2pass",  // 可选: "2pass", "online", "offline"
  "chunk_size": "5,10",  // 块大小，格式为"encoder_size,decoder_size"
  "wav_name": "audio1",  // 音频标识名称
  "is_speaking": true    // 是否正在说话
}
```

2. **客户端音频数据**:
二进制音频数据流，16kHz采样率，16位PCM格式

3. **服务器识别结果**:
```json
{
  "mode": "2pass-online", // 识别模式
  "text": "识别的文本内容",   // 识别结果
  "wav_name": "audio1",    // 音频标识
  "is_final": false        // 是否是最终结果
}
```
