pokung commited on
Commit
e848a0c
·
verified ·
1 Parent(s): 8bf93c8

Upload 18 files

Browse files
.gitattributes CHANGED
@@ -56,3 +56,5 @@ examples/original/0x000faf94.wav filter=lfs diff=lfs merge=lfs -text
56
  examples/original/0x0011ce99.wav filter=lfs diff=lfs merge=lfs -text
57
  examples/original/dialogue_1.wav filter=lfs diff=lfs merge=lfs -text
58
  examples/original/dialogue_9.wav filter=lfs diff=lfs merge=lfs -text
 
 
 
56
  examples/original/0x0011ce99.wav filter=lfs diff=lfs merge=lfs -text
57
  examples/original/dialogue_1.wav filter=lfs diff=lfs merge=lfs -text
58
  examples/original/dialogue_9.wav filter=lfs diff=lfs merge=lfs -text
59
+ assets/G13_DUBAI.pdf filter=lfs diff=lfs merge=lfs -text
60
+ assets/G13_DUBAI.pptx filter=lfs diff=lfs merge=lfs -text
assets/DubAI.png ADDED
assets/G13_DUBAI.pdf ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:232fa26f926ed888eb48f7bd62a32c3af77c02f96a90da38ceaf6afb99fd96a5
3
+ size 1192603
assets/G13_DUBAI.pptx ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:ce44e49d8e6f9afb7a02036480bb19b61f9139dab90c256baa86c12f17dd5ccc
3
+ size 12509463
assets/nmos.png ADDED
assets/schema.png CHANGED
assets/smos.png ADDED
src/content/about_tab.py CHANGED
@@ -1,4 +1,5 @@
1
  import gradio as gr
 
2
 
3
  def about_tab():
4
  with gr.TabItem("ℹ️ O projekcie"):
@@ -21,6 +22,33 @@ def about_tab():
21
  gr.HTML("""
22
  <div style="font-size: 18px; font-family: Myriad, sans-serif;">
23
  Aby osiągnąć nasz cel, opracowaliśmy modularną architekturę systemu umożliwiającego generowanie dubbingu z użyciem nowoczesnych modeli AI. Cały proces został podzielony na trzy główne etapy: przetwarzanie wstępne, tłumaczenie oraz generowanie dźwięku. Każdy z tych komponentów działa niezależnie, co pozwala na łatwą modyfikację lub wymianę modelu na bardziej zaawansowany bez konieczności przebudowy całego potoku przetwarzania.
 
 
 
 
 
 
 
 
24
  </div>
25
  """)
26
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import gradio as gr
2
+ from src.utils import get_base64_image
3
 
4
  def about_tab():
5
  with gr.TabItem("ℹ️ O projekcie"):
 
22
  gr.HTML("""
23
  <div style="font-size: 18px; font-family: Myriad, sans-serif;">
24
  Aby osiągnąć nasz cel, opracowaliśmy modularną architekturę systemu umożliwiającego generowanie dubbingu z użyciem nowoczesnych modeli AI. Cały proces został podzielony na trzy główne etapy: przetwarzanie wstępne, tłumaczenie oraz generowanie dźwięku. Każdy z tych komponentów działa niezależnie, co pozwala na łatwą modyfikację lub wymianę modelu na bardziej zaawansowany bez konieczności przebudowy całego potoku przetwarzania.
25
+ <br><br>
26
+ Proces rozpoczęto od oczyszczenia nagrań z zakłóceń tła przy użyciu modelu Demucs, który umożliwił skuteczne wydzielenie sygnału mowy. Następnie zastosowano Mossformer2 do separacji mówców, co pozwoliło rozdzielić wypowiedzi różnych osób w nagraniu. Transkrypcja i segmentacja audio zostały przeprowadzone za pomocą modelu Whisper, znanego z wysokiej jakości rozpoznawania mowy. Otrzymane wypowiedzi pogrupowano przy użyciu algorytmu DBSCAN, co ułatwiło identyfikację spójnych segmentów konwersacyjnych.
27
+ <br><br>
28
+ Do tłumaczenia wykorzystano polski wielojęzyczny model językowy Bielik, który efektywnie przekłada teksty zachowując ich znaczenie. Unikalnym aspektem naszego podejścia jest uwzględnianie kontekstu w postaci sąsiadujących fragmentów dialogu — zarówno wypowiedzi poprzedzających, jak i następujących po tłumaczonym fragmencie. Jakość tłumaczeń jest oceniana automatycznie za pomocą metryk takich jak COMET, BERTScore i BLEU, które zapewniają obiektywną ocenę pod kątem zgodności semantycznej oraz płynności tłumaczonego tekstu.
29
+ <br><br>
30
+ Syntezę mowy zrealizowano przy użyciu modelu XTTS-v2, obsługującego 17 języków i umożliwiającego generowanie naturalnego głosu na podstawie jedynie 6-sekundowego nagrania referencyjnego. Został on wybrany ze względu na dobrą jakość dźwięku, szybkość działania oraz lepszą kompatybilność z językiem polskim niż inne dostępne modele. Na końcu przeprowadzono subiektywną ocenę końcowego dźwięku w formie testów odsłuchowych.
31
+ <br><br>
32
+ Na poniższym schemacie przedstawiono szczegółowy przebieg procesu.
33
  </div>
34
  """)
