🌐

TouchDesignerのWeb Server DATでHTTPリクエストを処理する

に公開

展示イベントのコンテンツ開発でTouchDesignerをよく利用しますが、そのときに複数のアプリケーションを連動させて一つのコンテンツを作ることが多々あります。そのような場合、アプリケーション間の連携にOSCをよく使います。しかし、OSCは基本的にUDPを利用するので開始シグナルなどのワンショット系の信号を扱うには信頼性の面で不安があり、またデータサイズの制限があり画像などの大きいデータは扱うことができません。

OSC以外に利用できそうなプロトコルとしてHTTPがあります。TouchDesignerではWeb Client DATを利用することでHTTPリクエストを送ることができ、Web Server DATを利用することでHTTPリクエストを処理することができます。

この記事ではWeb Server DATを利用してHTTPリクエストを処理してみます。Web Server DATはWebSocketsも扱えるようですが、この記事では扱いません。

https://derivative.ca/UserGuide/Web_Server_DAT


まずはシンプルにGETリクエストを送り、それに対してレスポンスを返してみます。

具体的には、/greetingというエンドポイントにクエリパラメータnameを送ると、nameを含んだ文字列をJSON形式で返すというサンプルになります。/greeting以外に送ると404を返します。確認用のHTTPクライアントにはWeb Client DATを利用しています。

webserver1_callbacks
import json

def onHTTPRequest(webServerDAT, request, response):
	if request['uri'] == '/greeting' and request['method'] == 'GET':
		response['statusCode'] = 200
		response['statusReason'] = 'OK'
		response['Content-Type'] = 'application/json'
		name = request['pars']['name']
		response['data'] = json.dumps({'greeting': f'Hello, {name}!'})
	else:
		response['statusCode'] = 404
		response['statusReason'] = 'Not Found'
	return response

画像を扱う例として、Base64エンコーディングした画像をPOSTリクエストで受け取り、ローカルに画像を保存したのちにMovie File In TOPで表示します。
以下のネットワークではHTTPクライアントとしてWeb Client DATを用いて、Text DATをRun Scriptすると画像をBase64エンコーディングしてWeb Server DATに送っています。

text1
import base64

def convert_to_base64(path):
    with open(path, "rb") as file:
        return base64.b64encode(file.read()).decode("utf-8")

op_image = op('moviefilein1')
image_path = op_image.par.file.eval()
image_base64 = convert_to_base64(image_path)
op_webclient = op('webclient1')
op_webclient.request('http://localhost:9980', 'POST', data=image_base64)
webserver1_callbacks
import base64

def save_base64_as_file(path, image_base64):
	with open(path, "wb") as file:
		file.write(base64.b64decode(image_base64))

def onHTTPRequest(webServerDAT, request, response):
	response['statusCode'] = 200
	response['statusReason'] = 'OK'
	image_base64 = request['data']
	image_path = "image.jpg"
	save_base64_as_file(image_path, image_base64)
	op_image = op('moviefilein2')
	op_image.par.file = image_path
	return response

Discussion