Estimate text-to-speech duration using PaddleSpeech command-line tool.
| 252 | |
| 253 | |
| 254 | class PaddlespeechTTSDurationEstimator: |
| 255 | """Estimate text-to-speech duration using PaddleSpeech command-line tool.""" |
| 256 | |
| 257 | def __init__( |
| 258 | self, |
| 259 | binary: str, |
| 260 | model_name: str, |
| 261 | sample_rate: int, |
| 262 | device: str, |
| 263 | temp_dir: str, |
| 264 | speaker_id: Optional[int] = None, |
| 265 | ffprobe_bin: str = "ffprobe", |
| 266 | cleanup: bool = True, |
| 267 | extra_env: Optional[Dict[str, str]] = None, |
| 268 | ) -> None: |
| 269 | self.binary = binary |
| 270 | self.model_name = model_name |
| 271 | self.sample_rate = sample_rate |
| 272 | self.device = device |
| 273 | self.temp_dir = resolve_path(temp_dir) |
| 274 | self.speaker_id = speaker_id |
| 275 | self.ffprobe_bin = ffprobe_bin |
| 276 | self.cleanup = cleanup |
| 277 | self.extra_env = extra_env or {} |
| 278 | self._lock = threading.Lock() |
| 279 | self._counter = 0 |
| 280 | os.makedirs(self.temp_dir, exist_ok=True) |
| 281 | |
| 282 | def estimate_seconds(self, text: str) -> float: |
| 283 | content = text.strip() |
| 284 | if not content: |
| 285 | return 0.0 |
| 286 | |
| 287 | with self._lock: |
| 288 | self._counter += 1 |
| 289 | index = self._counter |
| 290 | |
| 291 | segment_dir = os.path.join(self.temp_dir, f"seg_{index:04d}") |
| 292 | os.makedirs(segment_dir, exist_ok=True) |
| 293 | wav_path = os.path.join(segment_dir, "speech.wav") |
| 294 | |
| 295 | cmd: List[str] = [ |
| 296 | self.binary, |
| 297 | "tts", |
| 298 | "--input", |
| 299 | content, |
| 300 | "--output", |
| 301 | wav_path, |
| 302 | "--am", |
| 303 | self.model_name, |
| 304 | "--device", |
| 305 | self.device, |
| 306 | "--sr", |
| 307 | str(self.sample_rate), |
| 308 | ] |
| 309 | if self.speaker_id is not None: |
| 310 | cmd.extend(["--spk_id", str(self.speaker_id)]) |
| 311 |