1. API Documentation
  2. Motion Capture WebSocket API documentation

Sample Code

 

Python

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import time
import json
import hmac
import hashlib
import requests
import websocket # <https://websocket-client.readthedocs.io/en/latest/installation.html>

print('---------------------REST API Authorization-----------------------');

# REST API Authorization
access_key = 'fa53be261a6f97b9dac4'
secret_key = 'a53be261a6f97b9dac4ac4e9031afe62591e6ed8'
method = 'POST'
path = '/user/read/GetWebsocketInfo'
body = {}
md5enc = hashlib.md5()
md5enc.update(json.dumps(body).encode('utf-8'))
body_hash = md5enc.hexdigest()
time_str = str(int(time.time() * 1000))
print('access_key: ' + access_key)
print('secret_key: ' + secret_key)
print('path: ' + path)
print('method: ' + method)
print('timestamp: ' + time_str)
print('body_hash: ' + body_hash)

auth_hmac = hmac.new(bytes(secret_key, encoding='utf-8'), digestmod=hashlib.sha256)
auth_hmac.update(bytes(time_str, encoding='utf-8'))
auth_hmac.update(bytes(method, encoding='utf-8'))
auth_hmac.update(bytes(path, encoding='utf-8'))
auth_hmac.update(bytes(body_hash, encoding='utf-8'))

api_auth_header = f'PLSK1-HMAC-SHA256 Credential={access_key}, Body={body_hash}, Signature={time_str}:{auth_hmac.hexdigest()}'
print('REST API Authorization Key: '+ api_auth_header)

print('---------------------WebSocket Authorization-----------------------')
# WebSocket Authorization
base_url = '<https://dev-api-mocap.plask.ai>'
api_response = requests.post(
base_url + path,
json = body,
headers = {
'Authorization': api_auth_header
}
)

socket_url = api_response.json()['socketUrl']
socket_api_id = api_response.json()['socketApiId']
print('socket_url: ' + socket_url)
print('socket_api_id: ' + socket_api_id)

socket_md5enc = hashlib.md5()
socket_md5enc.update(socket_api_id.encode('utf-8'))
socket_body_hash = socket_md5enc.hexdigest()
socket_time_str = str(int(time.time() * 1000))
print('socket_body_hash: ' + socket_body_hash)
print('socket_time_str: ' + socket_time_str)

socket_hmac = hmac.new(bytes(secret_key, encoding='utf-8'), digestmod=hashlib.sha256)
socket_hmac.update(bytes(socket_time_str, encoding='utf-8'))
socket_hmac.update(bytes('CONNECT', encoding='utf-8'))
socket_hmac.update(bytes(socket_body_hash, encoding='utf-8'))

socket_auth_header = f'WS-HMAC-SHA256 Credential={access_key}, Event=CONNECT, Signature={socket_time_str}:{socket_hmac.hexdigest()}'
print('WebSocket Authorization Key: '+ socket_auth_header)

print('---------------------WebSocket Connection-----------------------');
# websocket.enableTrace(True) # Allow Websocket Logging

def send_message_to_socket(socket, message, pending):
pending_message.append(message['request'])
socket.send(json.dumps(message))

def handle_socket_response(response, pending, result):
pending_request = pending.pop(0)
result.append({
"time": time.strftime('%c', time.localtime(time.time())),
"request": pending_request,
"response": json.loads(response)
})

ws = websocket.WebSocket()
ws.connect(
socket_url,
header = { "Authorization" : socket_auth_header }
)

socket_result = []
pending_message = []

# GetUploadUrl API
uploadUrlMessage = {
"method": "read",
"request": "GetUploadUrl",
"param": {
"sourceFileName": "sample_dance_short.mov"
}
}
send_message_to_socket(ws, uploadUrlMessage, pending_message)
handle_socket_response(ws.recv(), pending_message, socket_result)

# GetUserApiUsages API
userApiUsagesMessage = {
"method": "read",
"request": "GetUserApiUsages",
"param": {
"startInvokedAt": "2022-10-01T07:32:25.232Z",
"endInvokedAt": "2022-10-21T07:32:25.232Z",
"apiName": "ExtractMotionCapture",
"billedDurationSec": 0,
"billedFrame": 0,
"isError": False
}
}
send_message_to_socket(ws, userApiUsagesMessage, pending_message)
handle_socket_response(ws.recv(), pending_message, socket_result)

print(json.dumps(socket_result, indent = 2))

ws.close()

Javascript

const crypto = require('crypto');
const axios = require('axios');
const WebSocket = require('ws');

