Переводчик бота в разногласийPython

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Переводчик бота в разногласий

Сообщение Anonymous »

Я пытался создать бота в разногласий, который выполнял бы функцию двойного перевода в голосовых каналах, этот код написан через нейронную сеть DeepSeek. Я столкнулся с такой проблемой, что при загрузке discord.py [голос] Discord не установлен. Sinks, без которых, насколько я понимаю, работа невозможна, я не могу найти эту библиотеку отдельно. И, если возможно, запишите, что можно добавить, исправить и как лучше это сделать. < /P>
import os
import asyncio
import discord
from discord.ext import commands
from discord.sinks import MP3Sink # Импорт из стандартной библиотеки
from transformers import (
WhisperForConditionalGeneration,
WhisperProcessor,
AutoTokenizer,
AutoModelForSeq2SeqLM
)
from gtts import gTTS
from io import BytesIO
import logging

# Настройка логирования
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

# Конфигурация (замените на свои значения)
DISCORD_TOKEN = "---------------------"
VOICE_CHANNEL_ID = 937370496989806607 # ID голосового канала
TEXT_CHANNEL_ID = 937370496989806605 # ID текстового канала

# Модели
WHISPER_MODEL_NAME = "openai/whisper-large-v2"
NLLB_MODEL_NAME = "facebook/nllb-200-distilled-600M"

# Языки
SOURCE_LANG = "eng_Latn"
TARGET_LANG = "rus_Cyrl"

class VoiceTranslateBot(commands.Bot):
def __init__(self, **kwargs):
intents = discord.Intents.all()
super().__init__(command_prefix='!', intents=intents)
self.voice_client = None
self.whisper_processor = None
self.whisper_model = None
self.nllb_tokenizer = None
self.nllb_model = None
self.audio_queue = asyncio.Queue()

async def setup_hook(self):
await self.load_models()
await self.connect_to_voice()
self.loop.create_task(self.audio_processing_loop())

async def load_models(self):
logger.info("Загружаем модели...")
self.whisper_processor = WhisperProcessor.from_pretrained(WHISPER_MODEL_NAME)
self.whisper_model = WhisperForConditionalGeneration.from_pretrained(WHISPER_MODEL_NAME).to('cuda')
self.nllb_tokenizer = AutoTokenizer.from_pretrained(NLLB_MODEL_NAME)
self.nllb_model = AutoModelForSeq2SeqLM.from_pretrained(NLLB_MODEL_NAME).to('cuda')
logger.info("Модели загружены.")

async def connect_to_voice(self):
channel = self.get_channel(VOICE_CHANNEL_ID)
if channel:
self.voice_client = await channel.connect()

# Начинаем запись с использованием MP3Sink
self.voice_client.start_recording(
MP3Sink(),
self.on_voice_data,
self.loop
)
logger.info("Подключено и начата запись.")
else:
logger.warning("Голосовой канал не найден!")

async def on_voice_data(self, sink, audio_data, *args):
"""Callback при получении аудиоданных"""
for user_id, data in audio_data.items():
if user_id != self.user.id: # Игнорируем собственный голос
await self.audio_queue.put(data.file.read())

async def audio_processing_loop(self):
"""Цикл обработки аудио"""
while True:
audio_bytes = await self.audio_queue.get()
try:
text = await self.transcribe_audio(audio_bytes)
if text.strip():
await self.process_translation(text)
except Exception as e:
logger.error(f"Ошибка обработки аудио: {e}")

async def transcribe_audio(self, audio_bytes):
"""Распознавание речи через Whisper"""
with open("temp_input.wav", "wb") as f:
f.write(audio_bytes)

from transformers import pipeline
transcriber = pipeline(
"automatic-speech-recognition",
model=self.whisper_model,
tokenizer=self.whisper_processor,
device=0
)
result = transcriber("temp_input.wav")
os.remove("temp_input.wav")
return result['text']

