Files
bililive-touhou-tts/audio_player.py
T
chun_qiu 9b277fe2e0 feat: Bilibili Live Danmaku -> Yukkuri TTS Reader
- Python main entry with CLI (--room-id, --voice, --speed)
- blivedm integration for real-time danmaku receiving
- Chinese-to-Japanese katakana conversion (pypinyin + mapping table)
- Node.js persistent bridge for aquestalk.js TTS synthesis
- Audio playback via sounddevice
- Message queue for sequential TTS playback
2026-08-08 11:26:11 +08:00

47 lines
1.1 KiB
Python

"""Audio playback for WAV files."""
import asyncio
import io
import logging
import sounddevice as sd
import soundfile as sf
logger = logging.getLogger(__name__)
def play_wav(wav_data: bytes) -> None:
"""Play WAV audio data synchronously (blocking).
Args:
wav_data: Raw WAV file bytes.
"""
data, samplerate = sf.read(io.BytesIO(wav_data), dtype="float32")
sd.play(data, samplerate)
sd.wait()
async def play_wav_async(wav_data: bytes) -> None:
"""Play WAV audio data asynchronously.
Args:
wav_data: Raw WAV file bytes.
"""
loop = asyncio.get_running_loop()
await loop.run_in_executor(None, play_wav, wav_data)
def get_output_devices() -> list[dict]:
"""List available audio output devices."""
devices = sd.query_devices()
result = []
for i, dev in enumerate(devices):
if dev["max_output_channels"] > 0:
result.append({
"index": i,
"name": dev["name"],
"channels": dev["max_output_channels"],
"default_samplerate": dev["default_samplerate"],
})
return result