4.1 KiB
SmartMeeting
SmartMeeting is a Docker Compose deployment for Speakr, FunASR Paraformer ASR, speaker embedding extraction, and the realtime WebSocket bridge.
Directory Layout
/storage01/home/xll/202607/voice
├── docker-compose.yml # Main Compose file
├── config.env # Runtime configuration to edit
├── asr/main.py # ASR adapter service code
├── speakr/ # Speakr frontend/backend code
├── voice-dected/ # Speaker embedding service code
├── fastapi_wss/ # Realtime WebSocket bridge code
└── deploy/data/ # Runtime data, ignored by git
Start And Stop
Run all services:
cd /storage01/home/xll/202607/voice
docker compose up -d
Check status and logs:
docker compose ps
docker compose logs -f
Stop services:
docker compose down
Services And Ports
| Service | Container | Port | Purpose |
|---|---|---|---|
| Speakr | voice-speakr |
8899 |
Web UI and backend |
| ASR | asr-test |
59805 |
Paraformer HTTP and WebSocket ASR |
| Speaker embedding | voice-dected |
18000 |
/extract_embedding voiceprint service |
| Realtime bridge | fastapi-wss |
10095 |
Browser realtime ASR WebSocket bridge |
| Redis | voice-redis |
16380 |
Cache/session storage for realtime bridge |
Main access URL:
http://192.168.0.46:8899/tool/speakr/
For browser microphone recording, use a secure context. The quickest local workaround is an SSH tunnel:
ssh -L 8899:127.0.0.1:8899 xll@192.168.0.46
Then open:
http://localhost:8899/tool/speakr/
Configuration
Most runtime settings are in:
/storage01/home/xll/202607/voice/config.env
Edit this file first when changing service addresses, model endpoints, LLM settings, or speaker matching behavior. After editing:
cd /storage01/home/xll/202607/voice
docker compose up -d
Important variables:
ASR_BASE_URL=http://asr-test:59805
TARGET_WS_URL=ws://asr-test:59805/ws/asr
VOICE_DETECTED_URL=http://voice-dected:8000
SPEAKER_DET_URL=http://voice-dected:8000/extract_embedding
REDIS_URL=redis://redis:6379/0
TEXT_MODEL_BASE_URL=http://192.168.0.46:59800/v1
TEXT_MODEL_NAME=46-qwen3.5-35B
TEXT_MODEL_API_KEY=none
VOICEPRINT_STORE=/data/asr_voiceprints.json
VOICEPRINT_MATCH_THRESHOLD=0.45
Notes:
- Inside Docker Compose, use service names such as
asr-test,voice-dected, andredis. - From outside Docker, use host ports such as
192.168.0.46:59805,192.168.0.46:18000, and192.168.0.46:10095. VOICEPRINT_MATCH_THRESHOLDcontrols how strict speaker matching is. Lower values match more easily; higher values reduce false matches.
Runtime Data
Runtime data is stored under:
/storage01/home/xll/202607/voice/deploy/data/
Important subdirectories:
deploy/data/speakr/uploads/ # Uploaded/recorded audio
deploy/data/speakr/instance/ # Speakr SQLite database
deploy/data/asr/ # ASR voiceprint store
deploy/data/redis/ # Redis persistence
These files are ignored by git.
Voiceprint Flow
Speakr calls the ASR adapter for voiceprint platform compatibility:
POST /voice_insert
GET /get_voice_name
DELETE /delete_voice
The ASR adapter stores embeddings in:
deploy/data/asr/asr_voiceprints.json
During /asr transcription, the adapter converts uploaded audio to 16 kHz mono
WAV, calls voice-dected, compares the embedding with stored voiceprints, and
returns a matched speaker name when the similarity passes the threshold.
Useful Checks
curl http://127.0.0.1:59805/health
curl http://127.0.0.1:59805/get_voice_name
curl http://127.0.0.1:8899/tool/speakr/api/config
WebSocket check:
docker exec -it fastapi-wss python - <<'PY'
import asyncio, json, websockets
async def main():
async with websockets.connect("ws://127.0.0.1:10095") as ws:
await ws.send(json.dumps({"mode": "2pass", "is_speaking": True}))
await ws.send(json.dumps({"type": "stop", "is_speaking": False}))
print(await ws.recv())
asyncio.run(main())
PY