jbilcke-hf HF staff commited on
Commit
7e1bff8
1 Parent(s): 3f9fd43

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +32 -7
app.py CHANGED
@@ -5,7 +5,6 @@ import base64
5
  import uuid
6
 
7
  from diffusers import AnimateDiffPipeline, MotionAdapter, EulerDiscreteScheduler
8
- from diffusers.utils import export_to_video
9
  from huggingface_hub import hf_hub_download
10
  from safetensors.torch import load_file
11
  from PIL import Image
@@ -30,6 +29,32 @@ dtype = torch.float16
30
  pipe = AnimateDiffPipeline.from_pretrained(bases[base_loaded], torch_dtype=dtype).to(device)
31
  pipe.scheduler = EulerDiscreteScheduler.from_config(pipe.scheduler.config, timestep_spacing="trailing", beta_schedule="linear")
32
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  def generate_image(secret_token, prompt, base, width, height, motion, step):
34
  if secret_token != SECRET_TOKEN:
35
  raise gr.Error(
@@ -69,18 +94,18 @@ def generate_image(secret_token, prompt, base, width, height, motion, step):
69
  )
70
 
71
  name = str(uuid.uuid4()).replace("-", "")
72
- path = f"/tmp/{name}.mp4"
73
 
74
- # I think we are looking time here too, converting to mp4 is too slow, we should return
75
  # the frames unencoded to the frontend renderer
76
- export_to_video(output.frames[0], path, fps=10)
77
 
78
  # Read the content of the video file and encode it to base64
79
  with open(path, "rb") as video_file:
80
  video_base64 = base64.b64encode(video_file.read()).decode('utf-8')
81
 
82
  # Prepend the appropriate data URI header with MIME type
83
- video_data_uri = 'data:video/mp4;base64,' + video_base64
84
 
85
  # clean-up (otherwise there is always a risk of "ghosting", eg. someone seeing the previous generated video",
86
  # of one of the steps go wrong)
@@ -94,8 +119,8 @@ with gr.Blocks() as demo:
94
  gr.HTML("""
95
  <div style="z-index: 100; position: fixed; top: 0px; right: 0px; left: 0px; bottom: 0px; width: 100%; height: 100%; background: white; display: flex; align-items: center; justify-content: center; color: black;">
96
  <div style="text-align: center; color: black;">
97
- <p style="color: black;">This space is a REST API to programmatically generate MP4 videos for AiTube, the next generation video platform.</p>
98
- <p style="color: black;">Interested in using it? Look no further than the <a href="https://huggingface.co/spaces/ByteDance/AnimateDiff-Lightning" target="_blank">original space</a>!</p>
99
  </div>
100
  </div>""")
101
 
 
5
  import uuid
6
 
7
  from diffusers import AnimateDiffPipeline, MotionAdapter, EulerDiscreteScheduler
 
8
  from huggingface_hub import hf_hub_download
9
  from safetensors.torch import load_file
10
  from PIL import Image
 
29
  pipe = AnimateDiffPipeline.from_pretrained(bases[base_loaded], torch_dtype=dtype).to(device)
30
  pipe.scheduler = EulerDiscreteScheduler.from_config(pipe.scheduler.config, timestep_spacing="trailing", beta_schedule="linear")
31
 
32
+ import tempfile
33
+ import numpy as np
34
+ import cv2
35
+
36
+ def export_to_video_file(video_frames, output_video_path=None, fps=10):
37
+ if output_video_path is None:
38
+ output_video_path = tempfile.NamedTemporaryFile(suffix=".webm").name
39
+
40
+ if isinstance(video_frames[0], np.ndarray):
41
+ video_frames = [(frame * 255).astype(np.uint8) for frame in video_frames]
42
+ elif isinstance(video_frames[0], Image.Image):
43
+ video_frames = [np.array(frame) for frame in video_frames]
44
+
45
+ # Use VP8 codec
46
+ fourcc = cv2.VideoWriter_fourcc(*'VP80')
47
+ h, w, c = video_frames[0].shape
48
+ video_writer = cv2.VideoWriter(output_video_path, fourcc, fps, (w, h), True)
49
+
50
+ for frame in video_frames:
51
+ # Ensure the video frame is in the correct color format
52
+ img = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
53
+ video_writer.write(img)
54
+ video_writer.release()
55
+
56
+ return output_video_path
57
+
58
  def generate_image(secret_token, prompt, base, width, height, motion, step):
59
  if secret_token != SECRET_TOKEN:
60
  raise gr.Error(
 
94
  )
95
 
96
  name = str(uuid.uuid4()).replace("-", "")
97
+ path = f"/tmp/{name}.webm"
98
 
99
+ # I think we are looking time here too, converting to webm is too slow, we should return
100
  # the frames unencoded to the frontend renderer
101
+ export_to_video_file(output.frames[0], path, fps=10)
102
 
103
  # Read the content of the video file and encode it to base64
104
  with open(path, "rb") as video_file:
105
  video_base64 = base64.b64encode(video_file.read()).decode('utf-8')
106
 
107
  # Prepend the appropriate data URI header with MIME type
108
+ video_data_uri = 'data:video/webm;base64,' + video_base64
109
 
110
  # clean-up (otherwise there is always a risk of "ghosting", eg. someone seeing the previous generated video",
111
  # of one of the steps go wrong)
 
119
  gr.HTML("""
120
  <div style="z-index: 100; position: fixed; top: 0px; right: 0px; left: 0px; bottom: 0px; width: 100%; height: 100%; background: white; display: flex; align-items: center; justify-content: center; color: black;">
121
  <div style="text-align: center; color: black;">
122
+ <p style="color: black;">This space is a headless component of the cloud rendering engine used by AiTube.</p>
123
+ <p style="color: black;">It is not available for public use, but you can use the <a href="https://huggingface.co/spaces/ByteDance/AnimateDiff-Lightning" target="_blank">original space</a>.</p>
124
  </div>
125
  </div>""")
126