35
 
36
+ img_data = get_base64_image("assets/schema.png")
37
+ schema_html = f"""
38
+ <div style="display: flex; justify-content: center; padding: 20px;">
39
+ <img src="{img_data}"
40
+ style="
41
+ width: 100%;
42
+ max-width: 1000px;
43
+ border: none;
44
+ object-fit: contain;
45
+ "
46
+ alt="Schemat procesu"
47
+ />
48
+ </div>
49
+ """
50
+ gr.HTML(schema_html)
51
+ gr.HTML('<div style="text-align: center; font-size: 18px; font-family: Myriad, sans-serif;">Przebieg procesu przetwarzania nagrania.</div>')
52
+
53
+
54
+
src/content/about_us_tab.py CHANGED
@@ -13,9 +13,10 @@ def about_us_tab():
13
  W skład zespołu wchodzą: Natalia Iwańska, Klaudia Janicka, Wiktor Jeżowski, Kajetan Kołodziejczyk oraz Michał Wiktorowski.
14
  <br>
15
  Opiekunami projektu są dr hab. inż. Maciej Piasecki oraz dr inż. Piotr Syga.
16
- </div>
17
  """)
18
 
 
19
  gr.HTML('<div style="font-size: 35px; font-family: Myriad, sans-serif; font-weight: bold; text-align: left;">📩 Kontakt</div>')
20
 
21
  gr.HTML("""
 
13
  W skład zespołu wchodzą: Natalia Iwańska, Klaudia Janicka, Wiktor Jeżowski, Kajetan Kołodziejczyk oraz Michał Wiktorowski.
14
  <br>
15
  Opiekunami projektu są dr hab. inż. Maciej Piasecki oraz dr inż. Piotr Syga.
16
+ </div><br>
17
  """)
18
 
19
+
20
  gr.HTML('<div style="font-size: 35px; font-family: Myriad, sans-serif; font-weight: bold; text-align: left;">📩 Kontakt</div>')
21
 
22
  gr.HTML("""
src/content/front_image.py CHANGED
@@ -4,26 +4,23 @@ from src.utils import get_base64_image
4
  def image_tab():
5
  gr.HTML("""
6
  <style>
7
- .full-width-img-container {
8
- width: 100%;
9
- overflow: hidden;
10
- margin: 0;
11
- padding: 0;
12
  }
13
- .full-width-img {
14
- width: 100%;
15
- height: auto;
16
- display: block;
17
  }
18
  </style>
19
  """)
20
-
21
- img_data = get_base64_image("assets/logo.png")
22
  logo_html = f"""
23
- <div class="full-width-img-container">
24
  <img src="{img_data}"
25
- class="full-width-img"
26
  alt="Logo" />
27
  </div>
28
  """
29
- gr.HTML(logo_html)
 
4
  def image_tab():
5
  gr.HTML("""
6
  <style>
7
+ .scaled-img-container {
8
+ display: flex;
9
+ justify-content: center;
10
+ padding: 0.1em 0;
 
11
  }
12
+ .scaled-img {
13
+ transform-origin: top center;
 
 
14
  }
15
  </style>
16
  """)
