Skip to content

Commit

Permalink
add turbo
Browse files Browse the repository at this point in the history
  • Loading branch information
chaojie committed Jan 7, 2024
1 parent 57a8700 commit cd9142d
Show file tree
Hide file tree
Showing 7 changed files with 623 additions and 0 deletions.
133 changes: 133 additions & 0 deletions turbo/api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
#This is an example that uses the websockets api to know when a prompt execution is done
#Once the prompt execution is done it downloads the images using the /history endpoint
import os
import websocket #NOTE: websocket-client (https://github.com/websocket-client/websocket-client)
import uuid
import json
import urllib.request
import urllib.parse
from flask import Flask, request, jsonify, render_template, session, abort
from flask_socketio import SocketIO, join_room, leave_room,send, emit
import secrets

from PIL import Image
import io
import base64

server_address = "127.0.0.1:8188"
client_id = str(uuid.uuid4())

def queue_prompt(prompt):
p = {"prompt": prompt, "client_id": client_id}
data = json.dumps(p).encode('utf-8')
req = urllib.request.Request("http://{}/prompt".format(server_address), data=data)
return json.loads(urllib.request.urlopen(req).read())

def get_image(filename, subfolder, folder_type):
data = {"filename": filename, "subfolder": subfolder, "type": folder_type}
url_values = urllib.parse.urlencode(data)
with urllib.request.urlopen("http://{}/view?{}".format(server_address, url_values)) as response:
return response.read()

def get_history(prompt_id):
with urllib.request.urlopen("http://{}/history/{}".format(server_address, prompt_id)) as response:
return json.loads(response.read())

def get_images(ws, prompt):
prompt_id = queue_prompt(prompt)['prompt_id']
output_images = {}
while True:
out = ws.recv()
if isinstance(out, str):
message = json.loads(out)
if message['type'] == 'executing':
data = message['data']
if data['node'] is None and data['prompt_id'] == prompt_id:
break #Execution is done
else:
continue #previews are binary data

history = get_history(prompt_id)[prompt_id]
for o in history['outputs']:
for node_id in history['outputs']:
node_output = history['outputs'][node_id]
if 'images' in node_output:
images_output = []
for image in node_output['images']:
image_data = get_image(image['filename'], image['subfolder'], image['type'])
images_output.append(image_data)
output_images[node_id] = images_output

return output_images

prompt={}
with open('./workflow_api_motionctrl_turbo.json') as fr:
prompt = json.load(fr)

ws = websocket.WebSocket()
ws.connect("ws://{}/ws?clientId={}".format(server_address, client_id))

#Commented out code to display the output images:

# for node_id in images:
# for image_data in images[node_id]:
# from PIL import Image
# import io
# image = Image.open(io.BytesIO(image_data))
# image.show()

app = Flask(__name__, template_folder=os.path.abspath('.'), static_folder='assets')
app.secret_key = secrets.token_hex(16)

socketio = SocketIO(app, cors_allowed_origins='*')
connected_sids = set() # 存放已连接的客户端

#后端程序
lockroom='None'
@socketio.on('connect')
def on_connect():
connected_sids.add(request.sid)
print(f'{request.sid} 已连接')
socketio.start_background_task(background_thread_heartbeat)

@socketio.on('disconnect')
def on_disconnect():
connected_sids.remove(request.sid)
print(f'{request.sid} 已断开')

@socketio.on('message')
def handle_message(message):
"""收消息"""
print(f'message:{request.sid} {message}')
json.loads(message)

@socketio.on('camera_poses')
def handle_message(camera_poses):
print(f'camera_poses:{request.sid} {camera_poses}')
prompt["60"]["inputs"]["camera"] = camera_poses["camera_poses"]
images = get_images(ws, prompt)
for node_id in images:
for image_data in images[node_id]:
b64img=base64.b64encode(image_data).decode('utf-8')
socketio.emit('server_response',{'b64img':b64img}, to=camera_poses["roomid"])

@socketio.on('server_reconnect')
def server_reconnect(message):
print(f'server_reconnect:{request.sid} {message}')
join_room(message['roomid'])

def background_thread_heartbeat():
global lockroom
while True:
socketio.emit('server_response',{'lockroom':lockroom})
socketio.sleep(5)


@app.route('/')
def index():
session['user'] = None
return render_template('index.html')

if __name__ == '__main__':
socketio.run(app, host='0.0.0.0', port=5017, debug=True)
#app.run(host='0.0.0.0', port=5017)
22 changes: 22 additions & 0 deletions turbo/dist/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<title>CAMERA MOTION DESIGNER</title>
<style>
body { margin: 0; }
</style>
<script type="module" crossorigin src="/assets/index-6Ejqr5Fv.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-43v8HXt0.css">
</head>
<body>
<div id="info"><button id="btn_translate">Translate</button><button id="btn_rotate">Rotate</button>
<button id="btn_addpoint" style="display:none;">Add Point</button>
<!--"W" translate | "E" rotate--><br />
<!--textarea id="tb_result" style="width:256px; height:128px;">[]</textarea><br/-->
<button id="btn_startrt">Start Real Time MotionCtrl</button><br/>
<div style="width:256px;height:256px;" class="imageContainer"></div>
</div>
</body>
</html>
Expand Down
22 changes: 22 additions & 0 deletions turbo/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<link type="text/css" rel="stylesheet" href="main.css">
<title>CAMERA MOTION DESIGNER</title>
<style>
body { margin: 0; }
</style>
</head>
<body>
<div id="info"><button id="btn_translate">Translate</button><button id="btn_rotate">Rotate</button>
<button id="btn_addpoint" style="display:none;">Add Point</button>
<!--"W" translate | "E" rotate--><br />
<!--textarea id="tb_result" style="width:256px; height:128px;">[]</textarea><br/-->
<button id="btn_startrt">Start Real Time MotionCtrl</button><br/>
<div style="width:256px;height:256px;" class="imageContainer"></div>
</div>
<script type="module" src="main.js"></script>
</body>
</html>
91 changes: 91 additions & 0 deletions turbo/main.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
body {
margin: 0;
background-color: #000;
color: #fff;
font-family: Monospace;
font-size: 13px;
line-height: 24px;
overscroll-behavior: none;
}

a {
color: #ff0;
text-decoration: none;
}

a:hover {
text-decoration: underline;
}

button {
cursor: pointer;
text-transform: uppercase;
}

#info {
position: absolute;
top: 0px;
left: 0px;
padding: 10px;
box-sizing: border-box;
text-align: center;
/*-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
user-select: none;
pointer-events: none;*/
z-index: 1; /* TODO Solve this in HTML */
}

a, button, input, select {
pointer-events: auto;
}

.lil-gui {
z-index: 2 !important; /* TODO Solve this in HTML */
}

@media all and ( max-width: 640px ) {
.lil-gui.root {
right: auto;
top: auto;
max-height: 50%;
max-width: 80%;
bottom: 0;
left: 0;
}
}

#overlay {
position: absolute;
font-size: 16px;
z-index: 2;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
background: rgba(0,0,0,0.7);
}

#overlay button {
background: transparent;
border: 0;
border: 1px solid rgb(255, 255, 255);
border-radius: 4px;
color: #ffffff;
padding: 12px 18px;
text-transform: uppercase;
cursor: pointer;
}

#notSupported {
width: 50%;
margin: auto;
background-color: #f00;
margin-top: 20px;
padding: 10px;
}
Loading

0 comments on commit cd9142d

Please sign in to comment.