yta-audio-narration 0.0.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,266 @@
1
+ """
2
+ This engine has been extracted from here:
3
+ - https://ttsmp3.com/
4
+
5
+ This voice engine has just a limit of
6
+ 3.000 characters of input when generating
7
+ with normal voices, and 1.000 daily
8
+ characters when using AI. AI is disabled
9
+ by now as the limit makes it not
10
+ interesting for our purpose.
11
+ """
12
+ from yta_audio_narration.consts import DEFAULT_VOICE
13
+ from yta_audio_narration.enums import NarrationLanguage, VoiceEmotion, VoiceSpeed, VoicePitch
14
+ from yta_audio_narration.voice import NarrationVoice
15
+ from yta_file_downloader import Downloader
16
+ from yta_constants.file import FileType
17
+ from yta_constants.enum import YTAEnum as Enum
18
+ from yta_programming.output import Output
19
+ from typing import Union
20
+
21
+ import requests
22
+
23
+
24
+ """
25
+ The options below are specified even if we
26
+ don't use them later when processing the
27
+ voice narration. This is to keep the same
28
+ structure for any voice narration and to
29
+ simplify the way we offer the options in
30
+ an API that is able to make requests.
31
+ """
32
+
33
+ # 1. The voices we accept, as Enums
34
+ class Ttsmp3VoiceName(Enum):
35
+ # Normal voices below:
36
+ DEFAULT = DEFAULT_VOICE
37
+ LUPE = 'Lupe' # US Spanish
38
+ PENELOPE = 'Penelope' # US Spanish
39
+ MIGUEL = 'Miguel' # US Spanish
40
+ # TODO: There are more voices for the different
41
+ # languages, so jus copy the names here and you
42
+ # will be able to use them
43
+ # AI voices below:
44
+ # ALLOY = 'alloy' # female
45
+ # ECHO = 'echo' # male
46
+ # FABLE = 'fable' # male
47
+ # ONYX = 'onyx' # male (deeper voice)
48
+ # NOVA = 'nova' # female (soft)
49
+ # SHIMMER = 'shimmer' # female
50
+
51
+ # 2. The languages we accept
52
+ LANGUAGE_OPTIONS = [
53
+ NarrationLanguage.DEFAULT
54
+ ]
55
+
56
+ # 3. The emotions we accept
57
+ EMOTION_OPTIONS = [
58
+ VoiceEmotion.DEFAULT,
59
+ VoiceEmotion.NORMAL,
60
+ ]
61
+
62
+ # 4. The speeds we accept
63
+ SPEED_OPTIONS = [
64
+ VoiceSpeed.DEFAULT,
65
+ VoiceSpeed.NORMAL,
66
+ ]
67
+
68
+ # 5. The pitches we accept
69
+ PITCH_OPTIONS = [
70
+ VoicePitch.DEFAULT,
71
+ VoicePitch.NORMAL,
72
+ ]
73
+
74
+ class Ttsmp3NarrationVoice(NarrationVoice):
75
+ """
76
+ Voice instance to be used when narrating with
77
+ Ttsmp3 engine.
78
+ """
79
+
80
+ @property
81
+ def processed_name(
82
+ self
83
+ ) -> str:
84
+ """
85
+ Get the usable name value from the one that has
86
+ been set when instantiating the instance.
87
+ """
88
+ return (
89
+ Ttsmp3VoiceName.MIGUEL.value
90
+ if Ttsmp3VoiceName.to_enum(self.name) == Ttsmp3VoiceName.DEFAULT else
91
+ Ttsmp3VoiceName.to_enum(self.name).value
92
+ )
93
+
94
+ @property
95
+ def processed_emotion(
96
+ self
97
+ ) -> str:
98
+ """
99
+ Get the usable emotion value from the one that
100
+ has been set when instantiating the instance.
101
+ """
102
+ # This narration is not able to handle any
103
+ # emotion (at least by now)
104
+ return None
105
+
106
+ @property
107
+ def processed_speed(
108
+ self
109
+ ) -> int:
110
+ """
111
+ Get the usable speed value from the one that
112
+ has been set when instantiating the instance.
113
+ """
114
+ # This is not used here
115
+ return None
116
+
117
+ @property
118
+ def processed_pitch(
119
+ self
120
+ ) -> int:
121
+ """
122
+ Get the usable pitch value from the one that
123
+ has been set when instantiating the instance.
124
+ """
125
+ # This is not used here
126
+ return None
127
+
128
+ @property
129
+ def processed_language(
130
+ self
131
+ ) -> str:
132
+ """
133
+ Get the usable language value from the one that
134
+ has been set when instantiating the instance.
135
+ """
136
+ # This engine has the language set in the voice
137
+ # names so you should select a voice name that
138
+ # is specific of the language you need
139
+ return None
140
+
141
+ def validate_and_process(
142
+ self,
143
+ name: str,
144
+ emotion: VoiceEmotion,
145
+ speed: VoiceSpeed,
146
+ pitch: VoicePitch,
147
+ language: NarrationLanguage
148
+ ):
149
+ Ttsmp3VoiceName.to_enum(name)
150
+ if VoiceEmotion.to_enum(emotion) not in EMOTION_OPTIONS:
151
+ raise Exception(f'The provided {emotion} is not valid for this narration voice.')
152
+ if VoiceSpeed.to_enum(speed) not in SPEED_OPTIONS:
153
+ raise Exception(f'The provided {speed} is not valid for this narration voice.')
154
+ if VoicePitch.to_enum(pitch) not in PITCH_OPTIONS:
155
+ raise Exception(f'The provided {pitch} is not valid for this narration voice.')
156
+ if NarrationLanguage.to_enum(language) not in LANGUAGE_OPTIONS:
157
+ raise Exception(f'The provided {language} is not valid for this narration voice.')
158
+
159
+ @staticmethod
160
+ def default():
161
+ return Ttsmp3NarrationVoice(
162
+ name = Ttsmp3VoiceName.DEFAULT.value,
163
+ emotion = VoiceEmotion.DEFAULT,
164
+ speed = VoiceSpeed.DEFAULT,
165
+ pitch = VoicePitch.DEFAULT,
166
+ language = NarrationLanguage.DEFAULT
167
+ )
168
+
169
+ # The voices but for a specific language, to be able to
170
+ # choose one when this is requested from the outside
171
+ def get_narrator_names_by_language(
172
+ language: NarrationLanguage
173
+ ) -> list[str]:
174
+ language = NarrationLanguage.to_enum(language)
175
+ language = (
176
+ NarrationLanguage.SPANISH
177
+ if language is NarrationLanguage.DEFAULT else
178
+ language
179
+ )
180
+
181
+ return {
182
+ NarrationLanguage.SPANISH: [
183
+ Ttsmp3VoiceName.DEFAULT.value,
184
+ Ttsmp3VoiceName.LUPE.value,
185
+ Ttsmp3VoiceName.MIGUEL.value,
186
+ Ttsmp3VoiceName.PENELOPE.value
187
+ ]
188
+ }[language]
189
+
190
+ # All the remaining functionality we need to make it
191
+ # work properly
192
+ # TODO: Check this because I don't know if this webpage is using the tts (coqui)
193
+ # library as the generator engine. If that, I have this engine in 'coqui.py' file
194
+ # so I don't need this (that is not stable because is based in http requests)
195
+ def narrate_tts3(
196
+ text: str,
197
+ voice: Ttsmp3NarrationVoice = Ttsmp3NarrationVoice.default(),
198
+ output_filename: Union[str, None] = None
199
+ ) -> str:
200
+ """
201
+ This makes a narration based on an external platform. You
202
+ can change some voice configuration in code to make the
203
+ voice different.
204
+
205
+ Aparrently not limited. Check, because it has time breaks
206
+ and that stuff to enhance the narration.
207
+ """
208
+ # From here: https://ttsmp3.com/
209
+ headers = {
210
+ 'accept': '*/*',
211
+ 'accept-language': 'es-ES,es;q=0.9',
212
+ 'content-type': 'application/x-www-form-urlencoded',
213
+ 'origin': 'https://ttsmp3.com',
214
+ 'referer': 'https://ttsmp3.com/',
215
+ 'sec-ch-ua': '"Google Chrome";v="123", "Not:A-Brand";v="8", "Chromium";v="123"',
216
+ 'sec-ch-ua-mobile': '?0',
217
+ 'sec-ch-ua-platform': '"Windows"',
218
+ 'sec-fetch-dest': 'empty',
219
+ 'sec-fetch-mode': 'cors',
220
+ 'sec-fetch-site': 'same-origin',
221
+ 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36',
222
+ }
223
+
224
+ data = {
225
+ 'msg': text,
226
+ 'lang': voice.processed_name,
227
+ 'source': 'ttsmp3',
228
+ }
229
+
230
+ """
231
+ There is an AI voices version but it has a
232
+ daily limit of only 1.000 characters so it
233
+ is not interesting, that is why I leave the
234
+ code but commented.
235
+
236
+ The way to request AI voice narrations is
237
+ the same, but using the AI url and the AI
238
+ voices names instead of the normal ones.
239
+ """
240
+ # AI_VERSION_HEADERS = {
241
+ # 'accept': '*/*',
242
+ # 'accept-language': 'es-ES,es;q=0.9',
243
+ # 'content-type': 'application/x-www-form-urlencoded',
244
+ # 'origin': 'https://ttsmp3.com',
245
+ # 'priority': 'u=1, i',
246
+ # 'referer': 'https://ttsmp3.com/ai',
247
+ # 'sec-ch-ua': '"Not(A:Brand";v="99", "Google Chrome";v="133", "Chromium";v="133"',
248
+ # 'sec-ch-ua-mobile': '?0',
249
+ # 'sec-ch-ua-platform': '"Windows"',
250
+ # 'sec-fetch-dest': 'empty',
251
+ # 'sec-fetch-mode': 'cors',
252
+ # 'sec-fetch-site': 'same-origin',
253
+ # 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36',
254
+ # }
255
+ # AI_VERSION_URL = 'https:ttsmp3.com/makemp3_ai.php'
256
+
257
+ response = requests.post('https://ttsmp3.com/makemp3_new.php', headers = headers, data = data)
258
+ response = response.json()
259
+ url = response['URL']
260
+
261
+ output_filename = Output.get_filename(output_filename, FileType.AUDIO)
262
+
263
+ # This is one example of a valid url we receive
264
+ # as response:
265
+ # https://ttsmp3.com/created_mp3/8b38a5f2d4664e98c9757eb6db93b914.mp3
266
+ return Downloader.download_audio(url, output_filename).filename
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2018 The Python Packaging Authority
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ SOFTWARE.
@@ -0,0 +1,27 @@
1
+ Metadata-Version: 2.3
2
+ Name: yta-audio-narration
3
+ Version: 0.0.1
4
+ Summary: Youtube Autonomous Audio Narration Module.
5
+ Author: danialcala94
6
+ Author-email: danielalcalavalera@gmail.com
7
+ Requires-Python: ==3.9
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Programming Language :: Python :: 3.9
10
+ Requires-Dist: coqui-tts (>=0.25.3,<0.26.0)
11
+ Requires-Dist: gtts (>=2.5.1,<3.0.0)
12
+ Requires-Dist: pyttsx3 (>=2.90,<3.0)
13
+ Requires-Dist: yta_constants (>=0.0.1,<1.0.0)
14
+ Requires-Dist: yta_file (>=0.0.1,<1.0.0)
15
+ Requires-Dist: yta_file_downloader (>=0.0.1,<1.0.0)
16
+ Requires-Dist: yta_programming (>=0.0.1,<1.0.0)
17
+ Requires-Dist: yta_text (>=0.0.1,<1.0.0)
18
+ Requires-Dist: yta_validation (>=0.0.1,<1.0.0)
19
+ Description-Content-Type: text/markdown
20
+
21
+ # Youtube Autonomous Audio Narration Module
22
+
23
+ The Audio narration module.
24
+
25
+ Please, check the 'pyproject.toml' file to see the dependencies.
26
+
27
+
@@ -0,0 +1,18 @@
1
+ yta_audio_narration/__init__.py,sha256=E7aNhIl4Uy87WJK4VEoMbvaoVB567tfSzvolV9z-vZU,63
2
+ yta_audio_narration/consts.py,sha256=zeV3NpUyMURg3yyrcBZCGSzB950fwVAQo_mVCbiacmQ,25
3
+ yta_audio_narration/enums.py,sha256=q9utHejNzwwHB9LHah4nkzQN5TTbMH0q7dJkCD-y47c,13227
4
+ yta_audio_narration/narrator.py,sha256=AXFABqcJ3Ox2SnALLynGXLXt0b_dfDUU8IXtBCGO0oY,20445
5
+ yta_audio_narration/voice.py,sha256=QlqH1Smmsaoyu9PKJeVai-vEPiSKptmw5AoUggJTm3U,2371
6
+ yta_audio_narration/voices/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
+ yta_audio_narration/voices/coqui.py,sha256=JpfqAj9rAXPrp9I3xWNARZx5RJbYx0linZw1yzE8I3E,8825
8
+ yta_audio_narration/voices/google.py,sha256=PKOgPz_1_6oZUGD0LFh1cgWiVsPwUUPIq4mwQYrP1jQ,8110
9
+ yta_audio_narration/voices/microsoft.py,sha256=Tfsc5C-kSjgqp_2S8B6xBQqiJ11RvsP-HUegPdgcGNw,6354
10
+ yta_audio_narration/voices/open_voice.py,sha256=gYJsykS-bYroXe5oklq_qn4xHcl_5FqpXHUgsVI7s-U,12960
11
+ yta_audio_narration/voices/tetyys.py,sha256=0UvJUBo4iVGF1pbC-EJVfTpV04UiK-xfNzg1RRfHMkM,8270
12
+ yta_audio_narration/voices/tiktok.py,sha256=IT57jbFtt-mW52gZUB8O9mduYoZ4luNaUegep5TNavI,7461
13
+ yta_audio_narration/voices/tortoise.py,sha256=BzBjwLUCjh8Zw2nAgElUMSNf3Nl4YMN0Q1BUTu6u8zI,6555
14
+ yta_audio_narration/voices/ttsmp3.py,sha256=v8S448zwFvVDMMCxewuPNKGmznA3RhPoO-D5tx8qnYk,8778
15
+ yta_audio_narration-0.0.1.dist-info/LICENSE,sha256=6kbiFSfobTZ7beWiKnHpN902HgBx-Jzgcme0SvKqhKY,1091
16
+ yta_audio_narration-0.0.1.dist-info/METADATA,sha256=gUDLEw_sSUXBzGWsgyrEI1eI5yBne8J5C9jhBJBWE3Q,875
17
+ yta_audio_narration-0.0.1.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
18
+ yta_audio_narration-0.0.1.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: poetry-core 2.1.1
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any