Marek4321 commited on
Commit
4e0f139
·
verified ·
1 Parent(s): 94d0333

Update core/audio_gen.py

Browse files
Files changed (1) hide show
  1. core/audio_gen.py +139 -0
core/audio_gen.py CHANGED
@@ -0,0 +1,139 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # @title core/audio_gen.py
2
+ import os
3
+ import json
4
+ import httpx
5
+ from pathlib import Path
6
+ from typing import Dict, Any, Optional, Tuple
7
+ from utils.logger import SpotMakerLogger
8
+
9
+ class AudioGenerator:
10
+ """
11
+ Generator ścieżki audio dla głosu lektora używając Hailuo T2A API.
12
+ """
13
+ def __init__(self, api_key: str, group_id: str, output_dir: str, logger: SpotMakerLogger):
14
+ self.api_key = api_key
15
+ self.group_id = group_id
16
+ self.logger = logger
17
+ self.output_dir = Path(output_dir)
18
+ self.output_dir.mkdir(parents=True, exist_ok=True)
19
+
20
+ # Konfiguracja API
21
+ self.base_url = "https://api.minimaxi.chat/v1/t2a_v2"
22
+ self.model = "speech-01-hd"
23
+
24
+ async def generate_voice_over(self, text: str) -> Tuple[str, float]:
25
+ """
26
+ Generuje ścieżkę dźwiękową dla tekstu lektora.
27
+
28
+ Args:
29
+ text: Tekst do przeczytania przez lektora
30
+
31
+ Returns:
32
+ Tuple[str, float]: Ścieżka do pliku audio i jego długość w sekundach
33
+ """
34
+ try:
35
+ self.logger.log("audio_gen", "Rozpoczynam generowanie audio", "info")
36
+ self.logger.update_progress("audio_gen", 10, "Przygotowuję tekst...")
37
+
38
+ # Konstruowanie URL z GroupId
39
+ url = f"{self.base_url}?GroupId={self.group_id}"
40
+
41
+ # Przygotuj dane dla API zgodnie z dokumentacją
42
+ headers = {
43
+ "Content-Type": "application/json",
44
+ "Authorization": f"Bearer {self.api_key}",
45
+ "accept": "application/json, text/plain, */*"
46
+ }
47
+
48
+ data = {
49
+ "model": self.model,
50
+ "text": text,
51
+ "stream": False,
52
+ "subtitle_enable": True,
53
+ "voice_setting": {
54
+ "voice_id": "male-qn-qingse",
55
+ "speed": 1.0,
56
+ "vol": 1.0,
57
+ "pitch": 0
58
+ },
59
+ "audio_setting": {
60
+ "sample_rate": 32000,
61
+ "bitrate": 128000,
62
+ "format": "mp3",
63
+ "channel": 1
64
+ }
65
+ }
66
+
67
+ # Log request details
68
+ self.logger.log("audio_gen",
69
+ f"Wysyłam zapytanie do: {url}\nDane: {json.dumps(data, indent=2)}",
70
+ "debug")
71
+
72
+ self.logger.update_progress("audio_gen", 30, "Generuję audio...")
73
+
74
+ # Wywołaj API
75
+ async with httpx.AsyncClient() as client:
76
+ response = await client.post(
77
+ url,
78
+ headers=headers,
79
+ json=data,
80
+ timeout=30.0
81
+ )
82
+
83
+ # Log response
84
+ self.logger.log("audio_gen",
85
+ f"Status odpowiedzi: {response.status_code}",
86
+ "debug")
87
+
88
+ if response.status_code != 200:
89
+ error_msg = f"Błąd API: {response.status_code} - {response.text}"
90
+ self.logger.log("audio_gen", error_msg, "error")
91
+ raise Exception(error_msg)
92
+
93
+ response_data = response.json()
94
+
95
+ # Sprawdź status_code z API
96
+ if response_data.get('base_resp', {}).get('status_code') != 0:
97
+ error_msg = response_data.get('base_resp', {}).get('status_msg', 'Unknown API error')
98
+ raise Exception(f"API error: {error_msg}")
99
+
100
+ self.logger.update_progress("audio_gen", 60, "Przetwarzam odpowiedź...")
101
+
102
+ # Log response data
103
+ self.logger.log("audio_gen",
104
+ f"Otrzymana odpowiedź:\n{json.dumps(response_data, indent=2)}",
105
+ "debug")
106
+
107
+ try:
108
+ # Pobierz audio z odpowiedzi zgodnie z dokumentacją
109
+ audio_data = response_data['data']['audio']
110
+ audio_length = response_data['extra_info']['audio_length'] / 1000.0 # konwersja na sekundy
111
+
112
+ self.logger.log("audio_gen",
113
+ f"Długość audio: {audio_length:.2f}s",
114
+ "info")
115
+
116
+ # Zapisz plik audio
117
+ output_path = self.output_dir / "voice_over.mp3"
118
+ with open(output_path, 'wb') as f:
119
+ f.write(bytes.fromhex(audio_data))
120
+
121
+ self.logger.update_progress("audio_gen", 100, "Zakończono generowanie audio")
122
+
123
+ return str(output_path), audio_length
124
+
125
+ except KeyError as e:
126
+ error_msg = f"Błąd w strukturze odpowiedzi: {str(e)}"
127
+ self.logger.log("audio_gen", error_msg, "error")
128
+ raise Exception(error_msg)
129
+
130
+ except Exception as e:
131
+ self.logger.format_error("audio_gen", e)
132
+ raise
133
+
134
+ def get_status(self) -> Dict[str, Any]:
135
+ """Zwraca aktualny status generatora."""
136
+ return {
137
+ 'progress': self.logger.get_module_progress("audio_gen"),
138
+ 'status': self.logger.get_module_status("audio_gen")
139
+ }