Muhammad Waqas commited on
Commit
0e95549
·
1 Parent(s): 78e3b99

Added: Generate image to video

Browse files
Dockerfile CHANGED
@@ -39,4 +39,5 @@ USER flaskuser
39
  EXPOSE 7860
40
 
41
  # Run the Flask app using gunicorn with an infinite request timeout
42
- CMD ["gunicorn", "--bind", "0.0.0.0:7860", "--timeout", "0", "app:app"]
 
 
39
  EXPOSE 7860
40
 
41
  # Run the Flask app using gunicorn with an infinite request timeout
42
+ # CMD ["gunicorn", "--bind", "0.0.0.0:7860", "--timeout", "0", "app:app"]
43
+ CMD ["gunicorn", "--bind", "0.0.0.0:7860", "--timeout", "0", "--access-logfile", "-", "--error-logfile", "-", "app:app"]
app.py CHANGED
@@ -261,8 +261,8 @@ def get_video_data(filename, subfolder, token):
261
  ##################################################
262
 
263
  # Route: Image to Video
264
- @app.route('/image_to_video', methods=['POST'])
265
- def image_to_video():
266
  data = request.json
267
 
268
  # Extract and validate token
@@ -273,9 +273,21 @@ def image_to_video():
273
 
274
  # Validate text prompt
275
  text_prompt = data.get('text_prompt')
276
- if not text_prompt:
 
277
  return jsonify({'error': 'Text prompt is required'}), 400
278
 
 
 
 
 
 
 
 
 
 
 
 
279
  # Handle uploaded image or base64 image
280
  image_file = request.files.get('image')
281
  base64_image = data.get('base64_image')
@@ -322,8 +334,9 @@ def image_to_video():
322
 
323
  # Modify workflow with inputs
324
  workflow["30"]["inputs"]["prompt"] = text_prompt
 
325
  workflow["73"]["inputs"]["url"] = image_url
326
- workflow["31"]["inputs"]["prompt"] = "Low quality, watermark, strange motion"
327
 
328
  # WebSocket connection to queue the prompt
329
  ws = websocket.WebSocket()
@@ -345,9 +358,9 @@ def image_to_video():
345
  # os.remove(image_path)
346
  # print(f"Deleted temporary image: {image_path}", flush=True)
347
 
348
- # Get video route
349
- @app.route('/get_video/<prompt_id>', methods=['GET'])
350
- def get_video(prompt_id):
351
  token = request.headers.get('Authorization')
352
  if not token or not token.startswith("Bearer "):
353
  return jsonify({'error': 'Valid Bearer token required'}), 400
@@ -408,8 +421,8 @@ def get_video(prompt_id):
408
  return jsonify({'error': str(e)}), 500
409
 
410
  # Route: Image to Video old
411
- @app.route('/v1/image_to_video', methods=['POST'])
412
- def v1_image_to_video():
413
  data = request.json
414
 
415
  # Extract and validate token
@@ -420,9 +433,21 @@ def v1_image_to_video():
420
 
421
  # Validate text prompt
422
  text_prompt = data.get('text_prompt')
423
- if not text_prompt:
 
424
  return jsonify({'error': 'Text prompt is required'}), 400
425
 
 
 
 
 
 
 
 
 
 
 
 
426
  # Handle uploaded image or base64 image
427
  image_file = request.files.get('image')
428
  base64_image = data.get('base64_image')
@@ -469,6 +494,7 @@ def v1_image_to_video():
469
 
470
  # Modify workflow with inputs
471
  workflow["30"]["inputs"]["prompt"] = text_prompt
 
472
  workflow["73"]["inputs"]["url"] = image_url
473
  workflow["31"]["inputs"]["prompt"] = "Low quality, watermark, strange motion"
474
 
@@ -518,8 +544,10 @@ def v1_image_to_video():
518
  local_video_path = f"static/generated_image_to_video_{prompt_id}.mp4"
519
  with open(local_video_path, 'wb') as f:
520
  f.write(video_data)
 
521
  # Construct the public URL for the video
522
- video_url = f"https://gosign-de-comfyui-api.hf.space/{local_video_path}"
 
523
 
524
  # Prepare the response with the video URL
525
  # response_data = {
 
261
  ##################################################
262
 
263
  # Route: Image to Video
264
+ @app.route('/v1/image_to_video', methods=['POST'])
265
+ def v1_image_to_video():
266
  data = request.json
267
 
268
  # Extract and validate token
 
273
 
274
  # Validate text prompt
275
  text_prompt = data.get('text_prompt')
276
+ frame_rate = data.get('frame_rate')
277
+ if not text_prompt or not text_prompt.strip():
278
  return jsonify({'error': 'Text prompt is required'}), 400
279
 