def translate_text(self, text):
"""Перевод текста через NLLB"""
self.nllb_tokenizer.src_lang = SOURCE_LANG
encoded = self.nllb_tokenizer(text, return_tensors="pt").to('cuda')
forced_bos_token_id = self.nllb_tokenizer.lang_code_to_id[TARGET_LANG]
generated_ids = self.nllb_model.generate(**encoded, forced_bos_token_id=forced_bos_token_id)
return self.nllb_tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]

def synthesize_speech(self, text, lang='ru'):
"""Синтез речи через gTTS"""
tts = gTTS(text=text, lang=lang)
fp = BytesIO()
tts.write_to_fp(fp)
fp.seek(0)
return fp

async def process_translation(self, text):
"""Обработка перевода"""
translated = self.translate_text(text)
logger.info(f"Перевод: {translated}")

audio_fp = self.synthesize_speech(translated)
await self.play_audio(audio_fp)

async def play_audio(self, audio_fp):
"""Воспроизведение аудио"""
source = discord.FFmpegPCMAudio(audio_fp, pipe=True)
if self.voice_client.is_playing():
self.voice_client.stop()
self.voice_client.play(source)

async def on_ready(self):
logger.info(f"Бот запущен как {self.user}")

# Запуск бота
bot = VoiceTranslateBot()
bot.run("-------")
< /code>
log -< /p>
E:\Translator\Python>python voice_translate_discord.py
Traceback (most recent call last):
File "E:\Translator\Python\voice_translate_discord.py", line 5, in
from discord.sinks import MP3Sink # Импорт из стандартной библиотеки
ModuleNotFoundError: No module named 'discord.sinks'
< /code>
новый код -< /p>
import os
import asyncio
import logging
from io import BytesIO

import discord
from discord.ext import commands
from discord.sinks import MP3Sink
from discord.sinks.core import Filters
from transformers import (
WhisperForConditionalGeneration,
WhisperProcessor,
AutoTokenizer,
AutoModelForSeq2SeqLM
)
from gtts import gTTS
from transformers import pipeline

# Настройка базового логирования
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
handlers=[
logging.StreamHandler(),
logging.FileHandler('bot.log', encoding='utf-8')
]
)
logger = logging.getLogger(__name__)

# Конфигурация
DISCORD_TOKEN = "--------------"
VOICE_CHANNEL_ID = 937370496989806607
TEXT_CHANNEL_ID = 937370496989806605

# Модели
WHISPER_MODEL_NAME = "openai/whisper-large-v2"
NLLB_MODEL_NAME = "facebook/nllb-200-distilled-600M"

# Языки
SOURCE_LANG = "eng_Latn"
TARGET_LANG = "rus_Cyrl"

class VoiceTranslateBot(commands.Bot):
def __init__(self, **kwargs):
intents = discord.Intents.all()
super().__init__(command_prefix='!', intents=intents)
self.voice_client = None
self.whisper_processor = None
self.whisper_model = None
self.nllb_tokenizer = None
self.nllb_model = None
self.audio_queue = asyncio.Queue()
self.recording_sink = None

async def setup_hook(self):
await self.load_models()
self.loop.create_task(self.audio_processing_loop())

async def load_models(self):
"""Загрузка моделей обработки языка"""
logger.info("Загружаем модели...")
try:
self.whisper_processor = WhisperProcessor.from_pretrained(WHISPER_MODEL_NAME)
self.whisper_model = WhisperForConditionalGeneration.from_pretrained(WHISPER_MODEL_NAME).to('cuda')
self.nllb_tokenizer = AutoTokenizer.from_pretrained(NLLB_MODEL_NAME)
self.nllb_model = AutoModelForSeq2SeqLM.from_pretrained(NLLB_MODEL_NAME).to('cuda')
logger.info("Модели успешно загружены.")
except Exception as e:
logger.error(f"Ошибка загрузки моделей: {e}")
raise

@commands.command()
async def join(self, ctx):
"""Подключиться к голосовому каналу пользователя"""
try:
if ctx.author.voice is None:
await ctx.send("Вы не в голосовом канале!")
return

