最近我一直试图做一些家庭助理。在主助手中,有一些在处理程序脚本中运行的模块。我导入了一个我创建的模块,通过我的覆盆子pi播放youtube视频。我想要做的是更新我的处理程序脚本中的youtube模块中的变量。以下是我到目前为止的情况:
from __future__ import unicode_literals
import subprocess
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError
import time
import urllib, json, sys
from six import string_types
from signal import pause
from omxplayer.player import OMXPlayer
from gpiozero import Button
import sys
from multiprocessing import Process
from keys import key
button_pause = Button(17)
button_quit = Button(2)
button_skip = Button(3)
var_pause = False
var_skip = False
var_quit = False
DEVELOPER_KEY = key.api_keys['YOUTUBE_API']
YOUTUBE_API_SERVICE_NAME = 'youtube'
YOUTUBE_API_VERSION = 'v3'
'''
OMXPLAYER
'''
class Player:
def __init__(self, url):
self.url = url
self.player = None
self.state = True
self.playlist = False
self._play = True
def start(self):
if isinstance(self.url, string_types):
cmd = 'youtube-dl -g -f best {0}'.format(self.url)
yt_dl = subprocess.Popen(cmd,shell=True, stdin = subprocess.PIPE, stdout = subprocess.PIPE, stderr = subprocess.PIPE)
(url, err) = yt_dl.communicate()
if yt_dl.returncode != 0:
sys.stderr.write(err)
print('error')
yurl = url.decode('UTF-8').strip()
self.player = OMXPlayer(yurl, args=['-o','hdmi'])
return self.player.duration()
def stop(self):
self.player.stop()
self._play = False
self.player = None
return False
def skip(self):
if self.playlist == True:
self.player.stop()
return True
else:
self.player.stop()
return False
def toggle(self):
#false = not playing // true = playing
if self.state == True:
self.state = False
self.player.pause()
elif self.state == False:
self.state = True
self.player.play()
else:
return False
def is_play(self):
return self.player.can_control()
class Handlers:
def __init__(self):
self.url = None
self.typeof = None
self.proc = None
self._play = True
self.player = None
self.players = None
def input_handler(self):
if self.typeof == 'video':
#print(url)
self.players = [Player(self.url)]
self.player = self.players[0]
print('url for video:: {0}'.format(self.player.url))
self.player.start()
#self.proc = Process(target = self.output_handler)
#self.proc.start
self.output_handler()
elif self.typeof == 'playlist':
for video in self.url:
if self._play == True:
print(self._play)
#print(video)
self.players = [Player(video)]
self.player = self.players[0]
print('url for playlist video:: {0}'.format(self.player.url))
self.player.playlist = True
self.player.start()
#self.proc = Process(target = self.output_handler)
#self.proc.start()
self.output_handler()
else:
return False
def output_handler(self):
global button_quit
global button_pause
global button_skip
global var_quit
global var_pause
global var_skip
if self._play == True:
#player.start()
time.sleep(2.5)
p = self.player
p.playlist = True
if p is not None:
try:
while p.is_play():
if self._play == True:
if button_quit.is_pressed:
p.stop()
self._play = False
return False
elif button_pause.is_pressed:
p.toggle()
time.sleep(1)
elif button_skip.is_pressed:
if p.playlist == True:
p.skip()
return True
else:
p.stop()
return False
time.sleep(1)
elif var_skip == True:
var_skip = False
if p.playlist == True:
p.skip()
return True
else:
p.stop()
return False
time.sleep(1)
elif var_quit == True:
p.stop()
self._play = False
var_quit = False
return False
elif var_pause == True:
print('pausing')
p.toggle()
time.sleep(1)
var_pause = False
else:
time.sleep(0.1)
print(var_pause, var_quit, var_skip)
global var_quit
global var_pause
global var_skip
p.is_play()
else:
print('not playable')
return False
except Exception as e:
print("Something went wrong. Here it is: {0}".format(e))
注意:某些代码已被删除以用于可读性目的
您可以记下处理程序类中的Output处理程序。我想要做的是操纵另一个模块的var_skip,var_pause和var_quit,以便能够停止/播放我的视频。
在我的处理程序脚本中,我弹出一个单独的进程来运行youtube,使其在后台运行。按下时,我的按钮似乎能够熟练地更新。但是当我尝试从我的处理程序脚本访问我的变量时,没有任何反应。这是我的处理程序脚本
from modules import news
from modules import weather
from modules import sms
from modules import timers
from modules import define
from modules import youtube
from keys import key
from multiprocessing import Process, Pipe
import time
import paho.mqtt.client as mqtt
import requests
import json
import datetime
import os
############################################
mqtt_client = mqtt.Client()
HOST = key.mqtt_keys[0]
PORT = int(key.mqtt_keys[1])
TOPICS = key.mqtt_topics
timer = None
youtube_process
#API KEYS
YOUTUBE_API = key.api_keys['YOUTUBE_API']
WEATHER_API = key.api_keys['WEATHER_API']
YANDEX_API = key.api_keys['YANDEX_API']
def playVideo(query):
global youtube_process
youtube_process = Process(target = youtube.Youtube, args = [query,])
youtube_process.start()
#############################################
def on_message(client, userdata, msg):
global timer
if msg.topic not in TOPICS:
return False
os.system('aplay /home/pi/snips-custom-hotword/resources/dong.wav')
slots = parse_slots(msg)
#print(str(slots))
if msg.topic == 'hermes/intent/searchWeatherForecast':
weather = getWeather()
time = slots.get("forecast_start_datetime", None)
location = slots.get("forecast_locality", None)
set = handleWeather(weather, time, location)
response = set
elif msg.topic == 'hermes/intent/nickdeb:speakerInterrupt':
global youtube_process
keyword = slots.get("keyword", None)
if keyword:
if keyword == 'pause' or keyword == 'Pause' or keyword == 'paused':
response = 'Pausing your music!'
youtube_process.var_pause = True
else:
response = 'Stopping your music'
youtube_process.var_quit = True
else:
response = 'Stopping your music!'
youtube.var_quit = True
elif msg.topic == 'hermes/intent/nextSong':
youtube.var_skip = True
response = 'Skipping your song'
elif msg.topic == 'hermes/intent/resumeMusic':
youtube.var_pause = True
response = 'Resuming your music!'
elif msg.topic == 'hermes/intent/playArtist':
query = slots.get("artist_name", None) + ' top tracks'
youtubes = playVideo(query)
response = 'Playing top tracks by {1}'.format(msg.topic, slots.get("artist_name", None))
elif msg.topic == 'hermes/intent/nickdeb:playSong':
youtubes = playVideo(slots.get("song_name", None))
response = 'Playing {0} for you'.format(slots.get("song_name", None))
我已经尝试过编辑流程的模块变量和常规模块变量,但没有任何工作。请帮忙!谢谢!
TLDR;从处理程序脚本更改模块变量并实时更新它。模块位于进程内部,变量是我想要访问的全局变量。该变量在类
中使用答案 0 :(得分:0)
创建单独的流程时,当前全局状态将复制到新流程。您之后所做的任何更改(如更改全局变量)都不会与其他进程共享。
multiprocessing
包具有帮助share state between processes
在这种情况下,您可能希望使用Manager
在进程之间共享这些设置,而不是全局变量。
from multiprocessing import Manager, Process
manager = Manager()
state = manager.dict()
state['pause'] = False
state['skip'] = False
state['quit'] = False
youtube_process = Process(target = youtube.Youtube, args=(query, state))
# Process will get this change.
state['quit'] = True