File size: 2,597 Bytes
af4851b
 
 
 
cd0ff97
 
af4851b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
cd0ff97
 
 
af4851b
 
 
 
cd0ff97
 
 
af4851b
 
 
 
 
cd0ff97
 
af4851b
 
 
 
cd0ff97
 
 
 
 
af4851b
 
cd0ff97
 
 
 
 
 
 
 
 
 
 
 
 
 
af4851b
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
from dataclasses import asdict, dataclass, field
from pathlib import Path
from typing import Any, Dict, List, Optional

from backend.synthesis_catalog import LOCAL_BACKEND, OMNIVOICE_MODEL


JsonDict = Dict[str, Any]


@dataclass
class Chapter:
    id: str
    label: str
    title: str
    text: str
    chars: int
    est_minutes: int
    included: bool = True
    start_seconds: int = 0

    def to_dict(self) -> JsonDict:
        data = asdict(self)
        data["n"] = data["label"]
        return data


@dataclass
class SessionRecord:
    session_id: str
    root: Path
    created_at: float
    touched_at: float


@dataclass
class VoiceConfig:
    mode: str = "auto"
    model: str = OMNIVOICE_MODEL
    backend: str = LOCAL_BACKEND
    narrator_id: Optional[str] = None
    sample_path: Optional[str] = None
    reference_text: Optional[str] = None
    design_prompt: Optional[str] = None
    speaker: Optional[str] = None
    language: Optional[str] = None
    apply_text_normalization: bool = False

    @classmethod
    def from_dict(cls, data: JsonDict) -> "VoiceConfig":
        return cls(
            mode=data.get("mode", "auto"),
            model=data.get("model", OMNIVOICE_MODEL),
            backend=data.get("backend", LOCAL_BACKEND),
            narrator_id=data.get("narratorId") or data.get("narrator_id"),
            sample_path=data.get("samplePath") or data.get("sample_path"),
            reference_text=data.get("referenceText") or data.get("reference_text"),
            design_prompt=data.get("designPrompt") or data.get("design_prompt"),
            speaker=data.get("speaker"),
            language=data.get("language"),
            apply_text_normalization=bool(
                data.get("applyTextNormalization", data.get("apply_text_normalization", False))
            ),
        )

    def to_dict(self) -> JsonDict:
        return {
            "mode": self.mode,
            "model": self.model,
            "backend": self.backend,
            "narratorId": self.narrator_id,
            "samplePath": self.sample_path,
            "referenceText": self.reference_text,
            "designPrompt": self.design_prompt,
            "speaker": self.speaker,
            "language": self.language,
            "applyTextNormalization": self.apply_text_normalization,
        }


@dataclass
class RenderArtifact:
    path: Path
    duration_seconds: int
    chapter_id: str


@dataclass
class RenderJob:
    session_id: str
    status: str = "idle"
    current_chapter_id: Optional[str] = None
    outputs: List[RenderArtifact] = field(default_factory=list)