const main = async () => {
console.log('---------------------REST API Authorization-----------------------');

// REST API Authorization
const accessKey = 'fa53be261a6f97b9dac4';
const secretKey = 'a53be261a6f97b9dac4ac4e9031afe62591e6ed8';
const method = 'POST';
const body = {};
const path = '/user/read/GetWebsocketInfo'
const bodyHash = crypto.createHash('md5').update(JSON.stringify(body)).digest('hex');
const time = Date.now().toString(); // ex) '1653349880857';
console.log('accessKey: ' + accessKey);
console.log('secretKey: ' + secretKey);
console.log('path: ' + path);
console.log('method: ' + method);
console.log('timestamp: ' + time);
console.log('bodyHash: ' + bodyHash);

const hmac = crypto.createHmac('sha256', secretKey);
hmac.update(time);
hmac.update(method);
hmac.update(path);
hmac.update(bodyHash);

const apiAuthHeader = `PLSK1-HMAC-SHA256 Credential=${accessKey}, Body=${bodyHash}, Signature=${time}:${hmac.digest('hex')}`;
console.log('REST API Authorization Key: '+ apiAuthHeader);

console.log('---------------------WebSocket Authorization-----------------------');
// WebSocket Authorization
const baseUrl = '<https://dev-api-mocap.plask.ai>';
const apiResponse = await axios.post(baseUrl + path, {}, {
headers: {
'Authorization': apiAuthHeader
}
});

const {socketUrl, socketApiId} = apiResponse.data;
console.log('socketUrl: ' + socketUrl);
console.log('socketApiId: ' + socketApiId);

const socketBodyHash = crypto.createHash('md5').update(socketApiId).digest('hex');
const socketTimestamp = Date.now().toString();
console.log('socketBodyHash: ' + socketBodyHash);
console.log('socketTimestamp: ' + socketTimestamp);

const socketHmac = crypto.createHmac('sha256', secretKey);
socketHmac.update(socketTimestamp);
socketHmac.update('CONNECT');
socketHmac.update(socketBodyHash);

const socketAuthHeader = `WS-HMAC-SHA256 Credential=${accessKey}, Event=CONNECT, Signature=${socketTimestamp}:${socketHmac.digest('hex')}`
console.log('WebSocket Authorization Key: '+ socketAuthHeader);

console.log('---------------------WebSocket Connection-----------------------');
// WebSocket Setting
const socket = new WebSocket(socketUrl, {
headers: {
Authorization: socketAuthHeader
}
})

/*
message object interface
{
"method": "read", >>> "read" or "write"
"request": "GetUploadUrl", >>> API Name
"param": {
"sourceFileName": "sample_dance_short.mov"
} >>> API Request Data Parameters. If not needed, put {}
}
*/
const sendMessageToSocket = (socket, message, pending) => {
pending.push(message.request);
socket.send(JSON.stringify(message));
}

const handleSocketResponse = (response, pending, result) => {
const pendingRequest = pending.shift();
result.push({
time: new Date(),
request: pendingRequest,
response: JSON.parse(response)
})
}

let socketOpen = false;
const pendingMessage = [];
const socketResult = [];

socket.onopen = (e) => {
console.log("WebSocket Connection established");
socketOpen = true;
};
socket.onmessage = (event) => {
handleSocketResponse(event.data,pendingMessage,socketResult);
};
socket.onclose = (e) => {
console.log(socketResult);
console.log("WebSocket Disconnected");
}

// Wait for WebSocket Connection
while(socketOpen === false) {
await new Promise((resolve) => {
setTimeout(resolve, 500);
});
}

// GetUploadUrl API
const uploadUrlMessage = {
method: "read",
request: "GetUploadUrl",
param: {
"sourceFileName": "sample_dance_short.mov"
}
}
sendMessageToSocket(socket,uploadUrlMessage,pendingMessage);

// Wait until previous request is over
while(pendingMessage.length > 0) {
await new Promise((resolve) => {
setTimeout(resolve, 500);
});
}

// GetUserApiUsages API
const userApiUsagesMessage = {
method: "read",
request: "GetUserApiUsages",
param: {
startInvokedAt: "2022-10-01T07:32:25.232Z",
endInvokedAt: "2022-10-21T07:32:25.232Z",
apiName: "ExtractMotionCapture",
billedDurationSec: 0,
billedFrame: 0,
isError: false
}
}
sendMessageToSocket(socket,userApiUsagesMessage,pendingMessage);

// Socket Disconnect after 30 sec
await new Promise((resolve) => {
setTimeout(() => {
socket.close();
resolve();
}, 1000 * 30);
});

}

main();