TouchDesigner (TD) kann Python-Skripte ausführen. Wenn die Verarbeitung wie die HTTP-Kommunikation einige Zeit in Anspruch nimmt, friert sie ein wenig ein, bis die Verarbeitung abgeschlossen ist. Zu diesem Zeitpunkt wird ** auch die Zeitleiste des gesamten TD angehalten und die Zeichnung wird nicht aktualisiert ** Um dies zu verhindern, haben wir uns für eine asynchrone Kommunikation entschieden.
Wenn Sie den Wert nur asynchron erhalten möchten, können Sie zusätzlich zu TD aber auch Knoten usw. verwenden Aufgrund der Umstände der Umgebung wollte ich es nur mit TD vervollständigen, daher habe ich die folgende Methode in Betracht gezogen.
--Verwenden Sie "Web DAT" --Verwenden Sie das Threading-Modul
Ich werde jedes davon erklären.
Dieses Beispiel wird unten hochgeladen. https://github.com/genkitoyama/TD_with_asynchronous_communication
Das ist am einfachsten. Wenn der Parameter "Asynchroner Abruf" aktiviert ist, Geben Sie die URL ein und drücken Sie die Schaltfläche "Abrufen". Die TD-Timeline stoppt nicht und kommuniziert hinter den Kulissen (möglicherweise Curl?). Referenz: https://docs.derivative.ca/Web_DAT
(Im obigen Beispiel wird API zum Ermitteln der Höhe des Nationalen Landforschungsinstituts verwendet.)
Im Fall von GET ist es in Ordnung, wenn Sie es direkt in die URL eingeben. Im Fall von POST ist es in Ordnung, wenn Sie die Schaltfläche "Senden" mit der Tabelle der Daten, die Sie senden möchten, an den oberen Eingang "Eingang 0" anschließen. (Übrigens können Sie einen benutzerdefinierten HTTP-Header in den unteren Einlass einfügen.)
Ziehen Sie dann entsprechend dem Format des zurückgegebenen Elements den erforderlichen Wert mit dem Modul "XML DAT" oder "json", und fertig.
Referenz: JSON in DAT-Tabelle mit TouchDesigner analysieren
threading
Modul Ist ein Modul, das eine Multithread-Parallelverarbeitung durchführt.
Es ist standardmäßig in Python 3.5 in TD enthalten.
Wenn Sie die Funktion, die Sie ausführen möchten, in einen anderen Thread und das Argument dieser Funktion in das Argument "threading.Thread ()" einfügen, wird sie in einem anderen Thread ausgeführt.
Hier wird "Anfragen" als Modul für die HTTP-Kommunikation verwendet.
Anfragen
sind auch standardmäßig in Python in TD enthalten.
(Es gibt mehrere andere Module, die HTTP-Kommunikation durchführen, aber ich bin der Meinung, dass Sie alles verwenden können, was Sie möchten.)
import threading
import requests
class HttpRequest():
def __init__(self):
self.url = op('URL').text
self.city_id = op('CITY_ID').text
#Funktionen, die Sie asynchron ausführen möchten
def request(self):
response = requests.get(self.url, params={'city':self.city_id})
def start_request(self):
myThread = threading.Thread(target=self.request)
myThread.start()
Dies ist ein großartiger Verweis auf Artikel von Dr. Matthew Ragan.
Das "Threading" -Modul ist ebenfalls sehr nützlich, hat jedoch einige Nachteile.
--Kann nicht erkennen, wann der Prozess in einem anderen Thread beendet wurde --Kann nicht auf den TD-Operator verweisen, während ein anderer Thread verarbeitet wird
Ich kann einen Stoppbefehl vom Hauptthread senden.
Es ist nicht möglich zu erkennen, wann die Verarbeitung in einem anderen Thread abgeschlossen ist.
Wenn Sie die Methode join ()
verwenden, können Sie auf das Ende eines anderen Threads warten.
Während dieser Zeit stoppt der Haupt-Thread, sodass der TD schließlich stoppt. ..
Daher ist es nicht einfach, etwas wie "Ich habe die URL in einem anderen Thread getroffen und diesen Prozess ausgeführt, wenn der Wert zurückgegeben wird" zu tun.
Dies ist natürlich, wenn Sie darüber nachdenken, aber da es in einem anderen Thread verarbeitet wird, Zugriff auf den Operator im Hauptthread des TD nicht möglich.
Daher ist es nicht möglich, "das zurückgegebene Ergebnis zu analysieren, indem Sie die URL in einem anderen Thread auf" Table DAT "klicken, da es sich in derselben Funktion befindet".
(Übrigens, wenn Sie das tun, erhalten Sie einen Dialog wie diesen)
Es ist also eine ziemliche Fähigkeit, aber ich habe mich entschieden, "Timer CHOP" zu verwenden, um zu überwachen, ob der Wert zurückgegeben wird (≒ ob die Verarbeitung eines anderen Threads abgeschlossen ist) **.
Ich möchte, dass Sie das Beispiel für Details sehen, aber grob gesagt ist der Fluss wie folgt.
Im obigen Beispiel wird [Weather Hacks] von livingoor (http://maps.gsi.go.jp/development/elevation_s.html) verwendet. Mit dieser API wird das Ergebnis sofort zurückgegeben. Selbst wenn Sie dies auf diese Weise tun, ist es nicht sehr lecker. Wenn es sich jedoch um die ursprüngliche API handelt, die Sie zuvor verwendet haben, dauert die Rückgabe aufgrund der Umstände 7 bis 8 Sekunden. Also habe ich diese Methode entwickelt.
Python hat versucht, die Klassen "RequestManager" und "HttpRequest" wie folgt zu erstellen.
import http_request
import json
class RequestManager():
def __init__(self):
self.http = http_request.HttpRequest()
self.can_start_request = True #Darf ich eine Anfrage stellen
self.max_confirmation_count = 10 #Maximale Anzahl von Bestätigungen
self.current_confirmation_count = 0 #Aktuelle Bestätigungsanzahl
self.timer = op('timer1')
def init_timer(self):
print('init http request timer')
def start_timer(self):
#Wenn Sie eine Anfrage stellen können, werfen Sie eine Anfrage, wenn nicht, warten Sie
if self.can_start_request == True:
print('start http request timer')
self.http.start_request()
else:
print('restart timer')
def done_timer(self):
print('done http request timer')
#Überprüfen Sie, ob der Wert zurückgegeben wird
output = self.http.get_data()
#Wenn kein Wert vorhanden ist, erhöhen Sie die Anzahl der Bestätigungen und versuchen Sie es erneut
if output is None:
print('http response is none')
self.can_start_request = False
self.current_confirmation_count += 1
#Wenn die Bestätigungsanzahl das Maximum erreicht, wird beurteilt, dass die Kommunikation fehlgeschlagen ist.
if self.current_confirmation_count >= self.max_confirmation_count:
print('http out of request')
self.timer.par.initialize.pulse()
self.http = http_request.HttpRequest()
self.current_confirmation_count = 0
else:
self.timer.par.start.pulse()
else:
#Wenn es einen Wert gibt, wird json analysiert und gespeichert
self.can_start_request = True
out_json = json.loads(output)
op('out_json')[0,0].val = out_json['forecasts'][0]
self.current_confirmation_count = 0
self.timer.par.initialize.pulse()
import threading
import requests
class HttpRequest():
def __init__(self):
self.url = op('URL').text
self.city_id = op('CITY_ID').text
self.out_data = None
print('http request init')
def request(self):
get_data = {'city':self.city_id}
response = requests.get(self.url, params=get_data)
self.out_data = response.text
print(self.out_data)
def start_request(self):
self.out_data = None
myThread = threading.Thread(target=self.request)
myThread.start()
def get_data(self):
return self.out_data
――Wir haben zwei Arten von asynchronen Kommunikationsmethoden zusammengefasst, die nur TouchDesigner verwenden. ――Weil ich ein Anfänger von Python bin, wäre ich dankbar, wenn Sie den letzten Teil der Brute Force kommentieren könnten, besonders wenn Sie Ideen für eine bessere Methode haben ...!
――Dieses Mal habe ich TouchPlayer verwendet, um jedes auf mehreren Terminals auszuführen. Da ich den Textport mit TouchPlayer jedoch nicht sehen kann, habe ich das Protokoll in eine externe Datei ausgespuckt und überprüft, ob ein Fehler aufgetreten ist.
Recommended Posts