Files
compute/tools/backfill_voice.py
2026-08-31 16:09:08 -07:00

70 lines
2.1 KiB
Python

#!/usr/bin/env python3
"""One-time backfill: seed voice.jsonl from WAV files that already existed in
~/chatterbox/generations before per-request logging was added to voice_api.py.
No chars/voice/variant metadata exists for these -- marked backfill:true.
Safe to re-run: skips gen_ids already present in voice.jsonl.
"""
import contextlib
import json
import os
import wave
GEN_DIR = os.path.expanduser("~/chatterbox/generations")
USAGE_DIR = os.path.expanduser("~/lumbridge/compute/.compute/usage")
VOICE_LOG = os.path.join(USAGE_DIR, "voice.jsonl")
def already_logged():
seen = set()
if os.path.exists(VOICE_LOG):
with open(VOICE_LOG) as f:
for line in f:
try:
seen.add(json.loads(line)["gen_id"])
except Exception:
continue
return seen
def main():
os.makedirs(USAGE_DIR, exist_ok=True)
seen = already_logged()
added = 0
skipped = 0
errors = 0
with open(VOICE_LOG, "a") as out:
for fname in os.listdir(GEN_DIR):
if not fname.endswith(".wav"):
continue
gen_id = fname[:-4]
if gen_id in seen:
skipped += 1
continue
path = os.path.join(GEN_DIR, fname)
try:
with contextlib.closing(wave.open(path, "rb")) as wf:
frames = wf.getnframes()
rate = wf.getframerate()
duration = frames / float(rate) if rate else 0.0
except Exception:
errors += 1
continue
record = {
"ts": os.path.getmtime(path),
"gen_id": gen_id,
"duration_s": duration,
"sr": rate,
"chars": None,
"voice": None,
"variant_used": None,
"gen_ms": None,
"backfill": True,
}
out.write(json.dumps(record) + "\n")
added += 1
print(f"added={added} skipped(already logged)={skipped} errors={errors}")
if __name__ == "__main__":
main()