SmartMeeting/README.md
2026-07-15 17:04:08 +08:00

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, and redis.
  • From outside Docker, use host ports such as 192.168.0.46:59805, 192.168.0.46:18000, and 192.168.0.46:10095.
  • VOICEPRINT_MATCH_THRESHOLD controls 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