diff --git a/tools/asmr.py b/tools/asmr.py new file mode 100644 index 0000000..9014771 --- /dev/null +++ b/tools/asmr.py @@ -0,0 +1,50 @@ +"""Render asmr/voices.json into asmr/audio/*.mp3 through the shared inference worker, plus a rain bed. + + python3 tools/asmr.py + +Keyless: calls inference.yolopreneur.lol as the gandora app. Skips files that already exist. Needs ffmpeg. +""" +import json, os, subprocess, sys, urllib.request, urllib.error + +ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +OUT = os.path.join(ROOT, "asmr", "audio") +W = "https://inference.yolopreneur.lol/v1/speech" +H = {"Content-Type": "application/json", "Origin": "https://gandora.yolopreneur.lol", "x-app": "gandora", "User-Agent": "gandora-asmr"} + +cfg = json.load(open(os.path.join(ROOT, "asmr", "voices.json"))) +os.makedirs(OUT, exist_ok=True) +fail = 0 + +bed = os.path.join(OUT, "bed-rain.mp3") +if not os.path.exists(bed): + subprocess.run(["ffmpeg", "-y", "-loglevel", "error", + "-f", "lavfi", "-i", "anoisesrc=c=pink:a=0.5:d=60", "-f", "lavfi", "-i", "anoisesrc=c=brown:a=0.6:d=60", + "-filter_complex", "[0]highpass=f=900,lowpass=f=7000,tremolo=f=7:d=0.25[a];[1]lowpass=f=300[b];" + "[a][b]amix=inputs=2:weights=1 0.6,afade=t=in:d=2,afade=t=out:st=58:d=2,volume=0.6", "-b:a", "96k", bed], check=True) + +for v in cfg["voices"]: + dst = os.path.join(OUT, v["id"] + ".mp3") + if os.path.exists(dst): + continue + text = cfg["script"].replace("Hey...", "Hey... ", 1) if v.get("tags") else cfg["script"] + fmt = v.get("format", "mp3") + body = {"model": v["model"], "voice": v["voice"], "input": text, "response_format": fmt} + if v.get("speed"): body["speed"] = v["speed"] + if v.get("style"): body["prompt"] = cfg["style"] + try: + with urllib.request.urlopen(urllib.request.Request(W, json.dumps(body).encode(), H), timeout=110) as r: + data = r.read() + except urllib.error.HTTPError as e: + print("ERR", v["id"], e.code, e.read()[:200]); fail += 1; continue + except Exception as e: + print("ERR", v["id"], e); fail += 1; continue + if fmt == "mp3": + open(dst, "wb").write(data) + else: + tmp = dst + "." + fmt + open(tmp, "wb").write(data) + subprocess.run(["ffmpeg", "-y", "-loglevel", "error", "-i", tmp, "-b:a", "128k", dst], check=True) + os.remove(tmp) + print("ok", v["id"]) + +sys.exit(1 if fail == len(cfg["voices"]) else 0)