TouchDesigner×microCMS
はじめに
こちらはTouchDesigner Advent Calendar 2024 19日目の記事です。
私事で恐縮ですが、先月から株式会社ワントゥーテンに入社致しました。
microCMSで設定したスキーマをTouchDesignerで読み込み、各パラメーター毎にDATに吐き出す工程をtoxにまとめています。
今回作ったtoxは以下に格納しています。
microCMS
Web界隈ではよく使われているmicroCMS。
シンプルゆえに汎用性が高く、今回のようにTouchDesignerと連携することもできます。
APIの作成方法は以下公式ドキュメントやネットに記事が沢山あるのでそちらを参考に作成してみてください。
microCMSで扱えるパラメータは以下です。
パラメータ一覧
- テキストフィールド
- テキストエリア
- リッチエディタ
- 旧リッチエディタ(非推奨)
- 画像
- 複数画像
- 日時
- 真偽値
- セレクトフィールド
- コンテンツ参照
- 複数コンテンツ参照
- 数字
- カスタム
- 繰り返し
かなり多くのを型を扱えますね。
今回TouchDesignerで使いどころが難しいリッチエディタ、旧リッチエディタ(非推奨)、コンテンツ参照、複数コンテンツ参照、カスタム、繰り返しは省きます。
ではこれらのパラメーターをTouchDesignerで取得してみましょう。
TouchDesigner
カスタムパラメーターは以下の通りです。
・Url
microCMSで作成したAPIのURL
・Apikey
microCMSで作成したAPIのキー
・APISchemaJson
microCMSで作成したAPIのスキーマ構造が記述されたJSON
JSONのダウンロード方法
microCMSではAPIのスキーマ構造が記述されたJSONをダウンロードできるようになっています。
画像のAPI設定から「この設定をエクスポートする」を押してダウンロードしましょう。
これを使用することで毎回tox内を書き換えずに環境を作ることができます。
tox内のPython
toxの中身を見てみましょう。
基本重要なのはPythonになります。
中身のCHOPExecuteDATは以下のようになっています。
JSONを元にこれから取得するデータを格納するTableDAT、それらを外に出すOutDATを生成し、取得後順番に振り分けていくような実装になっています。
テーブルは既に生成されているものと比較し足りないものは生成、不要なものは削除するようになっています。
import requests as req
import json
def generateOp(fieldId):
generate_table_op = parent().create(tableDAT,fieldId)
generate_table_op.tags.add('generate')
generate_out_op = parent().create(outDAT,fieldId + "Out")
generate_out_op.tags.add('generate')
generate_table_op.outputConnectors[0].connect(generate_out_op.inputConnectors[0])
def clearTableOp(tableOp):
tableOp.clear(keepSize = False)
def appendTableOp(fieldKind,jsonObj,val):
table_op = op(jsonObj)
if(fieldKind == "text")or(fieldKind == "textArea")or(fieldKind == "date")or(fieldKind == "select")or(fieldKind == "boolean")or(fieldKind == "number"):
table_op.appendRow(val)
elif(fieldKind == "media"):
table_op.appendRow([val["url"],val["width"],val["height"]])
elif(fieldKind == "mediaList"):
json_images = []
for json_image in val:
json_images.append(json_image["url"])
json_images.append(json_image["width"])
json_images.append(json_image["height"])
table_op.appendRow(json_images)
def onOffToOn(channel, sampleIndex, val, prev):
# APIのスキームが記述されたJSONをパース(microCMSのダッシュボードでダウンロード可能)
# これから生成したいもの
file_in = op("FileInSchemaJson").jsonObject
field_ids = []
field_kind = []
for jsonContents in file_in["apiFields"]:
field_ids.append(jsonContents["fieldId"])
field_kind.append(jsonContents["kind"])
# 同一階層内にtableDAT取得
# すでに生成されてるもの
table_ops = parent().findChildren(type=tableDAT)
table_op_name = []
for table_op in table_ops:
table_op_name.append(table_op.name)
if len(table_ops)==0: #同一階層内にtableDATが一つもなければJSON通りに生成
for field_id in field_ids:
generateOp(field_id)
elif len(table_ops)<len(field_ids): #すでに生成されてるものとAPIのスキームを照らし合わせ足りないものを判定し生成
for field_id in field_ids:
if field_id not in table_op_name:# 同階層のtableDATの中にAPIのスキーマのFieldIDと一致するものがなければ生成
generateOp(field_id)
elif len(table_ops)>len(field_ids): #すでに生成されてるものとAPIのスキームを照らし合わせ余分なものを判定し削除
for table_op in table_ops:
if table_op.name not in field_ids:
# 接続しているoutDATが存在すれば削除
if(op(table_op.outputs)):
op(table_op.outputs[0]).destroy()
# 不要なtableDATを削除
table_op.destroy()
# 新しく生成したtableDATも含めて再取得
table_ops = parent().findChildren(type=tableDAT)
for table_op in table_ops:
clearTableOp(table_op)
# microCMSからjsonを取得
url = str(parent().par.Url)
api_key = str(parent().par.Apikey)
header = {
'X-MICROCMS-API-KEY': api_key,
'Content-Type': 'application/json'
}
res = req.get(url, headers=header)
jsonData = res.json()
# 順番にJSONデータ内の値を各TableDATに入力
for jsonContents in jsonData["contents"]:
contentNum = 0
for jsonObj in jsonContents:
# APIのスキームと関係ないパラメーターは省く
if jsonObj not in field_ids:
continue
appendTableOp(field_kind[contentNum],jsonObj,jsonContents[jsonObj])
contentNum+=1
return
def whileOn(channel, sampleIndex, val, prev):
return
def onOnToOff(channel, sampleIndex, val, prev):
return
def whileOff(channel, sampleIndex, val, prev):
return
def onValueChange(channel, sampleIndex, val, prev):
return
取得したデータの使い道
取得したデータの使い道をそれぞれまとめました。
・テキストフィールド
キャッチコピーなど一行で済む文字に使用。
・テキストエリア
ボディコピーなど複数行ある文字に使用。
・画像
画像のURLとWidth、Heightが取得できるのでWebRenderTOPを使用し画像を取得。
複数画像も同様。
・日時
ClockCHOPと比較し特定の日時に発火するイベントを作成。
ExpressionCHOPに取得した日付の値とClockCHOPの日付の値を入力に入れ、以下の式を入力することで判定が行えます。
1 if me.inputs[0][0] == me.inputs[1][0] else 0
・真偽値
何かしらのフラグに使用。
TouchのCHOPでboolを0,1と認識できない為以下の式で判定。
1 if op("null1")[0,0]=="True" else 0
もしくは数字で代用かScriptCHOPなどPython用に使用してもよいかもしれません。
・セレクトフィールド
要素のだし分けなどに使用。
以下の式で判定。
1 if op("null6")[0,0]=="testA" else 0
・数字
何かしらの閾値やパラメータの調整に使用。
まとめ
遅れてになってしまいましたが今年のアドカレの記事でした。
今年はVJの出演などアウトプットを出す機会もありつつ転職でかなりバタバタした一年でしたが、来年が楽しみなくらい環境が大きく変わりました。
新しい刺激と共にどんどん興味ある事に手を出していきたいと思います。
音をまたやりたいなと思い、早速クリスマスプレゼントとしてYAMAHAのSEQTRAKを購入して遊んでます。
それでは皆様よいお年を!
Discussion