61 lines
2.6 KiB
Python
61 lines
2.6 KiB
Python
"""Transfert de fichiers voix entre la tablette et Kazeia-central (adb).
|
|
|
|
Py3.14-safe (pas de torch) : seulement des opérations adb. Le chemin des fichiers est
|
|
**device-dépendant** → on part toujours de la colonne `wav_path` que le provider
|
|
`/voices` renvoie (autorité), jamais d'un chemin codé en dur (WAV sous
|
|
`/data/local/tmp/kazeia/…` en dev, `Android/data/com.kazeia/…` en prod).
|
|
|
|
Voix = clone-prompts **OmniVoice `.ovsp`** (migration 23/06/2026, ex-CosyVoice `.cvps`),
|
|
déployés dans `<MODELS_DIR>/omnivoice/voices/`.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import posixpath
|
|
|
|
from ..adb import Adb, AdbError
|
|
|
|
# Le provider expose VOICE_WAV_DIR = "${MODELS_DIR}/../voix/voix" → ce marqueur
|
|
# permet d'extraire MODELS_DIR depuis un wav_path, donc le dossier voix OmniVoice cible.
|
|
_WAV_MARKER = "/../voix/voix/"
|
|
|
|
|
|
def omnivoice_dir_for(wav_path: str) -> str:
|
|
"""Dossier device des `.ovsp` (`<MODELS_DIR>/omnivoice/voices`) dérivé d'un `wav_path`."""
|
|
if _WAV_MARKER in wav_path:
|
|
models = wav_path.split(_WAV_MARKER)[0]
|
|
return posixpath.join(models, "omnivoice", "voices")
|
|
# Fallback : …/kazeia/voix/voix/<id>.wav → …/kazeia/models/omnivoice/voices
|
|
voix_dir = posixpath.dirname(wav_path)
|
|
kazeia = posixpath.dirname(posixpath.dirname(voix_dir))
|
|
return posixpath.join(kazeia, "models", "omnivoice", "voices")
|
|
|
|
|
|
def deployed_ovsp(adb: Adb, serial: str, ovsp_dir: str) -> set[str]:
|
|
"""Ensemble des voice_id ayant un `.ovsp` déjà déployé sur la tablette."""
|
|
out = adb.shell(f"ls {ovsp_dir} 2>/dev/null", serial=serial)
|
|
return {line[:-5].strip() for line in out.splitlines()
|
|
if line.strip().endswith(".ovsp")}
|
|
|
|
|
|
def pull_wav(adb: Adb, serial: str, wav_path: str, local_path: str) -> None:
|
|
adb.pull(wav_path, local_path, serial=serial)
|
|
|
|
|
|
def push_ovsp(adb: Adb, serial: str, local_ovsp: str, ovsp_dir: str,
|
|
voice_id: str) -> str:
|
|
"""Pousse le `.ovsp` dans le dossier voix OmniVoice de la tablette. Renvoie le
|
|
chemin device. Crée le dossier au besoin."""
|
|
adb.shell(f"mkdir -p {ovsp_dir}", serial=serial)
|
|
remote = posixpath.join(ovsp_dir, f"{voice_id}.ovsp")
|
|
adb.push(local_ovsp, remote, serial=serial)
|
|
return remote
|
|
|
|
|
|
def delete_device_wav(adb: Adb, serial: str, wav_path: str) -> None:
|
|
"""Supprime le WAV d'origine de la tablette (après archivage côté PC).
|
|
Vérifie le retour : `rm` adb échoue silencieusement (§9)."""
|
|
out = adb.shell(f"rm -f {wav_path} && echo OK || echo FAIL", serial=serial)
|
|
if "OK" not in out:
|
|
raise AdbError(f"suppression WAV échouée: {wav_path} ({out.strip()})")
|