17
+
18
+ img_data = get_base64_image("assets/DubAI.png")
19
  logo_html = f"""
20
+ <div class="scaled-img-container">
21
  <img src="{img_data}"
22
+ class="scaled-img"
23
  alt="Logo" />
24
  </div>
25
  """
26
+ gr.HTML(logo_html)
src/content/others_tab.py ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+
3
+
4
+
5
+ def pdf_tab():
6
+ with gr.Tab("📂 Inne"):
7
+ with gr.Column():
8
+ gr.HTML('<div style="font-size: 35px; font-family: Myriad, sans-serif; font-weight: bold; text-align: left;">📂 Inne</div>')
9
+ gr.HTML("""
10
+ <div style="font-size: 18px; font-family: Myriad, sans-serif;">
11
+ Chciałbyś dowiedzieć się więcej? Poniżej znajdują się dodatkowe pliki związane z projektem, które udostępniamy do pobrania.
12
+ <br><br>
13
+ </div>
14
+ """)
15
+ gr.File(value="assets/G13_DUBAI.pdf", label="🖼️ Plakat", interactive=True)
16
+ gr.File(value="assets/G13_DUBAI.pptx", label="📈 Prezentacja", interactive=True)
17
+
src/content/results_tab.py CHANGED
@@ -1,5 +1,6 @@
1
  import gradio as gr
2
  from pathlib import Path
 
3
 
4
 
5
  def get_files(dir_name):
@@ -14,6 +15,11 @@ def results_tab():
14
  with gr.Tab("📊 Wyniki"):
15
  with gr.Column(elem_classes="results-tab"):
16
  gr.HTML('<div style="font-size: 35px; font-family: Myriad, sans-serif; font-weight: bold; text-align: left;">🎵 Przykłady dubbingu</div>')
 
 
 
 
 
17
  with gr.Row():
18
  gr.HTML('<div style="font-size: 20px; font-family: Myriad, sans-serif; font-weight: bold; text-align: center;">Oryginalne nagranie</div>')
19
  gr.HTML('<div style="font-size: 20px; font-family: Myriad, sans-serif; font-weight: bold; text-align: center;">Wygenerowany dubbing</div>')
@@ -26,7 +32,14 @@ def results_tab():
26
 
27
  gr.HTML('<br><br>')
28
 
29
- gr.HTML('<div style="font-size: 35px; font-family: Myriad, sans-serif; font-weight: bold; text-align: left;">Przykłady wpływu kontekstu na tłumaczenie</div>')
 
 
 
 
 
 
 
30
  gr.HTML("""
31
  <div style="display:flex; gap:20px; flex-wrap: wrap; color:#000;">
32
 
@@ -34,9 +47,9 @@ def results_tab():
34
  <h3 style="color:#000;">Przykład 1</h3>
35
  <b>Dialog:</b><br>
36
  <div style="background-color:#e0e0e0; border-radius:10px; padding:10px; margin-top:5px; margin-bottom:10px; color:#000;">
37
- Troll - Ick metal. Mouth stings.<br>
38
- Lambert - <b style="color:black;">You nuts?!</b><br>
39
- Geralt - Shut up and follow my lead.
40
  </div>
41
  <b style="color:black;">Oryginalne:</b> Zwariowałeś?! ⭐<br>
42
  <b style="color:black;">Bez kontekstu:</b> Ty orzeszku?! <span>❌</span><br>
@@ -47,16 +60,116 @@ def results_tab():
47
  <h3 style="color:#000;">Przykład 2</h3>
48
  <b>Dialog:</b><br>
49
  <div style="background-color:#e0e0e0; border-radius:10px; padding:10px; margin-top:5px; margin-bottom:10px; color:#000;">
50
- Yennefer - Philippa, your eyesight, only just recovered and magically simulated. Didn’t you say you’d need some time to get accustomed?<br>
51
- Philippa Eilhart - <b style="color:black;">Did I?</b><br>
52
- Yennefer - I’d forgotten how irritating she can be. Come, Ciri.
53
  </div>
54
  <b style="color:black;">Oryginalne:</b> Tak mówiłam? ⭐<br>
55
  <b style="color:black;">Bez kontekstu:</b> Czy ja? <span style="color:black;">❌</span><br>
56
  <b style="color:black;">Z kontekstem:</b> <b style="color:black;">Czy ja tak powiedziałam?</b> ✅
57
  </div>
58
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
  """)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
 
