Я работаю в Windows 10, использую Python 3.7 и хочу запустить подпроцесс для чтения видео и остановить его, если пользователь касается клавиатуры (я использую модуль keyboard
из https://pypi.org/project /клавиатура):
import subprocess
import keyboard
p1 = subprocess.call(keyboard.record(until='enter'))
p2 = subprocess.call([vlc, url_video, "vlc://quit", "&", "exit 0"])
while True:
if p1.poll():
p2.terminate()
break
if p2.poll() == None:
break
Проблема в том, что запуск p1
не возвращается и блокирует запуск p2
. Поэтому я никогда не вхожу в бесконечный цикл.
В этом коде есть как минимум две проблемы:
subprocess.call(keyboard.record(until='enter'))
сначала вызывает keyboard.record
, который блокируется до возврата, а затем вызывает subprocess.call
с возвращаемым значением keyboard.record
в качестве аргумента (что само по себе не имеет смысла).
subprocess.call также блокируется до тех пор, пока не завершится запущенный подпроцесс (помимо того, что он не делает то, что вы хотите здесь, он еще и устарел с Python 3.5.). Мы можем использовать subprocess.Popen
для запуска подпроцесса в фоновом режиме.
Вы неэффективно используете API клавиатуры . Вы не хотите записывать нажатия клавиш во время записи видео, вы хотите запускать действие при нажатии определенной клавиши. Для этого вроде бы подходит функция on_press_key.
Он принимает функцию (обратный вызов), которая будет выполняться после нажатия определенной клавиши. Мы можем передать функцию, которая завершит запущенный нами подпроцесс.
Насколько я могу судить, это должно работать:
import subprocess
import keyboard
# I haven't checked if these arguments are correct, they are unchanged
p = subprocess.Popen([vlc, url_video, "vlc://quit", "&", "exit 0"])
# set up callback to kill vlc if key is pressed
def stop_vlc(event):
if p.poll() is not None:
return # already done, do nothing
p.terminate()
keyboard.on_press_key('enter', stop_vlc)
# wait until vlc finishes, either by itself or because it is killed
p.wait()
Вам придется использовать многопоточность