Thorsten-Voice commited on
Commit
8b53cc6
1 Parent(s): 61f89f6

Initial commit

Browse files
Files changed (2) hide show
  1. app.py +166 -0
  2. requirements.txt +2 -0
app.py ADDED
@@ -0,0 +1,166 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import subprocess
3
+ import tempfile
4
+ import sys
5
+ import os
6
+ from os.path import exists
7
+ import requests
8
+ import tarfile
9
+ from PIL import Image
10
+
11
+ # Set base path
12
+ BASE_PATH = os.getcwd() # /home/user/app
13
+ BASE_PATH_MODEL = os.path.join(BASE_PATH, "Model")
14
+
15
+ # Piper TTS download url
16
+ URL_PIPER_DOWNLOAD = "https://github.com/rhasspy/piper/releases/download/v1.2.0/piper_amd64.tar.gz"
17
+
18
+ # Thorsten-Voice TTS model files
19
+ URL_TV_HOCHDEUTSCH_ONNX = "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/de/de_DE/thorsten/high/de_DE-thorsten-high.onnx"
20
+ URL_TV_EMOTIONAL_ONNX = "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/de/de_DE/thorsten_emotional/medium/de_DE-thorsten_emotional-medium.onnx"
21
+ URL_TV_HESSISCH_ONNX = "https://huggingface.co/Thorsten-Voice/Hessisch/resolve/main/Thorsten-Voice_Hessisch_Piper_high-Oct2023.onnx"
22
+
23
+ TMP_PIPER_FILENAME = os.path.join(BASE_PATH, "piper.tgz")
24
+
25
+ ##########################
26
+ # CHECK OR INSTALL PIPER #
27
+ ##########################
28
+ if os.path.exists(os.path.join(BASE_PATH,"piper")) == False:
29
+
30
+ # Piper not downloaded and extracted yet, let's do this first.
31
+ response = requests.get(URL_PIPER_DOWNLOAD)
32
+
33
+ if response.status_code == 200:
34
+ with open(TMP_PIPER_FILENAME, 'wb') as f:
35
+ f.write(response.content)
36
+
37
+ with tarfile.open(TMP_PIPER_FILENAME, 'r:gz') as tar:
38
+ tar.extractall(BASE_PATH)
39
+
40
+ else:
41
+ st.markdown(f"Failed to download Piper TTS from {URL_PIPER_DOWNLOAD} (Status code: {response.status_code})")
42
+
43
+
44
+ #####################################################
45
+ # CHECK OR DOWNLOAD: All Thorsten-Voice model files #
46
+ #####################################################
47
+
48
+ # Create "Model" path if not existing
49
+ if os.path.exists(BASE_PATH_MODEL) == False:
50
+ os.makedirs(BASE_PATH_MODEL)
51
+
52
+ # --- Download "NEUTRAL" TTS model --- #
53
+ response = requests.get(URL_TV_HOCHDEUTSCH_ONNX)
54
+ if response.status_code == 200:
55
+ with open(os.path.join(BASE_PATH_MODEL, "TV-Neutral.onnx"), 'wb') as f:
56
+ f.write(response.content)
57
+
58
+ response = requests.get(URL_TV_HOCHDEUTSCH_ONNX + ".json")
59
+ if response.status_code == 200:
60
+ with open(os.path.join(BASE_PATH_MODEL, "TV-Neutral.onnx.json"), 'wb') as f:
61
+ f.write(response.content)
62
+
63
+
64
+ # --- Download "EMOTIONAL" TTS model --- #
65
+ response = requests.get(URL_TV_EMOTIONAL_ONNX)
66
+ if response.status_code == 200:
67
+ with open(os.path.join(BASE_PATH_MODEL, "TV-Emotional.onnx"), 'wb') as f:
68
+ f.write(response.content)
69
+
70
+ response = requests.get(URL_TV_EMOTIONAL_ONNX + ".json")
71
+ if response.status_code == 200:
72
+ with open(os.path.join(BASE_PATH_MODEL, "TV-Emotional.onnx.json"), 'wb') as f:
73
+ f.write(response.content)
74
+
75
+
76
+ # --- Download "HESSISCH" TTS model --- #
77
+ response = requests.get(URL_TV_HESSISCH_ONNX)
78
+ if response.status_code == 200:
79
+ with open(os.path.join(BASE_PATH_MODEL, "TV-Hessisch.onnx"), 'wb') as f:
80
+ f.write(response.content)
81
+
82
+ response = requests.get(URL_TV_HESSISCH_ONNX + ".json")
83
+ if response.status_code == 200:
84
+ with open(os.path.join(BASE_PATH_MODEL, "TV-Hessisch.onnx.json"), 'wb') as f:
85
+ f.write(response.content)
86
+
87
+
88
+ ###########################
89
+ # MODEL DOWNLOAD FINISHED #
90
+ ###########################
91
+
92
+ hide_streamlit_style = """
93
+ <style>
94
+ #MainMenu {visibility: hidden;}
95
+ header {visibility: hidden;}
96
+ footer {visibility: hidden;}
97
+ .st-emotion-cache-1y4p8pa {padding-top: 0rem;}
98
+ </style>
99
+ """
100
+ st.markdown(hide_streamlit_style, unsafe_allow_html=True)
101
+
102
+ st.title('Guude! 👋')
103
+ st.header('Kostenlose deutsche Sprachausgabe - Dank "Thorsten-Voice"')
104
+
105
+ st.subheader('Wofür?')
106
+ st.markdown('Die künstlichen [Thorsten-Voice](https://www.Thorsten-Voice.de) Stimmen sind für **Voice Over und Social Media Content Creator** mit Youtube Videos/Shorts, Instagram, Tik Tok, ... geeignet.' +
107
+ ' Für eine andere künstliche Sprachausgabe in **Sprachassistenten**,' +
108
+ ' für **Hobby und Bastelprojekte** oder natürlich auch gerne **einfach nur zum Spaß** um witzige **Sprachnachrichten** zu verschicken.')
109
+
110
+ #st.image('Thorsten-Voice_transparent_klein.png')
111
+
112
+ with st.form("my_form"):
113
+ option = st.selectbox(
114
+ 'Wie soll die Stimme klingen?',
115
+ ('Normal', 'Fröhlich', 'Wütend', 'Angewidert', 'Betrunken', 'Schläfrig', 'Flüsternd', 'Hessischer Dialekt'))
116
+
117
+ text = st.text_area("Zu sprechender Text",max_chars=500)
118
+ submitted = st.form_submit_button("Sprechen")
119
+
120
+ if submitted:
121
+ with st.spinner("Bitte einen Augenblick Gedult - bin gleich soweit ..."):
122
+ filename = tempfile.NamedTemporaryFile(suffix=".wav", delete=False)
123
+
124
+ # Set Piper TTS command based on choice
125
+ PIPER_CMD = os.path.join(BASE_PATH,"piper","piper")
126
+ SPEAKER_ID = "0"
127
+
128
+ match option:
129
+ case "Normal":
130
+ MODEL = "TV-Neutral.onnx"
131
+ case "Hessischer Dialekt":
132
+ MODEL = "TV-Hessisch.onnx"
133
+ case "Fröhlich":
134
+ MODEL = "TV-Emotional.onnx"
135
+ SPEAKER_ID = "0"
136
+ case "Wütend":
137
+ MODEL = "TV-Emotional.onnx"
138
+ SPEAKER_ID = "1"
139
+ case "Angewidert":
140
+ MODEL = "TV-Emotional.onnx"
141
+ SPEAKER_ID = "2"
142
+ case "Betrunken":
143
+ MODEL = "TV-Emotional.onnx"
144
+ SPEAKER_ID = "3"
145
+ case "Schläfrig":
146
+ MODEL = "TV-Emotional.onnx"
147
+ SPEAKER_ID = "5"
148
+ case "Flüsternd":
149
+ MODEL = "TV-Emotional.onnx"
150
+ SPEAKER_ID = "7"
151
+
152
+ cmd = "echo '" + text + "' | " + BASE_PATH + "/piper/piper --model " + os.path.join(BASE_PATH_MODEL, MODEL) + " --speaker " + SPEAKER_ID + " --output_file " + filename.name
153
+
154
+ result = subprocess.run(cmd, shell=True)
155
+ audio_file = open(filename.name, 'rb')
156
+ audio_bytes = audio_file.read()
157
+ st.audio(audio_bytes,format="audio/wav")
158
+ try:
159
+ st.download_button('Runterladen', audio_bytes, file_name='Thorsten-Voice.wav')
160
+ except:
161
+ pass
162
+
163
+ st.subheader('Mehr Infos?')
164
+ st.markdown('Möchtest Du mehr über die Möglichkeiten von **Thorsten-Voice** erfahren? Beispielsweise wie Du meine Stimme' +
165
+ ' auch komplett ohne Internet auf deinem PC mit Windows, Linux, Mac OS oder auf dem Raspberry Pi verwendest.'+
166
+ ' Dann sieh gerne auf der Projektwebseite www.Thorsten-Voice.de nach.')
requirements.txt ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ requests
2
+ streamlit