62
 
 
1
  import gradio as gr
2
  from pathlib import Path
3
+ from src.utils import get_base64_image
4
 
5
 
6
  def get_files(dir_name):
 
15
  with gr.Tab("📊 Wyniki"):
16
  with gr.Column(elem_classes="results-tab"):
17
  gr.HTML('<div style="font-size: 35px; font-family: Myriad, sans-serif; font-weight: bold; text-align: left;">🎵 Przykłady dubbingu</div>')
18
+ gr.HTML("""
19
+ <div style="font-size: 18px; font-family: Myriad, sans-serif;">
20
+ Poniżej przedstawiamy efekty naszego rozwiązania — przykładowe pary nagrań oryginalnych i wygenerowanych. Wśród nich znajdują się zarówno nagrania pojedyńczych wypowiedzi, jak i rozbudowane dialogi z muzyką w tle. Poszczególne wypowiedzi można odsłuchać, klikając na przycisk uruchamiający odtwarzacz audio.
21
+ </div>
22
+ """)
23
  with gr.Row():
24
  gr.HTML('<div style="font-size: 20px; font-family: Myriad, sans-serif; font-weight: bold; text-align: center;">Oryginalne nagranie</div>')
25
  gr.HTML('<div style="font-size: 20px; font-family: Myriad, sans-serif; font-weight: bold; text-align: center;">Wygenerowany dubbing</div>')
 
32
 
33
  gr.HTML('<br><br>')
34
 
