naonauno commited on
Commit
1ff44b2
·
verified ·
1 Parent(s): 6f3a3ee

Upload app.py

Browse files
Files changed (1) hide show
  1. app.py +15 -264
app.py CHANGED
@@ -37,20 +37,12 @@ def format_credits_message(credits_info):
37
  return f"Credits Remaining: {credits_info['character_count']}"
38
 
39
  # Discord bot setup
40
- class VoiceBot(discord.Client):
41
- def __init__(self):
42
- super().__init__(intents=discord.Intents.default())
43
- self.tree = app_commands.CommandTree(self)
44
-
45
- async def setup_hook(self):
46
- await self.tree.sync()
47
-
48
- client = VoiceBot()
49
-
50
- # Get your Discord server ID (replace with your actual server ID)
51
- GUILD_ID = discord.Object(id=os.getenv('DISCORD_GUILD_ID'))
52
 
53
- @client.tree.command(name="list", description="List all available voices", guild=GUILD_ID)
54
  async def voice_list(interaction: discord.Interaction):
55
  await interaction.response.defer()
56
  available_voices = get_available_voices()
@@ -75,7 +67,7 @@ async def voice_autocomplete(
75
  for voice in voices if current.lower() in voice.lower()
76
  ][:25]
77
 
78
- @client.tree.command(name="create", description="Create a voice message", guild=GUILD_ID)
79
  @app_commands.describe(
80
  text="Text to convert to speech",
81
  voice_name="Select a voice to use",
@@ -121,8 +113,9 @@ async def voice_create(
121
  )
122
 
123
  # Save audio to temporary file
124
- with open("temp.mp3", "wb") as f:
125
- f.write(audio)
 
126
 
127
  # Get updated credits
128
  credits_info = get_remaining_credits()
@@ -135,11 +128,11 @@ async def voice_create(
135
  )
136
  await interaction.followup.send(
137
  embed=embed,
138
- file=discord.File("temp.mp3")
139
  )
140
 
141
  # Clean up
142
- os.remove("temp.mp3")
143
 
144
  except Exception as e:
145
  logger.error(f"Error generating audio: {str(e)}", exc_info=True)
@@ -149,256 +142,11 @@ async def voice_create(
149
  async def on_ready():
150
  logger.info(f"Bot is ready and logged in as {client.user}")
151
  try:
152
- synced = await client.tree.sync()
153
  logger.info(f"Synced {len(synced)} command(s)")
154
  except Exception as e:
155
  logger.error(f"Failed to sync commands: {e}")
156
 
157
- # Start Discord bot in a separate thread
158
- def start_discord_bot():
159
- """Start the Discord bot"""
160
- DISCORD_TOKEN = os.getenv("DISCORD_BOT_TOKEN")
161
- if not DISCORD_TOKEN:
162
- logger.error("DISCORD_BOT_TOKEN not found!")
163
- return
164
-
165
- logger.info("Starting Discord bot...")
166
- try:
167
- client.run(DISCORD_TOKEN)
168
- except Exception as e:
169
- logger.error(f"Failed to start Discord bot: {str(e)}")
170
- import os
171
- import gradio as gr
172
- import threading
173
- import discord
174
- from discord import app_commands
175
- from typing import List
176
- from elevenlabs import set_api_key, voices, generate, Voice, VoiceSettings, User
177
- import tempfile
178
- import speech_recognition as sr
179
- from pydub import AudioSegment
180
- import logging
181
-
182
- # Set up logging
183
- logging.basicConfig(level=logging.INFO)
184
- logger = logging.getLogger(__name__)
185
-
186
- # Set your ElevenLabs API key
187
- ELEVENLABS_API_KEY = os.getenv("ELEVENLABS_API_KEY")
188
- set_api_key(ELEVENLABS_API_KEY)
189
-
190
- # Create the voice command group
191
- voice_group = app_commands.Group(name="voice", description="Voice generation commands")
192
-
193
- # Discord bot setup
194
- intents = discord.Intents.default()
195
- intents.message_content = True
196
- client = discord.Client(intents=intents)
197
- tree = app_commands.CommandTree(client)
198
- tree.add_command(voice_group)
199
-
200
- def get_available_voices():
201
- """Fetch only custom voices from ElevenLabs account"""
202
- all_voices = voices()
203
- return {voice.name: voice.voice_id for voice in all_voices if not voice.category == "premade"}
204
-
205
- def get_remaining_credits():
206
- """Get remaining character credits from ElevenLabs"""
207
- user = User.from_api()
208
- subscription = user.subscription
209
- return {
210
- "character_count": subscription.character_count,
211
- "character_limit": subscription.character_limit
212
- }
213
-
214
- def format_credits_message(credits_info):
215
- """Format credits information into a readable message"""
216
- return f"Credits Remaining: {credits_info['character_count']}"
217
-
218
- # Discord bot commands
219
- # Command group for voice commands
220
- voice_group = app_commands.Group(name="voice", description="Voice generation commands")
221
-
222
- @voice_group.command(name="list", description="List all available voices")
223
- async def voice_list(interaction: discord.Interaction):
224
- await interaction.response.defer()
225
- available_voices = get_available_voices()
226
- voice_list = "\n".join([f"• {name}" for name in available_voices.keys()])
227
- credits_info = get_remaining_credits()
228
- credits_msg = format_credits_message(credits_info)
229
-
230
- embed = discord.Embed(
231
- title="Available Voices",
232
- description=f"{voice_list}\n\n{credits_msg}",
233
- color=0x2B2D31
234
- )
235
- await interaction.followup.send(embed=embed)
236
-
237
- @voice_group.command(name="create", description="Create a voice message")
238
- @app_commands.describe(
239
- text="Text to convert to speech",
240
- voice_name="Select a voice to use",
241
- stability="Voice stability (0-1)",
242
- clarity="Voice clarity (0-1)",
243
- style="Speaking style (0-1)"
244
- )
245
- async def voice_create(
246
- interaction: discord.Interaction,
247
- text: str,
248
- voice_name: str,
249
- stability: float = 0.5,
250
- clarity: float = 0.75,
251
- style: float = 0.5
252
- ):
253
- await interaction.response.defer()
254
-
255
- available_voices = get_available_voices()
256
- if voice_name not in available_voices:
257
- embed = discord.Embed(
258
- title="Voice Not Found",
259
- description=f"The voice '{voice_name}' was not found. Use `/voice list` to see available voices.",
260
- color=0x2B2D31
261
- )
262
- await interaction.followup.send(embed=embed)
263
- return
264
-
265
- try:
266
- voice_settings = VoiceSettings(
267
- stability=stability,
268
- similarity_boost=clarity,
269
- style=style,
270
- use_speaker_boost=True
271
- )
272
-
273
- audio = generate(
274
- text=text,
275
- voice=Voice(
276
- voice_id=available_voices[voice_name],
277
- settings=voice_settings
278
- )
279
- )
280
-
281
- # Save audio to temporary file
282
- with open("temp.mp3", "wb") as f:
283
- f.write(audio)
284
-
285
- # Get updated credits
286
- credits_info = get_remaining_credits()
287
- credits_msg = format_credits_message(credits_info)
288
-
289
- embed = discord.Embed(
290
- title="Voice Generated",
291
- description=f"Voice: {voice_name}\n{credits_msg}",
292
- color=0x2B2D31
293
- )
294
- await interaction.followup.send(
295
- embed=embed,
296
- file=discord.File("temp.mp3")
297
- )
298
-
299
- # Clean up
300
- os.remove("temp.mp3")
301
-
302
- except Exception as e:
303
- logger.error(f"Error generating audio: {str(e)}", exc_info=True)
304
- await interaction.followup.send(f"Error generating audio: {str(e)}")
305
-
306
- # Add autocomplete for voice names
307
- @voice_create.autocomplete('voice_name')
308
- async def voice_name_autocomplete(
309
- interaction: discord.Interaction,
310
- current: str,
311
- ) -> List[app_commands.Choice[str]]:
312
- voices = list(get_available_voices().keys())
313
- return [
314
- app_commands.Choice(name=voice, value=voice)
315
- for voice in voices if current.lower() in voice.lower()
316
- ][:25]
317
- logger.info(f"Received voice command: action={action}, voice_name={voice_name}")
318
- await interaction.response.defer()
319
-
320
- if action.lower() == "list":
321
- available_voices = get_available_voices()
322
- voice_list = "\n".join([f"• {name}" for name in available_voices.keys()])
323
- credits_info = get_remaining_credits()
324
- credits_msg = f"\n\nCredits remaining: {credits_info['character_count']} / {credits_info['character_limit']}"
325
-
326
- embed = discord.Embed(
327
- title="Available Voices",
328
- description=f"{voice_list}\n{credits_msg}",
329
- color=0x2B2D31 # Discord dark theme color
330
- )
331
- await interaction.followup.send(embed=embed)
332
-
333
- elif action.lower() == "create":
334
- if not all([text, voice_name]):
335
- embed = discord.Embed(
336
- title="Missing Information",
337
- description="Please provide both text and voice name. Use `/voice list` to see available voices.",
338
- color=0x2B2D31
339
- )
340
- await interaction.followup.send(embed=embed)
341
- return
342
-
343
- available_voices = get_available_voices()
344
- if voice_name not in available_voices:
345
- embed = discord.Embed(
346
- title="Voice Not Found",
347
- description=f"The voice '{voice_name}' was not found. Use `/voice list` to see available voices.",
348
- color=0x2B2D31
349
- )
350
- await interaction.followup.send(embed=embed)
351
- return
352
-
353
- try:
354
- voice_settings = VoiceSettings(
355
- stability=stability,
356
- similarity_boost=clarity,
357
- style=style,
358
- use_speaker_boost=True
359
- )
360
-
361
- audio = generate(
362
- text=text,
363
- voice=Voice(
364
- voice_id=available_voices[voice_name],
365
- settings=voice_settings
366
- )
367
- )
368
-
369
- # Save audio to temporary file
370
- with open("temp.mp3", "wb") as f:
371
- f.write(audio)
372
-
373
- # Get updated credits
374
- credits_info = get_remaining_credits()
375
- credits_msg = f"Credits remaining: {credits_info['character_count']} / {credits_info['character_limit']}"
376
-
377
- embed = discord.Embed(
378
- title="Voice Generated",
379
- description=f"Voice: {voice_name}\n{credits_msg}",
380
- color=0x2B2D31
381
- )
382
- await interaction.followup.send(
383
- embed=embed,
384
- file=discord.File("temp.mp3")
385
- )
386
-
387
- # Clean up
388
- os.remove("temp.mp3")
389
-
390
- except Exception as e:
391
- logger.error(f"Error generating audio: {str(e)}", exc_info=True)
392
- await interaction.followup.send(f"Error generating audio: {str(e)}")
393
-
394
- else:
395
- await interaction.followup.send("Invalid action. Use 'list' or 'create'.")
396
-
397
- @client.event
398
- async def on_ready():
399
- logger.info(f"Bot is ready and logged in as {client.user}")
400
- await tree.sync()
401
-
402
  # Gradio interface functions
403
  def text_to_speech(text, voice_name, stability, clarity, style):
404
  """Convert text to speech using selected voice and parameters"""
@@ -445,6 +193,9 @@ def speech_to_text(audio_file):
445
  return "Could not understand audio"
446
  except sr.RequestError:
447
  return "Error in speech recognition service"
 
 
 
448
 
449
  def speech_to_speech(audio_file, voice_name, stability, clarity, style):
450
  """Convert speech to speech by first converting to text, then to speech"""
 
37
  return f"Credits Remaining: {credits_info['character_count']}"
38
 
39
  # Discord bot setup
40
+ intents = discord.Intents.default()
41
+ intents.message_content = True
42
+ client = discord.Client(intents=intents)
43
+ tree = app_commands.CommandTree(client)
 
 
 
 
 
 
 
 
44
 
45
+ @tree.command(name="list", description="List all available voices")
46
  async def voice_list(interaction: discord.Interaction):
47
  await interaction.response.defer()
48
  available_voices = get_available_voices()
 
67
  for voice in voices if current.lower() in voice.lower()
68
  ][:25]
69
 
70
+ @tree.command(name="create", description="Create a voice message")
71
  @app_commands.describe(
72
  text="Text to convert to speech",
73
  voice_name="Select a voice to use",
 
113
  )
114
 
115
  # Save audio to temporary file
116
+ with tempfile.NamedTemporaryFile(delete=False, suffix=".mp3") as temp_file:
117
+ temp_file.write(audio)
118
+ temp_path = temp_file.name
119
 
120
  # Get updated credits
121
  credits_info = get_remaining_credits()
 
128
  )
129
  await interaction.followup.send(
130
  embed=embed,
131
+ file=discord.File(temp_path)
132
  )
133
 
134
  # Clean up
135
+ os.unlink(temp_path)
136
 
137
  except Exception as e:
138
  logger.error(f"Error generating audio: {str(e)}", exc_info=True)
 
142
  async def on_ready():
143
  logger.info(f"Bot is ready and logged in as {client.user}")
144
  try:
145
+ synced = await tree.sync()
146
  logger.info(f"Synced {len(synced)} command(s)")
147
  except Exception as e:
148
  logger.error(f"Failed to sync commands: {e}")
149
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
150
  # Gradio interface functions
151
  def text_to_speech(text, voice_name, stability, clarity, style):
152
  """Convert text to speech using selected voice and parameters"""
 
193
  return "Could not understand audio"
194
  except sr.RequestError:
195
  return "Error in speech recognition service"
196
+ finally:
197
+ # Clean up temporary wav file
198
+ os.unlink(wav_path)
199
 
200
  def speech_to_speech(audio_file, voice_name, stability, clarity, style):
201
  """Convert speech to speech by first converting to text, then to speech"""