Spaces:
Runtime error
Runtime error
bethecloud
commited on
Commit
·
ed7b89b
1
Parent(s):
f57cb4a
Create app.py
Browse files
app.py
ADDED
@@ -0,0 +1,154 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import gradio as gr
|
2 |
+
from gradio import Theme
|
3 |
+
|
4 |
+
import os, cv2, torch, time, random
|
5 |
+
import numpy as np
|
6 |
+
from moviepy.editor import *
|
7 |
+
import boto3
|
8 |
+
from botocore.client import Config
|
9 |
+
from botocore.exceptions import NoCredentialsError
|
10 |
+
|
11 |
+
from diffusers import DiffusionPipeline, EulerAncestralDiscreteScheduler
|
12 |
+
from PIL import Image
|
13 |
+
from yt_dlp import YoutubeDL
|
14 |
+
|
15 |
+
pipe = DiffusionPipeline.from_pretrained("timbrooks/instruct-pix2pix", torch_dtype=torch.float16, safety_checker=None)
|
16 |
+
pipe.scheduler = EulerAncestralDiscreteScheduler.from_config(pipe.scheduler.config)
|
17 |
+
pipe.enable_xformers_memory_efficient_attention()
|
18 |
+
pipe.unet.to(memory_format=torch.channels_last)
|
19 |
+
pipe = pipe.to("cuda")
|
20 |
+
|
21 |
+
s3_access_key = "juj22qxqxql7u2pl6nomgxu3ip7a"
|
22 |
+
s3_secret_key = "j3uwidtozhboy5vczhymhzkkjsaumznnqlzck5zjs5qxgsung4ukk"
|
23 |
+
s3_endpoint = "https://gateway.storjshare.io"
|
24 |
+
|
25 |
+
s3 = boto3.client("s3", aws_access_key_id=s3_access_key, aws_secret_access_key=s3_secret_key, endpoint_url=s3_endpoint, config=Config(signature_version="s3v4"))
|
26 |
+
|
27 |
+
my_theme = Theme.from_hub("bethecloud/storj_theme")
|
28 |
+
|
29 |
+
def download_video(url):
|
30 |
+
ydl_opts = {'overwrites':True, 'format':'bestvideo[ext=mp4]+bestaudio[ext=m4a]/mp4', 'outtmpl':'/content/video.mp4'}
|
31 |
+
with YoutubeDL(ydl_opts) as ydl:
|
32 |
+
ydl.download(url)
|
33 |
+
return f"/content/video.mp4"
|
34 |
+
|
35 |
+
def pix2pix(prompt, text_guidance_scale, image_guidance_scale, image, steps, neg_prompt="", width=512, height=512, seed=0):
|
36 |
+
if seed == 0:
|
37 |
+
seed = random.randint(0, 2147483647)
|
38 |
+
generator = torch.Generator("cuda").manual_seed(seed)
|
39 |
+
try:
|
40 |
+
image = Image.open(image)
|
41 |
+
ratio = min(height / image.height, width / image.width)
|
42 |
+
image = image.resize((int(image.width * ratio), int(image.height * ratio)), Image.LANCZOS)
|
43 |
+
result = pipe(
|
44 |
+
prompt,
|
45 |
+
negative_prompt=neg_prompt,
|
46 |
+
image=image,
|
47 |
+
num_inference_steps=int(steps),
|
48 |
+
image_guidance_scale=image_guidance_scale,
|
49 |
+
guidance_scale=text_guidance_scale,
|
50 |
+
generator=generator,
|
51 |
+
)
|
52 |
+
return result.images, result.nsfw_content_detected, seed
|
53 |
+
except Exception as e:
|
54 |
+
return None, None, error_str(e)
|
55 |
+
|
56 |
+
def error_str(error, title="Error"):
|
57 |
+
return (
|
58 |
+
f"""#### {title}
|
59 |
+
{error}"""
|
60 |
+
if error
|
61 |
+
else ""
|
62 |
+
)
|
63 |
+
|
64 |
+
def get_frames(video_in):
|
65 |
+
frames = []
|
66 |
+
clip = VideoFileClip(video_in)
|
67 |
+
if clip.fps > 30:
|
68 |
+
print("vide rate is over 30, resetting to 30")
|
69 |
+
clip_resized = clip.resize(height=512)
|
70 |
+
clip_resized.write_videofile("video_resized.mp4", fps=30, verbose=False)
|
71 |
+
else:
|
72 |
+
print("video rate is OK")
|
73 |
+
clip_resized = clip.resize(height=512)
|
74 |
+
clip_resized.write_videofile("video_resized.mp4", fps=clip.fps, verbose=False)
|
75 |
+
print("video resized to 512 height")
|
76 |
+
cap= cv2.VideoCapture("video_resized.mp4")
|
77 |
+
fps = cap.get(cv2.CAP_PROP_FPS)
|
78 |
+
print("video fps: " + str(fps))
|
79 |
+
i=0
|
80 |
+
while(cap.isOpened()):
|
81 |
+
ret, frame = cap.read()
|
82 |
+
if ret == False:
|
83 |
+
break
|
84 |
+
cv2.imwrite('in'+str(i)+'.jpg',frame)
|
85 |
+
frames.append('in'+str(i)+'.jpg')
|
86 |
+
i+=1
|
87 |
+
cap.release()
|
88 |
+
cv2.destroyAllWindows()
|
89 |
+
print("broke the video into frames")
|
90 |
+
return frames, fps
|
91 |
+
|
92 |
+
def create_video(frames, fps):
|
93 |
+
clips = [ImageClip(m).set_duration(1 / fps) for m in frames]
|
94 |
+
concat_clip = concatenate_videoclips(clips, method="compose")
|
95 |
+
concat_clip.write_videofile("/content/output.mp4", fps=fps, verbose=False)
|
96 |
+
return "/content/output.mp4"
|
97 |
+
|
98 |
+
|
99 |
+
def infer(prompt,video_in, seed_in, trim_value):
|
100 |
+
print(prompt)
|
101 |
+
break_vid = get_frames(video_in)
|
102 |
+
frames_list= break_vid[0]
|
103 |
+
fps = break_vid[1]
|
104 |
+
n_frame = int(trim_value*fps)
|
105 |
+
if n_frame >= len(frames_list):
|
106 |
+
print("video is shorter than the cut value")
|
107 |
+
n_frame = len(frames_list)
|
108 |
+
result_frames = []
|
109 |
+
print("set stop frames to: " + str(n_frame))
|
110 |
+
for i in frames_list[0:int(n_frame)]:
|
111 |
+
pix2pix_img = pix2pix(prompt,5.5,1.5,i,15,"",512,512,seed_in)
|
112 |
+
images = pix2pix_img[0]
|
113 |
+
rgb_im = images[0].convert("RGB")
|
114 |
+
rgb_im.save(f"out-{i}.jpg")
|
115 |
+
result_frames.append(f"out-{i}.jpg")
|
116 |
+
print("frame " + i + "/" + str(n_frame) + ": done;")
|
117 |
+
final_vid = create_video(result_frames, fps)
|
118 |
+
print("Done!")
|
119 |
+
return final_vid
|
120 |
+
|
121 |
+
def upload_to_storj(bucket_name, file_path):
|
122 |
+
try:
|
123 |
+
file_name = os.path.basename(file_path)
|
124 |
+
s3.upload_file(file_path, bucket_name, file_name)
|
125 |
+
print(f"{file_name} uploaded to {bucket_name}")
|
126 |
+
except NoCredentialsError:
|
127 |
+
print("Credentials not available")
|
128 |
+
|
129 |
+
with gr.Blocks(theme=my_theme) as demo:
|
130 |
+
with gr.Column(elem_id="col-container"):
|
131 |
+
with gr.Row():
|
132 |
+
with gr.Column():
|
133 |
+
input_text = gr.Textbox(show_label=False, value="https://link.storjshare.io/s/jwn3ljgyj4ynlg6qtqj6yrbo63ha/demo/dancing.mp4?view")
|
134 |
+
input_download_button = gr.Button(value="Enter a link from Storj Linkshare")
|
135 |
+
prompt = gr.Textbox(label="Prompt", placeholder="Enter new style of video", show_label=False, elem_id="prompt-in")
|
136 |
+
video_inp = gr.Video(label="Video source", source="upload", type="filepath", elem_id="input-vid")
|
137 |
+
input_download_button.click(download_video, inputs=[input_text], outputs=[video_inp])
|
138 |
+
with gr.Column():
|
139 |
+
video_out = gr.Video(label="Pix2pix video result", type="filepath", elem_id="video-output")
|
140 |
+
with gr.Row():
|
141 |
+
seed_inp = gr.Slider(label="Seed", minimum=0, maximum=2147483647, step=1, value=69)
|
142 |
+
trim_in = gr.Slider(label="Cut video at (s)", minimun=1, maximum=600, step=1, value=1)
|
143 |
+
submit_btn = gr.Button("Generate transformed video with Storj")
|
144 |
+
inputs = [prompt,video_inp,seed_inp, trim_in]
|
145 |
+
def process_and_upload(prompt, video_inp, seed_inp, trim_in):
|
146 |
+
final_vid = infer(prompt, video_inp, seed_inp, trim_in)
|
147 |
+
# Specify the name of the bucket to upload to
|
148 |
+
storj_bucket_name = "huggingface-demo"
|
149 |
+
upload_to_storj(storj_bucket_name, final_vid)
|
150 |
+
return final_vid
|
151 |
+
|
152 |
+
submit_btn.click(process_and_upload, inputs=inputs, outputs=[video_out])
|
153 |
+
demo.queue().launch(debug=True, share=True, inline=False)
|
154 |
+
%cd /content/temp
|