35
+ # WPŁYW KONTEKSTU NA TŁUMACZENIE
36
+
37
+ gr.HTML('<div style="font-size: 35px; font-family: Myriad, sans-serif; font-weight: bold; text-align: left;">🈲 Przykłady wpływu kontekstu na tłumaczenie</div>')
38
+ gr.HTML("""
39
+ <div style="font-size: 18px; font-family: Myriad, sans-serif;">
40
+ Poniżej prezentujemy przykłady tłumaczeń wykonanych bez kontekstu oraz z uwzględnieniem kontekstu wypowiedzi. Zestawienie to ma na celu zilustrowanie, jak istotny wpływ na jakość i poprawność tłumaczenia może mieć kontekst w postaci wypowiedzi poprzedzającej i następującej po tłumaczonym fragmencie. Dzięki temu można zaobserwować różnice w interpretacji znaczenia, doborze słownictwa oraz płynności przekładu w zależności od dostępnych informacji kontekstowych.
41
+ </div>
42
+ """)
43
  gr.HTML("""
44
  <div style="display:flex; gap:20px; flex-wrap: wrap; color:#000;">
45
 
 
47
  <h3 style="color:#000;">Przykład 1</h3>
48
  <b>Dialog:</b><br>
49
  <div style="background-color:#e0e0e0; border-radius:10px; padding:10px; margin-top:5px; margin-bottom:10px; color:#000;">
50
+ Troll &mdash; Ick metal. Mouth stings.<br>
51
+ Lambert &mdash; <b style="color:black;">You nuts?!</b><br>
52
+ Geralt &mdash; Shut up and follow my lead.
53
  </div>
54
  <b style="color:black;">Oryginalne:</b> Zwariowałeś?! ⭐<br>
55
  <b style="color:black;">Bez kontekstu:</b> Ty orzeszku?! <span>❌</span><br>
 
60
  <h3 style="color:#000;">Przykład 2</h3>
61
  <b>Dialog:</b><br>
62
  <div style="background-color:#e0e0e0; border-radius:10px; padding:10px; margin-top:5px; margin-bottom:10px; color:#000;">
63
+ Yennefer &mdash; Philippa, your eyesight, only just recovered and magically simulated. Didn’t you say you’d need some time to get accustomed?<br>
64
+ Philippa Eilhart &mdash; <b style="color:black;">Did I?</b><br>
65
+ Yennefer &mdash; I’d forgotten how irritating she can be. Come, Ciri.
66
  </div>
67
  <b style="color:black;">Oryginalne:</b> Tak mówiłam? ⭐<br>
68
  <b style="color:black;">Bez kontekstu:</b> Czy ja? <span style="color:black;">❌</span><br>
69
  <b style="color:black;">Z kontekstem:</b> <b style="color:black;">Czy ja tak powiedziałam?</b> ✅
70
  </div>
71
  </div>
72
+
73
+ <br>
74
+
75
+ <div style="display:flex; gap:20px; flex-wrap: wrap; color:#000;">
76
+ <div style="flex:2; background-color:#f5f5f5; color:#000; border:2px solid black; border-radius:20px; padding:15px; min-width:300px;">
77
+ <h3 style="color:#000;">Przykład 3</h3>
78
+ <b>Dialog:</b><br>
79
+ <div style="background-color:#e0e0e0; border-radius:10px; padding:10px; margin-top:5px; margin-bottom:10px; color:#000;">
80
+ Chamberlain Emhyr &mdash; Bow before His Imperial Majesty, The White Flame Dancing on the Graves of his Foes, Emhyr var Emreis!<br>
81
+ Chamberlain Emhyr &mdash; <b style="color:black;">Bow.</b><br>
82
+ Emhyr &mdash; I thought you bowed before no man.<br>
83
+ </div>
84
+ <b style="color:black;">Oryginalne:</b> Ukłon. ⭐<br>
85
+ <b style="color:black;">Bez kontekstu:</b> Łuk. <span>❌</span><br>
86
+ <b style="color:black;">Z kontekstem:</b> <b style="color:black;">Ukłon.</b> ✅
87
+ </div>
88
+
89
+ <div style="flex:2; background-color:#f5f5f5; color:#000; border:2px solid black; border-radius:20px; padding:15px; min-width:300px;">
90
+ <h3 style="color:#000;">Przykład 4</h3>
91
+ <b>Dialog:</b><br>
92
+ <div style="background-color:#e0e0e0; border-radius:10px; padding:10px; margin-top:5px; margin-bottom:10px; color:#000;">
93
+ Keira Metz &mdash; Find him immediately. We’re close to unraveling this, I can feel it.<br>
94
+ Keira Metz &mdash; <b style="color:black;">What was that? It sounded for a moment like you’d joined the wraiths yourself...</b><br>
95
+ Geralt &mdash; Had to fight a pesta.<br>
96
+ </div>
97
+ <b style="color:black;">Oryginalne:</b> Co to było? Brzmiało, jakbyś postanowił dołączyć do drużyny upiorów... ⭐<br>
98
+ <b style="color:black;">Bez kontekstu:</b> Co to było? Brzmiało przez chwilę, jakbyś dołączył do cieni sam <span>❌</span><br>
99
+ <b style="color:black;">Z kontekstem:</b> <b style="color:black;">Co to było? Na chwilę brzmiało to tak, jakbyś sam dołączył do upiorów...</b> ✅
100
+ </div>
101
+ </div>
102
  """)