280
+ # Check if frame_rate is missing or invalid
281
+ if not frame_rate: # If frame_rate is None, empty, or 0
282
+ frame_rate = 24 # Default to 24 fps
283
+ else:
284
+ try:
285
+ frame_rate = int(frame_rate)
286
+ if frame_rate not in [8, 12, 24]: # Ensure it's one of the allowed values
287
+ return jsonify({'error': 'Frame rate must be a valid number (8, 12, or 24).'}), 400
288
+ except ValueError:
289
+ return jsonify({'error': 'Frame rate must be a valid number (8, 12, or 24).'}), 400
290
+
291
  # Handle uploaded image or base64 image
292
  image_file = request.files.get('image')
293
  base64_image = data.get('base64_image')
 
334
 
335
  # Modify workflow with inputs
336
  workflow["30"]["inputs"]["prompt"] = text_prompt
337
+ workflow["44"]["inputs"]["frame_rate"] = frame_rate
338
  workflow["73"]["inputs"]["url"] = image_url
339
+ workflow["31"]["inputs"]["prompt"] = "Low quality, watermark, strange motion, blur"
340
 
341
  # WebSocket connection to queue the prompt
342
  ws = websocket.WebSocket()
 
358
  # os.remove(image_path)
359
  # print(f"Deleted temporary image: {image_path}", flush=True)
360
 
361
+ # Get video_tasks route
362
+ @app.route('/v1/video_tasks/<prompt_id>', methods=['GET'])
363
+ def video_tasks(prompt_id):
364
  token = request.headers.get('Authorization')
365
  if not token or not token.startswith("Bearer "):
366
  return jsonify({'error': 'Valid Bearer token required'}), 400
 
421
  return jsonify({'error': str(e)}), 500
422
 
423
  # Route: Image to Video old
424
+ @app.route('/image_to_video', methods=['POST'])
425
+ def image_to_video():
426
  data = request.json
427
 
428
  # Extract and validate token
 
433
 
434
  # Validate text prompt
435
  text_prompt = data.get('text_prompt')
436
+ frame_rate = data.get('frame_rate')
437
+ if not text_prompt or not text_prompt.strip():
438
  return jsonify({'error': 'Text prompt is required'}), 400
439
 
440
+ # Check if frame_rate is missing or invalid
441
+ if not frame_rate: # If frame_rate is None, empty, or 0
442
+ frame_rate = 24 # Default to 24 fps
443
+ else:
444
+ try:
445
+ frame_rate = int(frame_rate)
446
+ if frame_rate not in [8, 12, 24]:
447
+ return jsonify({'error': 'Frame rate must be a valid number (8, 12, or 24).'}), 400
448
+ except ValueError:
449
+ return jsonify({'error': 'Frame rate must be a valid number (8, 12, or 24).'}), 400
450
+
451
  # Handle uploaded image or base64 image
452
  image_file = request.files.get('image')
453
  base64_image = data.get('base64_image')
 
494
 
495
  # Modify workflow with inputs
496
  workflow["30"]["inputs"]["prompt"] = text_prompt
497
+ workflow["44"]["inputs"]["frame_rate"] = frame_rate
498
  workflow["73"]["inputs"]["url"] = image_url
499
  workflow["31"]["inputs"]["prompt"] = "Low quality, watermark, strange motion"
500
 
 
544
  local_video_path = f"static/generated_image_to_video_{prompt_id}.mp4"
545
  with open(local_video_path, 'wb') as f:
546
  f.write(video_data)
547
+
548
  # Construct the public URL for the video
549
+
550
+ # video_url = f"https://gosign-de-comfyui-api.hf.space/{local_video_path}"
551
 
552
  # Prepare the response with the video URL
553
  # response_data = {
workflows/cogvideox_image_to_video_workflow_api.json CHANGED
@@ -17,7 +17,6 @@
17
  "clip_name": "t5\\google_t5-v1_1-xxl_encoderonly-fp8_e4m3fn.safetensors",
18
  "type": "sd3"
19
  },
20
- "class_type": "CLIPLoader",
21
  "_meta": {
22
  "title": "Load CLIP"
23
  }
@@ -72,7 +71,7 @@
72
  },
73
  "44": {
74
  "inputs": {
75
- "frame_rate": 12,
76
  "loop_count": 0,
77
  "filename_prefix": "CogVideoX-I2V",
78
  "format": "video/h264-mp4",
 
17
  "clip_name": "t5\\google_t5-v1_1-xxl_encoderonly-fp8_e4m3fn.safetensors",
18
  "type": "sd3"
19
  },
 
20
  "_meta": {
21
  "title": "Load CLIP"
22
  }
 
71
  },
72
  "44": {
73
  "inputs": {
74
+ "frame_rate": 24,
75
  "loop_count": 0,
76
  "filename_prefix": "CogVideoX-I2V",
77
  "format": "video/h264-mp4",