почему по нажатию кнопки “Найти песню” приложение не спрашивает “Какую песню вы хотите услышать? # coding: utf-8

import time
import re
import speech_recognition as sr
import pyttsx3
import yt_dlp as youtube_dl
import pygame
import imageio_ffmpeg as ffmpeg
from freeGPT import Client
from googletrans import Translator
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.uix.textinput import TextInput
import os
import logging
import sys

# Create console handler with an ERROR level
console_handler = logging.StreamHandler(sys.stderr)
console_handler.setLevel(logging.WARNING)

# Create formatter and add it to the handlers
formatter = logging.Formatter(‘%(asctime)s - %(levelname)s - %(message)s’)
console_handler.setFormatter(formatter)

# Add the handlers to the logger
logger = logging.getLogger()
logger.addHandler(console_handler)
logger.setLevel(logging.WARNING)

# Now only ERROR and higher-level messages will be shown
logger.error(‘This is an error message’)
logger.warning(‘This is a warning’)
logger.info(‘This is an informational message’)
logger.debug(‘This is a debug message’)

# Check if running on Android
try:
from android.permissions import request_permissions, Permission
from android import api_version

android_platform = True
except ImportError:
android_platform = False


def safe_print(text):
try:
print(text)
except UnicodeEncodeError:
print(text.encode(‘utf-8’).decode(‘utf-8’))


def initialize_tts_engine():
return pyttsx3.init()


def speak(text, engine=None):
if not engine:
engine = initialize_tts_engine()
engine.say(text)
engine.runAndWait()
engine.stop()


# Initialize speech recognizer
recognizer = sr.Recognizer()


