Spaces:
Runtime error
Runtime error
| import uuid | |
| import torch | |
| from diffusers.utils import export_to_video | |
| from diffusers import AutoencoderKLWan, WanPipeline | |
| from diffusers.schedulers.scheduling_unipc_multistep import UniPCMultistepScheduler | |
| import os | |
| import time | |
| import requests | |
| import json | |
| from PIL import Image as PIL_Image | |
| from google import genai | |
| from google.genai import types | |
| from google.cloud import aiplatform | |
| from google.cloud import storage | |
| import matplotlib.pyplot as plt | |
| import mediapy as media | |
| def wan_text_to_video(prompt, negative_prompt): | |
| # Available models: Wan-AI/Wan2.1-T2V-14B-Diffusers, Wan-AI/Wan2.1-T2V-1.3B-Diffusers | |
| # model_id = "Wan-AI/Wan2.1-T2V-14B-Diffusers" | |
| model_id = "Wan-AI/Wan2.1-T2V-1.3B-Diffusers" | |
| vae = AutoencoderKLWan.from_pretrained(model_id, subfolder="vae", torch_dtype=torch.float32) | |
| flow_shift = 5.0 # 5.0 for 720P, 3.0 for 480P | |
| scheduler = UniPCMultistepScheduler(prediction_type='flow_prediction', use_flow_sigmas=True, num_train_timesteps=1000, flow_shift=flow_shift) | |
| pipe = WanPipeline.from_pretrained(model_id, vae=vae, torch_dtype=torch.bfloat16) | |
| pipe.scheduler = scheduler | |
| pipe.to("cpu") | |
| prompt = ("A cat and a dog baking a cake together in a kitchen. The cat is carefully measuring flour, while the " | |
| "dog is stirring the batter with a wooden spoon. The kitchen is cozy, with sunlight streaming through " | |
| "the window.") | |
| negative_prompt = ("Bright tones, overexposed, static, blurred details, subtitles, style, works, paintings, " | |
| "images, static, overall gray, worst quality, low quality, JPEG compression residue, ugly, " | |
| "incomplete, extra fingers, poorly drawn hands, poorly drawn faces, deformed, disfigured, " | |
| "misshapen limbs, fused fingers, still picture, messy background, three legs, many people in " | |
| "the background, walking backwards") | |
| output = pipe( | |
| prompt=prompt, | |
| negative_prompt=negative_prompt, | |
| height=720, | |
| width=1280, | |
| num_frames=81, | |
| guidance_scale=5.0, | |
| ).frames[0] | |
| export_to_video(output, "output.mp4", fps=16) | |
| return "output.mp4" | |
| def gcp_veo(prompt: str = "a cat reading a book"): | |
| PROJECT_ID = "gcp-credit-applying-to-g-suite" | |
| LOCATION = os.environ.get("GOOGLE_CLOUD_REGION", "us-central1") | |
| BUCKET_NAME = "dante-test-123456-output" | |
| OUTPUT_GCS_PATH = f"gs://{BUCKET_NAME}/videos/output_{int(time.time())}.mp4" | |
| # Initialize Vertex AI | |
| aiplatform.init(project=PROJECT_ID, location=LOCATION) | |
| # Initialize Generative AI client | |
| client = genai.Client(vertexai=True, project=PROJECT_ID, location=LOCATION) | |
| # Video Generation Pipeline | |
| video_model = "veo-2.0-generate-001" | |
| # video_model = "veo-3.0-generate-preview" | |
| aspect_ratio = "16:9" | |
| operation = client.models.generate_videos( | |
| model=video_model, | |
| prompt=prompt, | |
| config=types.GenerateVideosConfig( | |
| aspect_ratio=aspect_ratio, | |
| output_gcs_uri=OUTPUT_GCS_PATH, | |
| number_of_videos=1, | |
| duration_seconds=5, | |
| person_generation="allow_adult", | |
| enhance_prompt=True, | |
| ), | |
| ) | |
| # Poll until operation is complete | |
| print("Generating video...") | |
| while not operation.done: | |
| time.sleep(15) | |
| operation = client.operations.get(operation) | |
| print(f"Operation status: {operation}") | |
| # Error Handling | |
| if operation.error: | |
| raise Exception(f"Video generation failed: {operation.error}") | |
| # Get the generated video URI | |
| if operation.response and operation.result.generated_videos: | |
| video_uri = operation.result.generated_videos[0].video.uri | |
| print(f"Video generated at: {video_uri}") | |
| # Download the video from GCS to local | |
| storage_client = storage.Client(project=PROJECT_ID) | |
| bucket = storage_client.bucket(BUCKET_NAME) | |
| blob_name = video_uri.replace(f"gs://{BUCKET_NAME}/", "") | |
| blob = bucket.blob(blob_name) | |
| local_output_path = f"output/sample-{uuid.uuid1()}.mp4" | |
| # Ensure local directory exists | |
| os.makedirs(os.path.dirname(local_output_path), exist_ok=True) | |
| # Download the video | |
| blob.download_to_filename(local_output_path) | |
| print(f"Video downloaded to: {local_output_path}") | |
| # Delete the file from GCS | |
| blob.delete() | |
| print(f"Video deleted from GCS: {video_uri}") | |
| return local_output_path | |
| else: | |
| raise Exception("No video generated or response is empty") | |
| def hailuo_text_to_video( | |
| prompt: str, | |
| model: str = "T2V-01-Director", | |
| output_file_name: str = "output.mp4", | |
| api_key: str = "" | |
| ) -> str: | |
| def invoke_video_generation()->str: | |
| print("-----------------Submit video generation task-----------------") | |
| url = "https://api.minimaxi.chat/v1/video_generation" | |
| payload = json.dumps({ | |
| "prompt": prompt, | |
| "model": model | |
| }) | |
| headers = { | |
| 'authorization': 'Bearer ' + api_key, | |
| 'content-type': 'application/json', | |
| } | |
| response = requests.request("POST", url, headers=headers, data=payload) | |
| print(response.text) | |
| task_id = response.json()['task_id'] | |
| print("Video generation task submitted successfully, task ID.:"+task_id) | |
| return task_id | |
| def query_video_generation(task_id: str): | |
| url = "https://api.minimaxi.chat/v1/query/video_generation?task_id="+task_id | |
| headers = { | |
| 'authorization': 'Bearer ' + api_key | |
| } | |
| response = requests.request("GET", url, headers=headers) | |
| status = response.json()['status'] | |
| if status == 'Preparing': | |
| print("...Preparing...") | |
| return "", 'Preparing' | |
| elif status == 'Queueing': | |
| print("...In the queue...") | |
| return "", 'Queueing' | |
| elif status == 'Processing': | |
| print("...Generating...") | |
| return "", 'Processing' | |
| elif status == 'Success': | |
| return response.json()['file_id'], "Finished" | |
| elif status == 'Fail': | |
| return "", "Fail" | |
| else: | |
| return "", "Unknown" | |
| def fetch_video_result(file_id: str): | |
| print("---------------Video generated successfully, downloading now---------------") | |
| url = "https://api.minimaxi.chat/v1/files/retrieve?file_id="+file_id | |
| headers = { | |
| 'authorization': 'Bearer '+api_key, | |
| } | |
| response = requests.request("GET", url, headers=headers) | |
| print(response.text) | |
| download_url = response.json()['file']['download_url'] | |
| print("Video download link:" + download_url) | |
| with open(output_file_name, 'wb') as f: | |
| f.write(requests.get(download_url).content) | |
| print("THe video has been downloaded in:"+os.getcwd()+'/'+output_file_name) | |
| task_id = invoke_video_generation() | |
| print("-----------------Video generation task submitted -----------------") | |
| while True: | |
| time.sleep(10) | |
| file_id, status = query_video_generation(task_id) | |
| if file_id != "": | |
| fetch_video_result(file_id) | |
| print("---------------Successful---------------") | |
| break | |
| elif status == "Fail" or status == "Unknown": | |
| print("---------------Failed---------------") | |
| break | |
| return os.getcwd()+'/'+output_file_name | |
| def generate_video(prompt, model_id, negative_prompt=None): | |
| video_path = None | |
| if model_id == "Wan2.1": | |
| video_path = wan_text_to_video(prompt, negative_prompt) | |
| elif model_id == "SkyReels-V2": | |
| raise ValueError("SkyReels-V2 model not yet implemented.") | |
| elif model_id == "Veo-2": | |
| video_path = gcp_veo(prompt) | |
| elif model_id == "T2V-01-Director": | |
| video_path = hailuo_text_to_video(prompt) | |
| return video_path | |
| # Only available for cuda / cpu | |
| # wan_text_to_video() | |
| # if __name__ == "__main__": | |
| # try: | |
| # local_path = gcp_veo_3( | |
| # prompt="a cat reading a book", | |
| # local_output_path="output/cat_reading_book.mp4" | |
| # ) | |
| # print(f"Success! Video saved at: {local_path}") | |
| # except Exception as e: | |
| # print(f"Error: {e}") | |