iFacialMocapの通信仕様


iFacialMocapにおいて3rdパーティのツール開発者様は、UDPまたはTCP/IPを使用してPCソフトウェアを介さずにフェイシャルデータを受信できます。

 

 


・UDPでデータを受信するには

PC上のソフトウェアを介さずにiFacialMocapと通信するには、PC側からiOS側の49983番ポートにUDPで、”iFacialMocap_sahuasouryya9218sauhuiayeta91555dy3719”という文字列を送信すると、PC側の49983番ポートにUDPで60FPSで返信が返ってきます。(長時間使用したり、端末が熱くなると30FPSに低下します)

 

・UDPで受信するPython使用例のサンプル

from socket import *

DstIP = "192.168.1.7"

DstPort = 49983

DstAddr = (DstIP,DstPort)

udpClntSock = socket(AF_INET, SOCK_DGRAM)

data = "iFacialMocap_sahuasouryya9218sauhuiayeta91555dy3719"

data = data.encode('utf-8')

udpClntSock.sendto(data,DstAddr)

 

server = socket(AF_INET, SOCK_DGRAM)

server.bind(("", 49983))

server.settimeout(0.05)

 

while True:

 try:

  messages, address = server.recvfrom(8192)

  print(messages.decode('utf-8'))

 except:

  pass

 

 

・1フレーム当たりに送られてくる文字列は以下のようなデータです。

mouthSmile_R-0|eyeLookOut_L-0|mouthUpperUp_L-11|eyeWide_R-0|mouthClose-8|mouthPucker-4|mouthRollLower-9|eyeBlink_R-7|eyeLookDown_L-17|cheekSquint_R-11|eyeBlink_L-7|tongueOut-0|jawRight-0|eyeLookIn_R-6|cheekSquint_L-11|mouthDimple_L-10|mouthPress_L-4|eyeSquint_L-11|mouthRight-0|mouthShrugLower-9|eyeLookUp_R-0|eyeLookOut_R-0|mouthPress_R-5|cheekPuff-2|jawForward-11|mouthLowerDown_L-9|mouthFrown_L-6|mouthShrugUpper-26|browOuterUp_L-4|browInnerUp-20|mouthDimple_R-10|browDown_R-0|mouthUpperUp_R-10|mouthRollUpper-8|mouthFunnel-12|mouthStretch_R-21|mouthFrown_R-13|eyeLookDown_R-17|jawOpen-12|jawLeft-0|browDown_L-0|mouthSmile_L-0|noseSneer_R-18|mouthLowerDown_R-8|noseSneer_L-21|eyeWide_L-0|mouthStretch_L-21|browOuterUp_R-4|eyeLookIn_L-4|eyeSquint_R-11|eyeLookUp_L-0|mouthLeft-1|=head#-21.488958,-6.038993,-6.6019735,-0.030653415,-0.10287084,-0.6584072|rightEye#6.0297494,2.4403017,0.25649446|leftEye#6.034903,-1.6660284,-0.17520553|

 

・簡略化された記述は以下のようなデータです。

BlendShape名-パラメータ(0~100) |BlendShape名-パラメータ(0~100)|....|=head#オイラー角X,オイラー角Y,オイラー角Z,移動値X,移動値Y,移動値Z|rightEye#オイラー角X,オイラー角Y,オイラー角Z|leftEye#オイラー角X,オイラー角Y,オイラー角Z|

 

角度関連のデータは、ラジアンではなくてdegreeで送られてきます。

 

 

 

 

 ・iOS側 ver1.1.8からFacemotion3dとの互換性を持たせるために外部コマンドが追加されました。

以下のように、|sendDataVersion=v2という文字列を付与すると、送られてくるBlendShapeパラメータの値が「&」で区切られるようになります。

iFacialMocap_sahuasouryya9218sauhuiayeta91555dy3719|sendDataVersion=v2

 

【例】

通常時

mouthSmile_R-0

sendDataVersion=v2

mouthSmile_R&0

 

何故このような処理になっているかというと、iFacialMocapの上位版となる、Facemotion3dアプリではブレンドシェイプの値にマイナスの値が送られてくる可能性があるためです。区切り文字に「-」を使っていると衝突が起きてしまう可能性があったためです。


・TCP/IPでデータを受信するには

UDPだとフレーム落ちする場合があるため、TCP/IPで受信する方法もあります。

iOS側の49983番ポートにUDPで、”iFacialMocap_UDPTCP_sahuasouryya9218sauhuiayeta91555dy3719”という文字列を送信するとPC側の49986番ポートにデータが送信されてきます。

 

送信される文字列は、UDPの時に送信されてくる文字列に"___iFacialMocap"という文字列を付加しただけのものです。

 