103
+
104
+ gr.HTML('<br><br>')
105
+
106
+ # MOS
107
+ gr.HTML('<div style="font-size: 35px; font-family: Myriad, sans-serif; font-weight: bold; text-align: left;">📋 Test MOS')
108
+ gr.HTML("""
109
+ <div style="font-size: 18px; font-family: Myriad, sans-serif;">
110
+ Jednym z najważniejszych wyznaczników jakości mowy syntetycznej jest opinia drugiego człowieka. W tym celu przeprowadziliśmy test MOS (ang. <i>Mean Opinion Score</i>), który polega na subiektywnej ocenie jakości dźwięku przez słuchaczy. W badaniu wzięło udział 63 uczestników, którzy mieli za zadanie wysłuchać fragmentów nagrań i ocenić je w skali od 1 do 5, gdzie 1 oznaczało bardzo niską jakość, a 5 bardzo wysoką. Sprawdzona została zarówno naturalność wygenerowanego dźwięku (nMOS), jak i jakość transferu cech mowy (sMOS).
111
+ <br><br>
112
+ W <a href="#mosTable">tabeli</a> przedstawiamy średnie wyniki testów nMOS i sMOS, zarówno dla tłumaczenia z języka angielskiego na polski, jak i odwrotnie. Rezultaty są w obu przypadkach na wysokim poziomie, aczkolwiek nieco gorsze wyniki uzyskano dla syntezy z języka angielskiego na polski. Wynika to głównie ze złożoności fleksyjnej języka polskiego oraz znacznie mniejszego wsparcia modeli dla tego języka. Na <a href="#nmos">wykresach</a> przedstawiono szczegółowy rozkład ocen dla nMOS i sMOS.
113
+ </div>
114
+ <br><br>
115
+ <table id="mosTable" style="margin: 0 auto; border-collapse: collapse; max-width: 600px; width: 100%; font-size: 20px;">
116
+ <thead>
117
+ <tr style="border-bottom: 2px solid #000;">
118
+ <th style="padding: 10px;"></th>
119
+ <th style="padding: 10px;"><strong>EN &rarr; PL</strong></th>
120
+ <th style="padding: 10px;"><strong>PL &rarr; EN</strong></th>
121
+ </tr>
122
+ </thead>
123
+ <tbody>
124
+ <tr style="border-bottom: 1px solid #ccc;">
125
+ <td style="padding: 10px;"><strong>nMOS</strong></td>
126
+ <td style="padding: 10px;">4,02</td>
127
+ <td style="padding: 10px;">4,38</td>
128
+ </tr>
129
+ <tr>
130
+ <td style="padding: 10px;"><strong>sMOS</strong></td>
131
+ <td style="padding: 10px;">4,08</td>
132
+ <td style="padding: 10px;">4,51</td>
133
+ </tr>
134
+ </tbody>
135
+ </table>
136
+ <div style="text-align: center; font-size: 16px; font-family: Myriad, sans-serif; margin-top: 8px;">
137
+ Średnie wyniki testu MOS.
138
+ </div>
139
+ <style>
140
+ table tbody tr:hover {
141
+ background-color: #f0f0f0;
142
+ }
143
+ </style>
144
+ """)
145
+
146
+ gr.HTML("""
147
+ <style>
148
+ .scaled-img-container {
149
+ display: flex;
150
+ justify-content: center;
151
+ padding: 0.1em 0;
152
+ }
153
+ .scaled-img {
154
+ transform-origin: top center;
155
+ }
156
+ </style>
157
+ """)
158
 
159
+ img_nmos = get_base64_image("assets/nmos.png")
160
+ img_smos = get_base64_image("assets/smos.png")
161
+ imgs_with_labels = f"""
162
+ <div style="display: flex; justify-content: center; gap: 40px; flex-wrap: wrap; text-align: center;">
163
+ <div>
164
+ <img id="nmos" src="{img_nmos}" class="scaled-img" alt="nmos" style="max-width: 100%; height: auto;" />
165
+ <div style="margin-top: 10px; font-size: 16px; font-family: Myriad, sans-serif;">Wyniki testu nMOS.</div>
166
+ </div>
167
+ <div>
168
+ <img id="smos" src="{img_smos}" class="scaled-img" alt="smos" style="max-width: 100%; height: auto;" />
169
+ <div style="margin-top: 10px; font-size: 16px; font-family: Myriad, sans-serif;">Wyniki testu sMOS.</div>
170
+ </div>
171
+ </div>
172
+ """
173
+ gr.HTML(imgs_with_labels)
174
 
175
 
src/models/translation.py CHANGED
@@ -18,7 +18,7 @@ class TranslationService:
18
  self,
19
  text: str,
20
  source_lang: str = "PL",
21
- target_lang: str = "EN"
22
  ) -> str:
23
  """Tłumaczenie tekstu"""
24
  result = self.translator.translate_text(
@@ -26,7 +26,7 @@ class TranslationService:
26
  source_lang=source_lang,
27
  target_lang=target_lang
28
  )
29
- return result.text
30
 
31
  # Singleton pattern
32
  TRANSLATOR = TranslationService()
 
18
  self,
19
  text: str,
20
  source_lang: str = "PL",
21
+ target_lang: str = "EN-US"
22
  ) -> str:
23
  """Tłumaczenie tekstu"""
24
  result = self.translator.translate_text(
 
26
  source_lang=source_lang,
27
  target_lang=target_lang
28
  )
29
+ return result.text.replace(".", ",")
30
 
31
  # Singleton pattern
32
  TRANSLATOR = TranslationService()