更新版本-https

This commit is contained in:
shadowcz007
2023-11-29 11:10:59 +08:00
parent 91a271b717
commit 240ffce0c7
11 changed files with 1103 additions and 764 deletions
+1
View File
@@ -1 +1,2 @@
__pycache__/
https/
+25 -12
View File
@@ -1,6 +1,8 @@
##
In progress.
!!
![screenshare](./assets/screenshare.png)
### ScreenShareNode & FloatingVideoNode
> Now comfyui supports capturing screen pixel streams from any software and can be used for LCM-Lora integration. Let's get started with implementation and design! 💻🌐
@@ -11,28 +13,39 @@ https://github.com/shadowcz007/comfyui-mixlab-nodes/assets/12645064/e7e77f90-e43
<!-- [ScreenShareNode](./workflow/2-screeshare.json) -->
[ScreenShareNode & FloatingVideoNode](./workflow/3-FloatVideo-workflow.json)
!! Please use the address with HTTPS (https://127.0.0.1).
## Installation
For the easiest install experience, install the [Comfyui Manager](https://github.com/ltdrdata/ComfyUI-Manager) and use that to automate the installation process.
Otherwise, to manually install, simply clone the repo into the custom_nodes directory with this command:
manually install, simply clone the repo into the custom_nodes directory with this command:
```
cd ComfyUI/custom_nodes
git clone https://github.com/shadowcz007/comfyui-mixlab-nodes.git
```
and install the requirements using:
```
.\python_embeded\python.exe -s -m pip install -r requirements.txt
```
If you are using a venv, make sure you have it activated before installation and use:
```
pip install -r requirements.txt
```
Run directly:
Install the requirements:
run directly:
```
cd ComfyUI_Mixlab
install.bat
```
or install the requirements using:
```
../../../python_embeded/python.exe -s -m pip install -r requirements.txt
```
If you are using a venv, make sure you have it activated before installation and use:
```
pip3 install -r requirements.txt
```
## Nodes
![main](./assets/all.png)
@@ -65,7 +78,7 @@ Add edges to an image.
### Models
下载[CLIPSeg](https://huggingface.co/CIDAS/clipseg-rd64-refined/tree/main)到 model/clipseg
[Download CLIPSeg](https://huggingface.co/CIDAS/clipseg-rd64-refined/tree/main), move to : model/clipseg
<!-- ### Workflow
[Workflow](./workflow.md) -->
+92
View File
@@ -7,6 +7,98 @@ import sys
python = sys.executable
from server import PromptServer
try:
import aiohttp
from aiohttp import web
except ImportError:
print("Module 'aiohttp' not installed. Please install it via:")
print("pip install aiohttp")
print("or")
print("pip install -r requirements.txt")
sys.exit()
def create_key(key_p,crt_p):
import OpenSSL
# 生成自签名证书
# 生成私钥
private_key = OpenSSL.crypto.PKey()
private_key.generate_key(OpenSSL.crypto.TYPE_RSA, 2048)
# 生成CSR
csr = OpenSSL.crypto.X509Req()
csr.get_subject().CN = "mixlab.com" # 设置证书的通用名称
csr.set_pubkey(private_key)
csr.sign(private_key, "sha256")
# 生成证书
certificate = OpenSSL.crypto.X509()
certificate.set_serial_number(1)
certificate.gmtime_adj_notBefore(0)
certificate.gmtime_adj_notAfter(365 * 24 * 60 * 60) # 设置证书的有效期
certificate.set_issuer(csr.get_subject())
certificate.set_subject(csr.get_subject())
certificate.set_pubkey(csr.get_pubkey())
certificate.sign(private_key, "sha256")
# 保存私钥到文件
with open(key_p, "wb") as f:
f.write(OpenSSL.crypto.dump_privatekey(OpenSSL.crypto.FILETYPE_PEM, private_key))
# 保存证书到文件
with open(crt_p, "wb") as f:
f.write(OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_PEM, certificate))
return
def create_for_https():
current_path = os.path.abspath(os.path.dirname(__file__))
# print("#####path::", current_path)
# TODO 处理路径
https_key_path=os.path.join(current_path, "https")
crt=os.path.join(https_key_path, "certificate.crt")
key=os.path.join(https_key_path, "private.key")
print("##https_key_path", crt,key)
if not os.path.exists(https_key_path):
# 使用mkdir()方法创建新目录
os.mkdir(https_key_path)
if not os.path.exists(crt):
create_key(key,crt)
return (crt,key)
# https
async def new_start(self, address, port, verbose=True, call_on_start=None):
runner = web.AppRunner(self.app, access_log=None)
await runner.setup()
site = web.TCPSite(runner, address, port)
await site.start()
import ssl
crt,key=create_for_https()
ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
ssl_context.load_cert_chain(crt,key)
site2 = web.TCPSite(runner, address, 443,ssl_context=ssl_context)
await site2.start()
if address == '':
address = '0.0.0.0'
if verbose:
print("Starting server\n")
print("To see the GUI go to: http://{}:{}".format(address, port))
print("To see the GUI go to: https://{}".format(address))
if call_on_start is not None:
call_on_start(address, port)
# import webbrowser
# if os.name == 'nt' and address == '0.0.0.0':
# address = '127.0.0.1'
# webbrowser.open(f"https://{address}")
# webbrowser.open(f"http://{address}:{port}")
PromptServer.start=new_start
def is_installed(package, package_overwrite=None):
try:
spec = importlib.util.find_spec(package)
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 428 KiB

+1 -1
View File
@@ -104,5 +104,5 @@ class FloatingVideo:
results.append(image_base64)
return { "ui": { "images": results } }
return { "ui": { "images_": results } }
+1
View File
@@ -1 +1,2 @@
numpy
pyOpenSSL
+103 -24
View File
@@ -3,9 +3,9 @@ import { api } from '../../../scripts/api.js'
import { ComfyWidgets } from '../../../scripts/widgets.js'
import { $el } from '../../../scripts/ui.js'
let api_host = '127.0.0.1:8188'
let api_host = `127.0.0.1:${window.location.port}`
let api_base = ''
let url = `http://${api_host}${api_base}`
let url = `${window.location.protocol}//${api_host}${api_base}`
async function getQueue () {
try {
@@ -467,14 +467,6 @@ app.registerExtension({
} else {
window._mixlab_stopLive = await startLive(widget.liveBtn)
console.log('window._mixlab_stopLive', window._mixlab_stopLive)
var node = this.graph._nodes.filter(n => n.type == 'ScreenShare')[0] // for you to look it up like this
var w = node?.widgets.find(w => w.name === 'prompt') // and then it's just the same
console.log('####node?.widgets', node?.widgets)
if (w) {
w.value = 'a girl'
node.onResize?.(node.size)
}
}
})
@@ -654,6 +646,10 @@ app.registerExtension({
// widget.card.appendChild(widget.PictureInPicture)
widget.PictureInPicture.addEventListener('click', async () => {
if (window.location.protocol != 'https:') {
window.alert('About to redirect to HTTPS access.https://127.0.0.1')
window.open('https://127.0.0.1')
}
// Open a Picture-in-Picture window.
let w = 360,
s = widget.preview.videoWidth / widget.preview.videoHeight,
@@ -667,30 +663,113 @@ app.registerExtension({
overflow: hidden;
background: #2a2c34;
border: 4px solid #878787;
outline: none;`
outline: none;background: black;`
let div = document.createElement('div')
div.style = `display:flex;position: fixed;
bottom: 0px;
z-index: 9999;
left: 0px;
width: calc(100% - 24px);
margin: 12px;`
// console.log(pipWindow.document)
// Move the player to the Picture-in-Picture window.
let input = document.createElement('textarea')
input.style = `width: 100%;
margin: 12px;
background: rgb(249, 249, 249);
color: black;
font-size: 16px;
input.style = `
min-width:90%;
max-width:100%;
background: #24283db3;
color: white;
font-size: 14px;
padding: 8px;
font-weight: 800;
font-weight: 300;
letter-spacing: 1px;
outline: none;
min-height: 98px;
border-radius: 8px;
border: 1px solid rgb(221, 221, 221);
box-shadow: rgb(228, 228, 228) 1px 3px`
border: 1px solid rgb(91, 91, 91);
font-family: sans-serif;
`
window._mixlab_screen_prompt =
window._mixlab_screen_prompt ||
'beautiful scenery nature glass bottle landscape,under water'
input.value = window._mixlab_screen_prompt
let btnDiv = document.createElement('div')
btnDiv.style = `cursor: pointer;
display: flex;
flex-direction: column;
justify-content: start;
align-items: center;
width: 24px;
font-size: 16px;
margin-right: 6px;`
let btn = document.createElement('butotn')
btn.innerText = '❤'
btn.style = `cursor: pointer;height: 24px;margin:4px;
color: red;`
btn.addEventListener('click', () => {
if (input.style.display == 'none') {
input.style.display = 'block'
} else {
input.style.display = 'none'
}
})
let pauseBtn = document.createElement('butotn')
pauseBtn.innerText = '⏸'
pauseBtn.style = `cursor: pointer;height: 24px;margin:4px;
color: #03A9F4;`
pauseBtn.addEventListener('click', async () => {
if (window._mixlab_stopLive) {
pauseBtn.innerText = '▶'
window._mixlab_stopLive()
window._mixlab_stopLive = null
let node = this.graph._nodes.filter(
n => n.type === 'ScreenShare'
)[0]
var w = node.widgets?.filter(w => w.name === 'sreen_share')[0] // see if it already exists
if (w) {
w.liveBtn.innerText = 'Live Run'
}
} else {
pauseBtn.innerText = '⏸'
let node = this.graph._nodes.filter(
n => n.type === 'ScreenShare'
)[0]
var w = node.widgets?.filter(w => w.name === 'sreen_share')[0] // see if it already exists
if (w) {
w.liveBtn.innerText = 'Stop Live'
window._mixlab_stopLive = await startLive(w.liveBtn)
console.log('window._mixlab_stopLive', window._mixlab_stopLive)
}
}
})
pipWindow.document.body.append(widget.preview)
pipWindow.document.body.append(input)
pipWindow.document.body.append(div)
div.appendChild(btnDiv)
btnDiv.appendChild(btn)
btnDiv.appendChild(pauseBtn)
div.appendChild(input)
input.addEventListener('input', () => {
window._mixlab_screen_prompt = input.value
})
// Move the player back when the Picture-in-Picture window closes.
pipWindow.addEventListener('pagehide', event => {
widget.card.appendChild(widget.preview)
pipWindow.remove()
// pipWindow.remove()
pipWindow.close()
})
})
@@ -749,8 +828,8 @@ app.registerExtension({
const context = canvas.getContext('2d')
if (message?.images) {
const base64 = message.images[0]
if (message?.images_) {
const base64 = message.images_[0]
const image = new Image()
image.onload = function () {
canvas.width = image.width
@@ -762,7 +841,7 @@ app.registerExtension({
}
const onRemoved = this.onRemoved
this.onRemoved = () => {
cleanupNode(this)
// cleanupNode(this)
return onRemoved?.()
}
}
+199 -184
View File
@@ -1,6 +1,6 @@
{
"last_node_id": 38,
"last_link_id": 52,
"last_node_id": 40,
"last_link_id": 60,
"nodes": [
{
"id": 4,
@@ -284,93 +284,6 @@
"horizontal": false
}
},
{
"id": 14,
"type": "VAEDecode",
"pos": [
2277.0850690937427,
-468.5410711699221
],
"size": {
"0": 210,
"1": 46
},
"flags": {
"collapsed": false
},
"order": 10,
"mode": 0,
"inputs": [
{
"name": "samples",
"type": "LATENT",
"link": 18
},
{
"name": "vae",
"type": "VAE",
"link": 19
}
],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
20,
21,
47
],
"slot_index": 0
}
],
"properties": {
"Node name for S&R": "VAEDecode"
}
},
{
"id": 36,
"type": "ImagesCrop",
"pos": [
3217,
81
],
"size": {
"0": 315,
"1": 154
},
"flags": {},
"order": 22,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 49
}
],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
50
],
"shape": 6,
"slot_index": 0
}
],
"properties": {
"Node name for S&R": "ImagesCrop"
},
"widgets_values": [
512,
512,
0,
0,
"enable"
]
},
{
"id": 22,
"type": "PrimitiveNode",
@@ -457,84 +370,6 @@
"Node name for S&R": "PreviewImage"
}
},
{
"id": 35,
"type": "TransparentImage",
"pos": [
2848,
184
],
"size": {
"0": 315,
"1": 338
},
"flags": {},
"order": 20,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 47
},
{
"name": "masks",
"type": "MASK",
"link": 46
}
],
"outputs": [
{
"name": "STRING",
"type": "STRING",
"links": null,
"shape": 6
},
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
49
],
"shape": 6,
"slot_index": 1
}
],
"properties": {
"Node name for S&R": "TransparentImage"
},
"widgets_values": [
"no",
"yes",
"Mixlab_save"
]
},
{
"id": 31,
"type": "PreviewImage",
"pos": [
3603,
87
],
"size": {
"0": 210,
"1": 246
},
"flags": {},
"order": 23,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 50,
"slot_index": 0
}
],
"properties": {
"Node name for S&R": "PreviewImage"
}
},
{
"id": 2,
"type": "SAMLoader",
@@ -915,7 +750,7 @@
60
],
"size": {
"0": 210,
"0": 243.60000610351562,
"1": 26
},
"flags": {},
@@ -942,6 +777,178 @@
"properties": {
"Node name for S&R": "InvertMask (segment anything)"
}
},
{
"id": 40,
"type": "ImageCropByAlpha",
"pos": [
3365,
-68
],
"size": {
"0": 210,
"1": 46
},
"flags": {},
"order": 22,
"mode": 0,
"inputs": [
{
"name": "image",
"type": "IMAGE",
"link": 60
},
{
"name": "RGBA",
"type": "RGBA",
"link": 56
}
],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
57
],
"shape": 3,
"slot_index": 0
}
],
"properties": {
"Node name for S&R": "ImageCropByAlpha"
}
},
{
"id": 14,
"type": "VAEDecode",
"pos": [
2277.0850690937427,
-468.5410711699221
],
"size": {
"0": 210,
"1": 46
},
"flags": {
"collapsed": false
},
"order": 10,
"mode": 0,
"inputs": [
{
"name": "samples",
"type": "LATENT",
"link": 18
},
{
"name": "vae",
"type": "VAE",
"link": 19
}
],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
20,
21,
47
],
"slot_index": 0
}
],
"properties": {
"Node name for S&R": "VAEDecode"
}
},
{
"id": 31,
"type": "PreviewImage",
"pos": [
3667,
-93
],
"size": {
"0": 210,
"1": 246
},
"flags": {},
"order": 23,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 57,
"slot_index": 0
}
],
"properties": {
"Node name for S&R": "PreviewImage"
}
},
{
"id": 35,
"type": "TransparentImage",
"pos": [
2943,
-54
],
"size": [
315,
358
],
"flags": {},
"order": 20,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 47
},
{
"name": "masks",
"type": "MASK",
"link": 46
}
],
"outputs": [
{
"name": "STRING",
"type": "STRING",
"links": null,
"shape": 6
},
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
60
],
"shape": 6,
"slot_index": 1
},
{
"name": "RGBA",
"type": "RGBA",
"links": [
56
],
"shape": 6,
"slot_index": 2
}
],
"properties": {
"Node name for S&R": "TransparentImage"
},
"widgets_values": [
"no",
"yes",
"Mixlab_save"
]
}
],
"links": [
@@ -1137,22 +1144,6 @@
0,
"IMAGE"
],
[
49,
35,
1,
36,
0,
"IMAGE"
],
[
50,
36,
0,
31,
0,
"IMAGE"
],
[
51,
3,
@@ -1168,6 +1159,30 @@
16,
0,
"MASK"
],
[
56,
35,
2,
40,
1,
"RGBA"
],
[
57,
40,
0,
31,
0,
"IMAGE"
],
[
60,
35,
1,
40,
0,
"IMAGE"
]
],
"groups": [],
+150 -110
View File
@@ -1,6 +1,6 @@
{
"last_node_id": 25,
"last_link_id": 27,
"last_node_id": 28,
"last_link_id": 30,
"nodes": [
{
"id": 7,
@@ -14,7 +14,7 @@
"1": 180.6060791015625
},
"flags": {},
"order": 7,
"order": 8,
"mode": 0,
"inputs": [
{
@@ -52,7 +52,7 @@
"1": 98
},
"flags": {},
"order": 9,
"order": 10,
"mode": 0,
"inputs": [
{
@@ -103,7 +103,7 @@
"1": 164.31304931640625
},
"flags": {},
"order": 6,
"order": 7,
"mode": 0,
"inputs": [
{
@@ -245,7 +245,7 @@
"1": 58.083831787109375
},
"flags": {},
"order": 5,
"order": 6,
"mode": 0,
"inputs": [
{
@@ -272,41 +272,6 @@
"control_v11f1p_sd15_depth.pth"
]
},
{
"id": 24,
"type": "ScreenShare",
"pos": [
-399,
472
],
"size": {
"0": 315,
"1": 202
},
"flags": {},
"order": 1,
"mode": 0,
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
25
],
"shape": 3,
"slot_index": 0
},
{
"name": "MASK",
"type": "MASK",
"links": null,
"shape": 3
}
],
"properties": {
"Node name for S&R": "ScreenShare"
}
},
{
"id": 5,
"type": "EmptyLatentImage",
@@ -319,7 +284,7 @@
"1": 106
},
"flags": {},
"order": 2,
"order": 1,
"mode": 0,
"outputs": [
{
@@ -358,7 +323,7 @@
{
"name": "image",
"type": "IMAGE",
"link": 25
"link": 29
}
],
"outputs": [
@@ -383,46 +348,6 @@
512
]
},
{
"id": 8,
"type": "VAEDecode",
"pos": [
1100,
-241
],
"size": {
"0": 210,
"1": 46
},
"flags": {},
"order": 11,
"mode": 0,
"inputs": [
{
"name": "samples",
"type": "LATENT",
"link": 7
},
{
"name": "vae",
"type": "VAE",
"link": 8
}
],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
17
],
"slot_index": 0
}
],
"properties": {
"Node name for S&R": "VAEDecode"
}
},
{
"id": 3,
"type": "KSampler",
@@ -435,7 +360,7 @@
"1": 262
},
"flags": {},
"order": 10,
"order": 11,
"mode": 0,
"inputs": [
{
@@ -484,24 +409,131 @@
]
},
{
"id": 16,
"type": "PreviewImage",
"id": 8,
"type": "VAEDecode",
"pos": [
1513,
-320
1100,
-241
],
"size": {
"0": 578.1627807617188,
"1": 544.9364013671875
"0": 210,
"1": 46
},
"flags": {},
"order": 12,
"mode": 0,
"inputs": [
{
"name": "samples",
"type": "LATENT",
"link": 7
},
{
"name": "vae",
"type": "VAE",
"link": 8
}
],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
28
],
"slot_index": 0
}
],
"properties": {
"Node name for S&R": "VAEDecode"
}
},
{
"id": 26,
"type": "FloatingVideo",
"pos": [
1689,
-484
],
"size": [
315,
106
],
"flags": {},
"order": 13,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 17
"link": 28
}
],
"properties": {
"Node name for S&R": "FloatingVideo"
}
},
{
"id": 27,
"type": "ScreenShare",
"pos": [
-387,
454
],
"size": {
"0": 315,
"1": 154
},
"flags": {},
"order": 2,
"mode": 0,
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
29,
30
],
"shape": 3,
"slot_index": 0
},
{
"name": "MASK",
"type": "MASK",
"links": null,
"shape": 3
},
{
"name": "STRING",
"type": "STRING",
"links": null,
"shape": 3
}
],
"properties": {
"Node name for S&R": "ScreenShare"
}
},
{
"id": 28,
"type": "PreviewImage",
"pos": [
-393,
975
],
"size": [
210,
246
],
"flags": {},
"order": 5,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 30
}
],
"properties": {
@@ -512,15 +544,15 @@
"id": 20,
"type": "PreviewImage",
"pos": [
1521,
277
492,
955
],
"size": {
"0": 526.9624633789062,
"1": 367.3833923339844
},
"flags": {},
"order": 8,
"order": 9,
"mode": 0,
"inputs": [
{
@@ -607,14 +639,6 @@
0,
"CLIP"
],
[
17,
8,
0,
16,
0,
"IMAGE"
],
[
18,
19,
@@ -647,14 +671,6 @@
0,
"MODEL"
],
[
25,
24,
0,
25,
0,
"IMAGE"
],
[
26,
25,
@@ -670,6 +686,30 @@
20,
0,
"IMAGE"
],
[
28,
8,
0,
26,
0,
"IMAGE"
],
[
29,
27,
0,
25,
0,
"IMAGE"
],
[
30,
27,
0,
28,
0,
"IMAGE"
]
],
"groups": [],
File diff suppressed because it is too large Load Diff