python не может сломаться, пока l oop при воспроизведении аудио с изменением пигмея - PullRequest
2 голосов
/ 07 января 2020

Я попробовал что-то новое, чтобы соответствовать коду. Теперь, когда я нажимаю Ctrl + S, звук действительно останавливается, но когда мой личный помощник снова воспроизводит musi c во время того же запуска, musi c не останавливается, как в первый раз:

import glob
import os
import keyboard

os.environ['PYGAME_HIDE_SUPPORT_PROMPT'] = "hide"

import pygame
songs = glob.glob("C:\\Users\zivsi\Music\\*.mp3")
import random

song = random.choice(songs)

with open("song_choice.txt", "r") as file:
    read = file.read()

if (read == song):
    print("switch song")
    song = random.choice(songs)

song_name = song.replace("C:\\Users\zivsi\Music\\", "").replace(".mp3", "")
print("song: ", song_name)

pygame.mixer.init()

music = pygame.mixer.music.load(song)
pygame.mixer.music.play()

while (pygame.mixer_music.get_busy()):
    pygame.time.Clock().tick(10)
    keyboard.add_hotkey("ctrl + s", lambda: pygame.mixer_music.stop())

# если я нажму ctrl + s, музыка c остановится, но работает только один раз`

1 Ответ

4 голосов
/ 07 января 2020

Вы не можете использовать break в другой области, он имеет , чтобы быть частью самого набора l oop (поэтому вложен в оператор while или for). lambda - это функция, которая является другой областью действия.

Поскольку вы хотите отключиться от l oop асинхронно, вам потребуется другой способ связи из обработчика обратного вызова клавиатуры обратно в основной л oop. В общих терминах компьютерной инженерии вам нужен какой-то примитив синхронизации для синхронизации между разными вещами, которые происходят в одно и то же время одновременно.

То есть Вы хотите установить какой-нибудь флаг , который вы можете установить в своем while l oop, поэтому while pygame.mixer_music.get_busy() and not keyboard_ctrl_s_flag:. Вы можете сделать это с любым глобальным значением, и это будет , вероятно, безопасным:

keyboard_ctrl_s_flag = False  

def control_s_handler():
    """Called when the keyboard combination CTRL-S is pressed"""
    global keyboard_ctrl_s_flag
    keyboard_ctrl_s_flag = True

keyboard.add_hotkey("ctrl + s", control_s_handler)

, тогда вы можете использовать это в вашем l oop:

# reset the flag to false, in case it was already set to true before
keyboard_ctrl_s_flag = False  
while pygame.mixer_music.get_busy() and not keyboard_ctrl_s_flag:
    pygame.time.Clock().tick(10)

Я говорю, что , вероятно, безопасно, потому что я не совсем уверен, как PyGame выполняет свою обработку событий l oop. Учитывая, что вы также использовали pygame.time.Clock().tick(10) в вашем l oop, я думаю, что событие l oop, вероятно, ожидает, пока ваш код Python вернет управление, прежде чем делать другие вещи.

В следующий раз, когда затем пользователь использует CTRL-S, вызывается обратный вызов control_s_handler(), keyboard_ctrl_s_flag устанавливается на True, и когда управление возвращается к while l oop (потому что pygame.time.Clock().tick(10) вернул управление вашему Python код) while l oop выходит, даже если pygame.mixer_music.get_busy() все еще имеет значение.

...