・簡略化された記述は以下のようなデータです。

BlendShape名-パラメータ(0~100) |BlendShape名-パラメータ(0~100)|....|=head#オイラー角X,オイラー角Y,オイラー角Z,移動値X,移動値Y,移動値Z|rightEye#オイラー角X,オイラー角Y,オイラー角Z|leftEye#オイラー角X,オイラー角Y,オイラー角Z|___iFacialMocap

 

TCP/IPでiOSからPCで受信するとコマ切れになった文字列が送信されてくるため、末尾の"___iFacialMocap"を区切り文字として使用してください。

 

TCP/IPの送信を停止するには、"iFacialMocap_UDPTCPSTOP_sahuasouryya9218sauhuiayeta91555dy3719"という文字列を49983番ポートに送信します。

 

・TCP/IPで受信するPython使用例のサンプル

from socket import socket, AF_INET, SOCK_DGRAM, SOCK_STREAM

 

#UDP send

HOST = ''

PORT = 49983

ADDRESS = "192.168.1.7" #iOS address

 

s = socket(AF_INET, SOCK_DGRAM)

msg = "iFacialMocap_UDPTCP_sahuasouryya9218sauhuiayeta91555dy3719"

s.sendto(msg.encode(), (ADDRESS, PORT))

 

s.close()

 

#create tcp server

with socket(AF_INET, SOCK_STREAM) as tcp_server:

tcp_server.bind(('192.168.1.5', 49986)) #192.168.1.5 is pc address

tcp_server.listen(1)

 

while True:

conn, addr = tcp_server.accept()

with conn:

while True:

data = conn.recv(10000)

print(data.decode('utf-8'))

 

 

 

 

 ・UDP同様、iOS側 ver1.1.8からFacemotion3dとの互換性を持たせるために外部コマンドが追加されました。

以下のように、|sendDataVersion=v2という文字列を付与すると、送られてくるBlendShapeパラメータの値が「&」で区切られるようになります。

iFacialMocap_UDPTCPSTOP_sahuasouryya9218sauhuiayeta91555dy3719|sendDataVersion=v2

 

【例】

通常時

mouthSmile_R-0

sendDataVersion=v2

mouthSmile_R&0

 

何故このような処理になっているかというと、iFacialMocapの上位版となる、Facemotion3dアプリではブレンドシェイプの値にマイナスの値が送られてくる可能性があるためです。区切り文字に「-」を使っていると衝突が起きてしまう可能性があったためです。

 


・iOS内で録画したデータを受信するには

iOS側の49983番ポートにUDPで、"iFacialMocap_bakeRecordedAnimation_start"という文字列を送信すると、録画済みのデータがTCP/IPでPC側の49987番ポートに送信されてきます。

 

送信されてくる文字列は、[".....",".....","....."]___iFacialMocapというような形式になっています。

[".....",".....","....."]の部分はJSON形式で、UDPやTCP/IPで使用したのと同じような文字列が格納されています。

常に60FPSで録画されたデータが格納されています。(iOS内で30FPSに処理が低下した場合でも60FPSで録画されるようになっています)

 

 

PC上のソフトウェアを介さずに通信する方法は、iFacialMocapがリリース当初に私が想定していた機能ではなかったのですが、仕様があまり綺麗ではないかもしれませんが、3rdパーティの開発者様は自由に使用して頂いて大丈夫です。ただ、開発者の私が他の方からお誘いを受けているため、iFacialMocapの開発は徐々に別の後継アプリに移行し、後継アプリがiFacialMocapの上位版のような扱いになる予定です。ただし、iFacialMocap自体が廃止されることはありません、今後もこのアプリもある程度は継続的にアップデートされます。

 

この機能をご使用して頂いている場合、今後リリースする後継アプリでどのような扱いになるかは未確定であることをご了承ください。

 

 

 

(具体的には、細かく各機能ごとに値段が分かれる設計になる予定です。)


・lookForwardボタンを外部から実行するには

 

"iFacialMocap_lookForward"という文字列をiOSの49983番ポートに送信してください。


・Unityへのダイレクトストリーミング

 

以下のスクリプトをゲームオブジェクトにアタッチして使用することができます。

iFacialMocapとFacemotion3dの両方でストリーミングが可能です。

https://drive.google.com/file/d/10cnZRlglrHmZIv-ECT66eqNZNsiWhMtf/view?usp=sharing

 

以下の画像のように、オブジェクト名を指定することで動作します。

これはVRMではなくFBXファイルを想定したスクリプトです。

VRMで使用したい場合は、ご自身で作成するか、メールでご相談ください。