HunyuanComfyDiffusionFP8 / run_comfyui.py
JBroDev's picture
Update run_comfyui.py
2a7912b verified
import requests
import json
import time
import argparse
import os
import re
def check_comfyui_started(url):
"""
Checks if ComfyUI is running at the given URL.
"""
try:
response = requests.get(url)
return response.status_code == 200
except requests.ConnectionError:
return False
def load_and_update_prompt(file_path, width, height, length, batch_size, shift_amount, guidance_amount, steps_amount, denoise_amount, frame_rate, prompt):
"""
Loads the prompt payload from a JSON file and updates the specified fields.
Args:
file_path (str): Path to the prompt-payload.json file.
width (int): Width to set in the prompt.
height (int): Height to set in the prompt.
length (int): Length (frames) to set in the prompt.
batch_size (int): Batch size to set in the prompt.
shift_amount (float): Shift amount to set in the prompt.
guidance_amount (float): Guidance amount to set in the prompt.
steps_amount (int): Steps amount to set in the prompt.
denoise_amount (float): Denoise amount to set in the prompt.
frame_rate (int): Frame rate to set in the prompt.
prompt (str): Prompt text to set in the prompt.
Returns:
dict: Updated prompt payload as a dictionary.
"""
try:
with open(file_path, 'r', encoding='utf-8') as f:
payload = json.load(f)
except Exception as e:
print(f"Error loading JSON file: {e}")
return None
# Update width and height
payload['prompt']['232']['inputs']['width'] = width
payload['prompt']['232']['inputs']['height'] = height
# Update length (frames)
payload['prompt']['295']['inputs']['int'] = length
# Update batch size
payload['prompt']['232']['inputs']['batch_size'] = batch_size
# Update shift amount
payload['prompt']['67']['inputs']['shift'] = shift_amount
# Update guidance amount
payload['prompt']['26']['inputs']['guidance'] = guidance_amount
# Update steps amount
payload['prompt']['17']['inputs']['steps'] = steps_amount
# Update denoise amount
payload['prompt']['17']['inputs']['denoise'] = denoise_amount
# Update frame rate
payload['prompt']['82']['inputs']['frame_rate'] = frame_rate
# Update prompt text
payload['prompt']['44']['inputs']['text'] = prompt
return payload
def post_prompt(url, payload):
"""
Posts the prompt payload to the ComfyUI API.
Args:
url (str): ComfyUI API endpoint URL.
payload (dict): Prompt payload as a dictionary.
Returns:
str: Prompt ID if successful, None otherwise.
"""
try:
response = requests.post(url, json=payload)
response.raise_for_status() # Raise HTTPError for bad responses (4xx or 5xx)
return response.json().get('prompt_id')
except requests.exceptions.RequestException as e:
print(f"Error posting prompt: {e}")
return None
def get_queue_progress(url):
"""
Retrieves the queue progress from the ComfyUI API.
Args:
url (str): ComfyUI API queue endpoint URL.
Returns:
tuple: (queue_pending, queue_running) where queue_pending and queue_running are lists,
or (None, None) if an error occurred.
"""
try:
response = requests.get(url)
response.raise_for_status()
queue_data = response.json()
queue_pending = queue_data.get('queue_pending', [])
queue_running = queue_data.get('queue_running', [])
return queue_pending, queue_running
except requests.exceptions.RequestException as e:
print(f"Error getting queue progress: {e}")
return None, None
def get_history(url, prompt_id):
"""
Retrieves the history from the ComfyUI API.
Args:
url (str): ComfyUI API history endpoint URL.
prompt_id (str): Prompt ID to look for in the history.
Returns:
tuple: (status, video_path) where status is a string ("success" or "failure") and video_path is the path to the video,
or (None, None) if an error occurred.
"""
try:
response = requests.get(url)
response.raise_for_status()
history_data = response.json()
if history_data:
# Find the history item with the matching prompt_id
for history_item_id, history_item in history_data.items():
if history_item_id == prompt_id:
status = history_item['status']['status_str']
completed = history_item['status']['completed']
if status == "success" and completed:
try:
for output in history_item['outputs'].values():
for gif in output.get('gifs', []):
video_path = gif['fullpath']
return "success", video_path
except (KeyError, TypeError):
print("Video path not found in history data.")
return "failure", None
else:
print("Video generation failed according to history data.")
return "failure", None
print("Prompt ID not found in history data.")
return "failure", None
else:
print("No history data found.")
return "failure", None
except requests.exceptions.RequestException as e:
print(f"Error getting history: {e}")
return None, None
def extract_video_number(filename):
"""
Extracts the video number from the filename using a regular expression.
"""
match = re.search(r'_(\d+)\.mp4', filename)
if match:
return match.group(1)
return None
def main():
parser = argparse.ArgumentParser(description="Run ComfyUI with specified parameters.")
parser.add_argument("--width", type=int, default=320, help="Width of the generated image.")
parser.add_argument("--height", type=int, default=480, help="Height of the generated image.")
parser.add_argument("--length", type=int, default=45, help="Length (number of frames) of the video.")
parser.add_argument("--batchSize", type=int, default=1, help="Batch size for video generation.")
parser.add_argument("--shiftAmount", type=float, default=9.0, help="Shift amount for ModelSamplingSD3.")
parser.add_argument("--guidanceAmount", type=float, default=7.5, help="Guidance amount for FluxGuidance.")
parser.add_argument("--stepsAmount", type=int, default=12, help="Steps amount for BasicScheduler.")
parser.add_argument("--denoiseAmount", type=float, default=1.0, help="Denoise amount for BasicScheduler.")
parser.add_argument("--frameRate", type=int, default=24, help="Frame rate for video combine.")
parser.add_argument("--prompt", type=str, required=True, help="Text prompt for video generation.")
parser.add_argument("--upscale", type=bool, default=False, help="Whether to use upscale or not.")
parser.add_argument("--comfyui_url", type=str, default="http://localhost:8188", help="ComfyUI base URL.")
args = parser.parse_args()
API_URL = f"{args.comfyui_url}/api/prompt"
QUEUE_URL = f"{args.comfyui_url}/api/queue"
HISTORY_URL = f"{args.comfyui_url}/api/history?max_items=1"
if args.upscale:
prompt_file = "prompt-payload.json"
filename_prefix = "Hunyuan_upscaled"
else:
prompt_file = "prompt-payload-no-upscale.json"
filename_prefix = "Hunyuan_raw"
# Check if ComfyUI is running
print("Checking if ComfyUI is running...")
while not check_comfyui_started(args.comfyui_url):
print("ComfyUI not yet running. Waiting...")
time.sleep(5)
print("ComfyUI is running.")
# Load and update the prompt payload
print("Loading and updating prompt payload...")
prompt_file_path = os.path.join(os.path.dirname(__file__), prompt_file)
try:
prompt_payload = load_and_update_prompt(prompt_file_path, args.width, args.height, args.length, args.batchSize, args.shiftAmount, args.guidanceAmount, args.stepsAmount, args.denoiseAmount, args.frameRate, args.prompt)
except Exception as e:
print(f"Error loading and updating prompt: {e}")
return
# Post the prompt
print("Posting prompt to ComfyUI...")
prompt_id = post_prompt(API_URL, prompt_payload)
if prompt_id:
print(f"Prompt submitted successfully with ID: {prompt_id}")
# Monitor the queue until it's empty
print("Monitoring queue...")
while True:
queue_pending, queue_running = get_queue_progress(QUEUE_URL)
if queue_pending is None or queue_running is None:
print("Failed to get queue progress. Aborting.")
break
if not queue_pending and not queue_running:
print("Queue is empty.")
break
else:
print(f"Queue pending: {len(queue_pending)}, running: {len(queue_running)}. Waiting...")
time.sleep(5)
# Get the history
print("Getting history...")
status, video_path = get_history(HISTORY_URL, prompt_id)
if status == "success":
print(f"Video generation complete! Video path: {video_path}")
video_number = extract_video_number(video_path)
if video_number:
output_filename = f"{filename_prefix}_{video_number}.mp4"
else:
output_filename = f"{filename_prefix}_latest.mp4"
print(output_filename) # Print the output filename
else:
print("Video generation failed.")
else:
print("Failed to submit prompt.")
if __name__ == "__main__":
main()