def listen_command():
with sr.Microphone() as source:
safe_print(“Listening for command…”)
audio = recognizer.listen(source)
try:
command = recognizer.recognize_google(audio, language=“ru-RU”)
safe_print(f"Command heard: {command}”)
return command.lower()
except sr.UnknownValueError:
speak(“Я не понял ваш запрос”)
return “”
except sr.RequestError:
speak(“Ошибка сервиса распознавания речи”)
return “”


def sanitize_filename(filename):
return re.sub(r’[/*?:“<>|]‘, ‘’, filename)


def search_youtube(query, tts_engine=None):
try:
sanitized_query = sanitize_filename(query)
directory = “mp3”

if not os.path.exists(directory):
os.makedirs(directory)

youtube_dl_opts = {
‘format’: ‘bestaudio/best’,
‘noplaylist’: True,
‘quiet’: True,
‘outtmpl’: os.path.join(directory, f’{sanitized_query}.%(ext)s’),
‘ffmpeg_location’: ffmpeg.get_ffmpeg_exe(),
‘postprocessors’: [{
‘key’: ‘FFmpegExtractAudio’,
‘preferredcodec’: ‘mp3’,
‘preferredquality’: ‘192’,
}],
}

file_path = os.path.join(directory, f”{sanitized_query}.mp3")

if os.path.exists(file_path):
speak(f"Файл уже существует. Проигрываю {sanitized_query}.“, tts_engine)
return file_path

with youtube_dl.YoutubeDL(youtube_dl_opts) as ydl:
info = ydl.extract_info(f"ytsearch1:{query}”, download=False)
video_info = info[‘entries’][0]
ydl.download([f"ytsearch1:{query}“])
while not os.path.exists(file_path):
time.sleep(1)
return file_path

except Exception as e:
logger.error(f"Error in search_youtube: {e}”)
speak(“Произошла ошибка при поиске песни”, tts_engine)
return None


def set_volume(level, tts_engine=None):
try:
level = int(level)
if 0 <= level <= 10:
pygame.mixer.music.set_volume(level / 10.0)
speak(f"Громкость установлена на {level}“, tts_engine)
else:
speak(“Пожалуйста, укажите уровень громкости от 0 до 10.”, tts_engine)
except ValueError:
speak(“Я не понял уровень громкости, укажите значение от 0 до 10.”, tts_engine)


commands = [
“найди песню - для поиска и воспроизведения песни”,
“продолжай - для продолжения воспроизведения”,
“пауза - для паузы воспроизведения”,
“стоп - для остановки воспроизведения и удаления песни”,
“включи - для воспроизведения песни”,
“найди или найти - для поиска новой песни”,
“перестань слушать или не слушай - для прекращения слушать команды”,
“слушай - для возобновления слушания команд”,
“громкость - от нуля до десяти”,
“команды - для воспроизведения этого списка команд”,
“спасибо, выход или завершить - для завершения программы”
]


def list_commands(tts_engine=None):
speak(“Доступные команды: " + “, “.join(commands), tts_engine)


def get_gpt_response(query, tts_engine=None):
translator = Translator()
try:
translated_query = translator.translate(query, src=‘ru’, dest=‘en’).text
resp = Client.create_completion(“gpt3_5”, translated_query)
translated_resp = translator.translate(resp, src=‘en’, dest=‘ru’).text
return translated_resp
except Exception as e:
logger.error(f"Error in get_gpt_response: {e}”)
return f"Произошла ошибка: {e}”


text_to_number = {
“ноль”: 0, “один”: 1, “два”: 2, “три”: 3, “четыре”: 4, “пять”: 5,
“шесть”: 6, “семь”: 7, “восемь”: 8, “девять”: 9, “десять”: 10
}


def get_number_from_text(text):
pattern = r”\d+”
match = re.search(pattern, text)
if match:
return int(match.group(0))
else:
return None


class MyApp(App):
def build(self):
pygame.init()
pygame.mixer.init()

if android_platform:
self.request_android_permissions()

self.current_song = None
self.listening = True
self.tts_engine = initialize_tts_engine()

self.layout = BoxLayout(orientation=‘vertical’)

# Перемещаем кнопку “Отправить запрос” вверх окна
self.text_query_button = Button(text=‘Отправить запрос’, size_hint=(1, 0.1))
self.text_query_button.bind(on_release=self.process_text_query)
self.layout.add_widget(self.text_query_button)

self.command_input = TextInput(size_hint=(1, 0.1), multiline=False, hint_text=‘Введите команду или запрос’)
self.layout.add_widget(self.command_input)

self.result_output = TextInput(size_hint=(1, 0.5), readonly=True)
self.layout.add_widget(self.result_output)

# Добавляем кнопку “Найти песню” вместо “Отправить запрос”
self.find_song_button = Button(text=‘Найти песню’, size_hint=(1, 0.1))
self.find_song_button.bind(on_release=self.find_song_action)
self.layout.add_widget(self.find_song_button)

self.button_layout = BoxLayout(size_hint=(1, 0.3))
commands = [“пауза”, “назад”, “продолжай”, “вперед”, “стоп”, “громкость +”, “громкость -”, “команды”, “выход”]
for command in commands:
btn = Button(text=command)
btn.bind(on_release=self.button_action)
if command == “громкость +”:
btn.bind(on_release=self.volume_up_button_action)
elif command == “громкость -”:
btn.bind(on_release=self.volume_down_button_action)
self.button_layout.add_widget(btn)

self.layout.add_widget(self.button_layout)

self.listen_button = Button(text=‘Голосовая команда’, size_hint=(1, 0.1))
self.listen_button.bind(on_release=self.listen_command_action)
self.layout.add_widget(self.listen_button)
self.result_output.text += “\nНажми ‘Голосовая команда’ и скажи ‘песню’”

return self.layout

def request_android_permissions(self):
def callback(permissions, results):
if all(results):
safe_print(“Permissions granted”)
else:
safe_print(“Permissions denied”)
speak(“Приложению необходимы все разрешения для корректной работы.”, self.tts_engine)
return

permissions_to_request = [Permission.READ_EXTERNAL_STORAGE,
Permission.WRITE_EXTERNAL_STORAGE,
Permission.RECORD_AUDIO]
request_permissions(permissions_to_request, callback)

def process_text_query(self, instance):
query = self.command_input.text
self.result_output.text += f"\nВы: {query}“
self.command_input.text = ‘’
self.execute_command(query)

# Новая функция для кнопки “Найти песню”
def find_song_action(self, instance):
query = self.command_input.text
if query:
command = f"найди песню {query}”
self.result_output.text += f"\nВы (поиск песни): {query}“
self.command_input.text = ‘’
self.execute_command(command)

def listen_command_action(self, instance):
command = listen_command()
self.result_output.text += f”\nВы (голосовая команда): {command}“
self.execute_command(command)

def button_action(self, instance):
command = instance.text
self.result_output.text += f”\nВы (кнопка): {command}“
self.execute_command(command)

def stop_playback(self):
if self.current_song:
pygame.mixer.music.stop()
while pygame.mixer.music.get_busy():
time.sleep(0.1)
if os.path.exists(self.current_song):
os.remove(self.current_song)
self.current_song = None
self.result_output.text += “\nВоспроизведение остановлено”

def volume_up_button_action(self, instance):
current_volume = pygame.mixer.music.get_volume() * 10
new_volume = min(current_volume + 1, 10)
set_volume(new_volume, self.tts_engine)
self.result_output.text += f”\nГромкость увеличена до {new_volume}“

def volume_down_button_action(self, instance):
current_volume = pygame.mixer.music.get_volume() * 10
new_volume = max(current_volume - 1, 0)
set_volume(new_volume, self.tts_engine)
self.result_output.text += f”\nГромкость уменьшена до {new_volume}“

def execute_command(self, command):
if “перестань слушать” in command or “не слушай” in command:
speak(“Я перестаю слушать. Скажите ‘Слушай’, чтобы я снова начал слушать.”, self.tts_engine)
self.listening = False
return

if “слушай” in command:
speak(“Я снова слушаю.”, self.tts_engine)
self.listening = True
return

if “команды” in command:
list_commands(self.tts_engine)
self.result_output.text += “\nДоступные команды:\n”
for c in commands:
self.result_output.text += f”- {c}\n"
self.result_output.text += “\nДоступные команды перечислены.”
return

if “песню” in command or “песня” in command or “музыку” in command or “музыка” in command or “youtube” or “Найти песню” or “Найди песню” in command:
speak(“Какую песню вы хотите услышать?”, self.tts_engine)
search_query = listen_command()
safe_print(f"Search Query: {search_query}“)

if search_query:
song_path = search_youtube(search_query, self.tts_engine)
safe_print(f"Song Path: {song_path}”)
self.result_output.text += “\nЗагружаю файл…”
if song_path and os.path.exists(song_path):
if self.current_song:
pygame.mixer.music.stop()
while pygame.mixer.music.get_busy():
time.sleep(0.1)
if os.path.exists(self.current_song):
os.remove(self.current_song)
self.current_song = song_path
pygame.mixer.music.load(self.current_song)
pygame.mixer.music.play()
speak(f"Проигрываю песню ‘{search_query}’“, self.tts_engine)
self.result_output.text += f”\nПроигрываю песню ‘{search_query}’“
else:
speak(“Не удалось найти песню.”, self.tts_engine)
return

if “продолжай” in command:
if self.current_song and not pygame.mixer.music.get_busy():
pygame.mixer.music.unpause()
self.result_output.text += “\nВоспроизведение продолжено”
return

if “пауза” in command:
if self.current_song and pygame.mixer.music.get_busy():
pygame.mixer.music.pause()
self.result_output.text += “\nВоспроизведение приостановлено”
return

if “стоп” in command:
if self.current_song:
try:
self.stop_playback()
except Exception as e:
logger.error(f"Error stopping playback: {e}”)
self.result_output.text += “\nОшибка приостановки воспроизведения”
return

if “включи” in command:
if self.current_song:
pygame.mixer.music.play()
self.result_output.text += “\nПроигрывание начато”
return

if “найди” in command or “найти” or “Найди песню” or “Найти песню” in command:
self.stop_playback()
speak(“Что вы хотите найти?”, self.tts_engine)
search_query = listen_command()
safe_print(f"Search Query: {search_query}“)

if search_query:
song_path = search_youtube(search_query, self.tts_engine)
safe_print(f"Song Path: {song_path}”)
if song_path and os.path.exists(song_path):
self.current_song = song_path
pygame.mixer.music.load(self.current_song)
pygame.mixer.music.play()
speak(f"Проигрываю песню ‘{search_query}’“, self.tts_engine)
self.result_output.text += f”\nПроигрываю песню ‘{search_query}’“
else:
speak(“Не удалось найти песню.”, self.tts_engine)
return

if “громкость” in command:
parts = command.split()
if len(parts) > 1:
number_word = parts[1]
level = get_number_from_text(number_word)
if level is not None:
set_volume(level, self.tts_engine)
self.result_output.text += f”\nГромкость установлена на {level}“
else:
speak(“Пожалуйста, укажите уровень громкости от 0 до 10.”, self.tts_engine)
else:
speak(“Пожалуйста, укажите уровень громкости от 0 до 10.”, self.tts_engine)
return

if “спасибо” in command or “выход” in command or “завершить” in command:
speak(“Завершаю работу. До свидания!”, self.tts_engine)
App.get_running_app().stop()
return

else:
gpt_response = get_gpt_response(command, self.tts_engine)
speak(gpt_response, self.tts_engine)
self.result_output.text += f”\nОтвет: {gpt_response}“
return


if name == “main”:
try:
MyApp().run()
except Exception as e:
logger.error(f"App crashed: {e}”)
finally:
pygame.quit()