@@ -68,6 +68,7 @@ bool Audio::connect_local_tts(const String& host, int port, const String& path,
6868And this can be used with a simple Python Server running locally :
6969```py
7070from flask import Flask, request, send_file, jsonify, after_this_request
71+ from flask_cors import CORS
7172import pyttsx3
7273import uuid
7374import os
@@ -76,6 +77,7 @@ import asyncio
7677import edge_tts
7778
7879app = Flask(__name__)
80+ CORS(app)
7981
8082# Load available pyttsx3 voices
8183engine = pyttsx3.init()
@@ -198,4 +200,122 @@ def edge_tts_route():
198200if __name__ == '__main__':
199201 app.run(host='0.0.0.0', port=5000)
200202
201- ```
203+ ```
204+ Installation instructions for the Python TTS Server:
205+ Create an empty folder
206+ Create an empty file in this folder and call it tts_ws.py
207+ Add the python script into this file
208+ Open a terminal in this folder
209+ Create a new virtual environment
210+ ` python3 -m venv venv `
211+ ` source venv/bin/activate `
212+ It looks like this:
213+ ![ new Folder] ( image.png )
214+ then:
215+ ` pip install pyttsx3 `
216+ ` pip install flask `
217+ ` pip install flask_cors `
218+ ` pip install gTTS `
219+ ` pip install edge_tts `
220+ And then start the server: ` python3 tts_ws.py `
221+ ![ start ws] ( image-1.png )
222+
223+ If necessary, adjust the firewall
224+
225+ A web interface for testing:
226+ ```` html
227+ <!DOCTYPE html>
228+ <html lang =" de" >
229+ <head >
230+ <meta charset =" UTF-8" >
231+ <title >TTS Webinterface</title >
232+ <style >
233+ body {
234+ font-family : Arial , sans-serif ;
235+ max-width : 600px ;
236+ margin : auto ;
237+ padding : 2em ;
238+ }
239+ label , select , input , textarea , button {
240+ display : block ;
241+ width : 100% ;
242+ margin-bottom : 1em ;
243+ }
244+ audio {
245+ width : 100% ;
246+ margin-top : 1em ;
247+ }
248+ </style >
249+ </head >
250+ <body >
251+ <h2 >Text-to-Speech Webinterface</h2 >
252+
253+ <label for =" text" >Text:</label >
254+ <textarea id =" text" rows =" 4" placeholder =" Gib den Text ein..." ></textarea >
255+
256+ <label for =" method" >TTS-Methode:</label >
257+ <select id =" method" >
258+ <option value =" tts" >pyttsx3 (offline)</option >
259+ <option value =" gtts" >gTTS (Google)</option >
260+ <option value =" edge_tts" >Edge TTS (Microsoft Neural)</option >
261+ </select >
262+
263+ <label for =" voice" >Stimme (optional):</label >
264+ <input id =" voice" placeholder =" z. B. de-DE-KatjaNeural" >
265+
266+ <label for =" rate" >Sprechgeschwindigkeit (optional):</label >
267+ <input id =" rate" placeholder =" z. B. 150 oder 0%" >
268+
269+ <label for =" pitch" >Tonhöhe (nur Edge, optional):</label >
270+ <input id =" pitch" placeholder =" z. B. +10%" >
271+
272+ <button onclick =" sendTTS()" >Senden & Abspielen</button >
273+
274+ <audio id =" audio" controls ></audio >
275+
276+ <script >
277+ async function sendTTS () {
278+ const text = document .getElementById (" text" ).value ;
279+ const method = document .getElementById (" method" ).value ;
280+ const voice = document .getElementById (" voice" ).value ;
281+ const rate = document .getElementById (" rate" ).value ;
282+ const pitch = document .getElementById (" pitch" ).value ;
283+
284+ const url = ` http://192.168.178.20:5000/${ method} ` ;
285+
286+ const data = { text };
287+ if (voice) data .voice = voice;
288+ if (rate) data .rate = method === " edge_tts" ? rate + " %" : parseInt (rate);
289+ if (pitch && method === " edge_tts" ) data .pitch = pitch;
290+
291+ try {
292+ const response = await fetch (url, {
293+ method: " POST" ,
294+ headers: { " Content-Type" : " application/json" },
295+ body: JSON .stringify (data)
296+ });
297+
298+ if (! response .ok ) {
299+ const error = await response .json ();
300+ alert (" Fehler: " + error .error );
301+ return ;
302+ }
303+
304+ const blob = await response .blob ();
305+ const audioURL = URL .createObjectURL (blob);
306+
307+ const audio = document .getElementById (" audio" );
308+ audio .src = audioURL;
309+ audio .play ();
310+
311+ } catch (err) {
312+ alert (" Verbindungsfehler: " + err .message );
313+ }
314+ }
315+ </script >
316+ </body >
317+ </html >
318+
319+ ````
320+
321+ ![ web interface] ( image-2.png )
0 commit comments