if self.voice_client and self.voice_client.is_connected():
await ctx.send("Бот уже подключен к голосовому каналу!")
return

self.voice_client = await ctx.author.voice.channel.connect(timeout=30.0, reconnect=True)

# Настройка аудио захвата
self.recording_sink = MP3Sink(
filters=Filters(
filter_users=[self.user.id],
filter_audio_data=lambda data: True
),
output_path="recordings"
)

self.voice_client.start_recording(
self.recording_sink,
self.on_voice_data,
self.loop
)

await ctx.send(f"Подключился к каналу {ctx.author.voice.channel.name} и начал запись!")
logger.info(f"Подключение к голосовому каналу {ctx.author.voice.channel.id}")

except discord.Forbidden:
await ctx.send("Ошибка: Нет прав на подключение к голосовому каналу!")
logger.error("Нет прав на подключение к голосовому каналу")
except discord.HTTPException as e:
await ctx.send(f"Ошибка сети: {e}")
logger.error(f"Ошибка сети при подключении: {e}")
except Exception as e:
await ctx.send(f"Неизвестная ошибка: {e}")
logger.error(f"Ошибка подключения: {e}")

@commands.command()
async def leave(self, ctx):
"""Отключиться от голосового канала"""
if not self.voice_client or not self.voice_client.is_connected():
await ctx.send("Бот не подключен к голосовому каналу!")
return

try:
if self.voice_client.is_recording():
self.voice_client.stop_recording()

await self.voice_client.disconnect()
self.voice_client = None
await ctx.send("Отключился от голосового канала!")
logger.info("Отключение от голосового канала")
except Exception as e:
await ctx.send(f"Ошибка отключения: {e}")
logger.error(f"Ошибка отключения: {e}")

async def on_voice_data(self, sink, audio_data):
"""Обработка входящих аудиоданных"""
try:
for user_id, data in audio_data.items():
user = self.get_user(user_id)
logger.info(f"Получены аудиоданные от {user.name if user else user_id}")
await self.audio_queue.put((user_id, data.file.read()))
except Exception as e:
logger.error(f"Ошибка обработки аудиоданных: {e}")

async def audio_processing_loop(self):
"""Основной цикл обработки аудио"""
while True:
user_id, audio_bytes = await self.audio_queue.get()
try:
text = await self.transcribe_audio(audio_bytes)
if text.strip():
await self.process_translation(user_id, text)
except Exception as e:
logger.error(f"Ошибка обработки аудио: {e}")

async def transcribe_audio(self, audio_bytes):
"""Распознавание речи через Whisper"""
try:
temp_file = "temp_input.wav"
with open(temp_file, "wb") as f:
f.write(audio_bytes)

transcriber = pipeline(
"automatic-speech-recognition",
model=self.whisper_model,
tokenizer=self.whisper_processor,
device=0
)
result = transcriber(temp_file)
os.remove(temp_file)
return result['text']
except Exception as e:
logger.error(f"Ошибка транскрибации: {e}")
return ""

def translate_text(self, text):
"""Перевод текста через NLLB"""
try:
self.nllb_tokenizer.src_lang = SOURCE_LANG
encoded = self.nllb_tokenizer(text, return_tensors="pt").to('cuda')
forced_bos_token_id = self.nllb_tokenizer.lang_code_to_id[TARGET_LANG]
generated_ids = self.nllb_model.generate(**encoded, forced_bos_token_id=forced_bos_token_id)
return self.nllb_tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]
except Exception as e:
logger.error(f"Ошибка перевода: {e}")
return text

def synthesize_speech(self, text, lang='ru'):
"""Синтез речи через gTTS"""
try:
tts = gTTS(text=text, lang=lang)
fp = BytesIO()
tts.write_to_fp(fp)
fp.seek(0)
return fp
except Exception as e:
logger.error(f"Ошибка синтеза речи: {e}")
return None

