import hashlib
import subprocess
from pathlib import Path
from namu import Namu
client = Namu()
CACHE = Path("cache"); CACHE.mkdir(exist_ok=True)
OUT = Path("reminders"); OUT.mkdir(exist_ok=True)
VOICES = {"ha": "nadia", "dje": "mouhamad"}
PARTS = {
"ha": {
"greeting": "Ina kwana!",
"message": "Kar ki manta, gobe da safe ki kawo jaririnki asibiti don allurar rigakafi.",
},
# Write the Zarma sentences with a native speaker and add them here before sending Zarma reminders.
"dje": {},
}
def spoken(text: str, language: str) -> Path:
"""The audio for `text`, generated once and kept in the cache."""
voice = VOICES[language]
path = CACHE / (hashlib.sha256(f"{voice}:{language}:{text}".encode()).hexdigest()[:16] + ".wav")
if not path.exists():
path.write_bytes(client.speech(text, voice=voice, language=language, format="wav"))
return path
def reminder(name: str, language: str) -> Path:
parts = PARTS[language]
files = [spoken(parts["greeting"], language), spoken(name, language), spoken(parts["message"], language)]
out = OUT / f"{hashlib.sha256((name + language).encode()).hexdigest()[:12]}.ogg"
listing = CACHE / "list.txt"
listing.write_text("".join(f"file '{f.resolve()}'\n" for f in files))
# Join the parts and encode once as small Opus, ready for WhatsApp or a phone line.
subprocess.run(["ffmpeg", "-y", "-loglevel", "error", "-f", "concat", "-safe", "0", "-i", str(listing),
"-c:a", "libopus", "-b:a", "24k", str(out)], check=True)
return out
if __name__ == "__main__":
for name in ["Aisha", "Hadiza", "Maryam"]:
print(reminder(name, "ha"))