async def process_translation(self, user_id, text):
"""Обработка перевода"""
try:
translated = self.translate_text(text)
logger.info(f"Перевод от пользователя {user_id}: {translated}")

if audio_fp := self.synthesize_speech(translated):
await self.play_audio(audio_fp)
except Exception as e:
logger.error(f"Ошибка обработки перевода: {e}")

async def play_audio(self, audio_fp):
"""Воспроизведение аудио"""
try:
if not self.voice_client or not self.voice_client.is_connected():
logger.warning("Невозможно воспроизвести: нет подключения к голосовому каналу")
return

source = discord.FFmpegPCMAudio(audio_fp, pipe=True)
if self.voice_client.is_playing():
self.voice_client.stop()

self.voice_client.play(source)
except Exception as e:
logger.error(f"Ошибка воспроизведения аудио: {e}")

async def on_ready(self):
"""Обработчик события готовности бота"""
logger.info(f"Бот запущен как {self.user} (ID: {self.user.id})")
logger.info(f"Доступные серверы: {len(self.guilds)}")
for guild in self.guilds:
logger.info(f"- {guild.name} (ID: {guild.id})")

if __name__ == "__main__":
# Проверка зависимостей
try:
from discord.sinks import MP3Sink
from discord.sinks.core import Filters
except ImportError as e:
logger.error(
"Требуется установить зависимости:\n"
"pip install py-cord[voice] transformers gtts\n"
f"Ошибка: {e}"
)
raise

# Создание необходимых директорий
os.makedirs("recordings", exist_ok=True)

# Запуск бота
bot = VoiceTranslateBot()
bot.run("---------------")
< /code>
log -< /p>
E:\Translator\Python>python voice_translate_discord.py
2025-07-10 16:07:07,467 - discord.client - INFO - logging in using static token
2025-07-10 16:07:08,229 - discord.gateway - INFO - Shard ID None has sent the IDENTIFY payload.
2025-07-10 16:07:08,497 - discord.gateway - INFO - Shard ID None has connected to Gateway: ["gateway-prd-us-east1-b-zn7s",{"micros":95814,"calls":["id_created",{"micros":387,"calls":[]},"session_lookup_time",{"micros":535,"calls":[]},"session_lookup_finished",{"micros":11,"calls":[]},"discord-sessions-prd-2-46",{"micros":94607,"calls":["start_session",{"micros":61890,"calls":["discord-api-rpc-5758b8d864-csz2n",{"micros":44247,"calls":["get_user",{"micros":14425},"get_guilds",{"micros":3725},"send_scheduled_deletion_message",{"micros":13},"guild_join_requests",{"micros":2},"authorized_ip_coro",{"micros":12},"pending_payments",{"micros":4408},"apex_experiments",{"micros":6542},"user_activities",{"micros":3},"played_application_ids",{"micros":2}]}]},"starting_guild_connect",{"micros":29,"calls":[]},"presence_started",{"micros":8920,"calls":[]},"guilds_started",{"micros":71,"calls":[]},"lobbies_started",{"micros":1,"calls":[]},"guilds_connect",{"micros":0,"calls":[]},"presence_connect",{"micros":23675,"calls":[]},"connect_finished",{"micros":23679,"calls":[]},"build_ready",{"micros":15,"calls":[]},"clean_ready",{"micros":0,"calls":[]},"optimize_ready",{"micros":1,"calls":[]},"split_ready",{"micros":0,"calls":[]}]}]}] (Session ID: dd0d615ff919f6b371a568dce7816632).
2025-07-10 16:07:10,508 - __main__ - INFO - Бот запущен как Translator bot#8792 (ID: 1392200178802360560)
2025-07-10 16:07:10,508 - __main__ - INFO - Доступные серверы: 1
2025-07-10 16:07:10,509 - __main__ - INFO - - Сервер cRATE (ID: 937370496989806602)
Ignoring exception in command None:
discord.ext.commands.errors.CommandNotFound: Command "join" is not found


Подробнее здесь: https://stackoverflow.com/questions/796 ... in-discord
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Python»