codelion commited on
Commit
ec68305
·
verified ·
1 Parent(s): 3d23cb0

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +134 -27
app.py CHANGED
@@ -17,7 +17,7 @@ except KeyError:
17
  raise ValueError("Please set the GEMINI_API_KEY environment variable.")
18
  client = genai.Client(api_key=api_key)
19
 
20
- # Define safety settings to disable all filters
21
  SAFETY_SETTINGS = [
22
  types.SafetySetting(
23
  category=types.HarmCategory.HARM_CATEGORY_HARASSMENT,
@@ -184,6 +184,11 @@ def generate_item(user_input, ideas, generate_video=False, max_retries=3):
184
  total_attempts += 1
185
 
186
  # Step 1: Generate an image (retry up to max_retries times)
 
 
 
 
 
187
  for image_attempt in range(max_retries):
188
  selected_idea = random.choice(ideas)
189
  prompt = f"""
@@ -225,8 +230,7 @@ def generate_item(user_input, ideas, generate_video=False, max_retries=3):
225
  prompt=image_prompt,
226
  config=types.GenerateImagesConfig(
227
  aspect_ratio="9:16",
228
- number_of_images=1,
229
- safety_settings=SAFETY_SETTINGS
230
  )
231
  )
232
  if imagen.generated_images and len(imagen.generated_images) > 0:
@@ -244,8 +248,9 @@ def generate_item(user_input, ideas, generate_video=False, max_retries=3):
244
  else:
245
  print(f"Image generation failed (image attempt {image_attempt + 1}, total attempt {total_attempts}): No images returned")
246
  if image_attempt == max_retries - 1:
247
- # Last image attempt in this cycle, use a gray placeholder if max total attempts not reached
248
  if total_attempts == max_total_attempts:
 
249
  image = Image.new('RGB', (360, 640), color='gray')
250
  buffered = BytesIO()
251
  image.save(buffered, format="PNG")
@@ -256,8 +261,8 @@ def generate_item(user_input, ideas, generate_video=False, max_retries=3):
256
  'video_base64': None,
257
  'ideas': ideas
258
  }
259
- # Otherwise, select a new idea and retry image generation in the next cycle
260
- continue
261
  except Exception as e:
262
  print(f"Error generating image (image attempt {image_attempt + 1}, total attempt {total_attempts}): {e}")
263
  if image_attempt == max_retries - 1:
@@ -274,12 +279,15 @@ def generate_item(user_input, ideas, generate_video=False, max_retries=3):
274
  'video_base64': None,
275
  'ideas': ideas
276
  }
277
- # Otherwise, select a new idea and retry image generation in the next cycle
278
- continue
279
 
280
  # Step 2: Generate video if enabled (with retries using the same image)
281
- if generate_video:
282
  max_video_retries_per_image = 2 # Try video generation twice per image
 
 
 
283
  for video_attempt in range(max_video_retries_per_image):
284
  try:
285
  # Base video prompt
@@ -297,7 +305,7 @@ def generate_item(user_input, ideas, generate_video=False, max_retries=3):
297
  Use a static close-up shot of the subject in a realistic style.
298
  """
299
 
300
- print(f"Attempting video generation (video attempt {video_attempt + 1}, total attempt {total_attempts}): {video_prompt}")
301
  operation = client.models.generate_videos(
302
  model="veo-2.0-generate-001",
303
  prompt=video_prompt,
@@ -306,8 +314,7 @@ def generate_item(user_input, ideas, generate_video=False, max_retries=3):
306
  aspect_ratio="9:16",
307
  number_of_videos=1,
308
  duration_seconds=8,
309
- negative_prompt="blurry, low quality, text, letters",
310
- safety_settings=SAFETY_SETTINGS
311
  )
312
  )
313
  # Wait for video to generate
@@ -361,6 +368,7 @@ def generate_item(user_input, ideas, generate_video=False, max_retries=3):
361
  video_bytes = video_buffer.getvalue()
362
  # Encode the video bytes as base64
363
  video_base64 = base64.b64encode(video_bytes).decode()
 
364
  # Successfully generated video, return the result
365
  return {
366
  'text': text,
@@ -371,29 +379,128 @@ def generate_item(user_input, ideas, generate_video=False, max_retries=3):
371
  else:
372
  raise ValueError("No video was generated")
373
  except Exception as e:
374
- print(f"Error generating video (video attempt {video_attempt + 1}, total attempt {total_attempts}): {e}")
375
  if video_attempt == max_video_retries_per_image - 1:
376
- if total_attempts == max_total_attempts:
377
- print("Max total attempts reached. Proceeding without video.")
378
- video_base64 = None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
379
  return {
380
  'text': text,
381
  'image_base64': img_str,
382
  'video_base64': video_base64,
383
  'ideas': ideas
384
  }
385
- # Video generation failed with this image, break to outer loop to try a new image
386
- print(f"Video generation failed after {max_video_retries_per_image} attempts with this image. Selecting a new idea and generating a new image.")
387
- break
388
- continue # Retry video generation with the same image but a modified prompt
 
 
 
 
 
 
 
 
 
 
 
 
 
 
389
 
390
- # If video generation is not enabled or succeeded, return the result
391
- return {
392
- 'text': text,
393
- 'image_base64': img_str,
394
- 'video_base64': video_base64,
395
- 'ideas': ideas
396
- }
 
 
397
 
398
  # If max total attempts reached without success, use a gray placeholder image
399
  print("Max total attempts reached without successful image generation. Using placeholder.")
 
17
  raise ValueError("Please set the GEMINI_API_KEY environment variable.")
18
  client = genai.Client(api_key=api_key)
19
 
20
+ # Define safety settings to disable all filters for content generation
21
  SAFETY_SETTINGS = [
22
  types.SafetySetting(
23
  category=types.HarmCategory.HARM_CATEGORY_HARASSMENT,
 
184
  total_attempts += 1
185
 
186
  # Step 1: Generate an image (retry up to max_retries times)
187
+ generated_image = None # Initialize to None
188
+ text = None
189
+ img_str = None
190
+ image_prompt = None
191
+
192
  for image_attempt in range(max_retries):
193
  selected_idea = random.choice(ideas)
194
  prompt = f"""
 
230
  prompt=image_prompt,
231
  config=types.GenerateImagesConfig(
232
  aspect_ratio="9:16",
233
+ number_of_images=1
 
234
  )
235
  )
236
  if imagen.generated_images and len(imagen.generated_images) > 0:
 
248
  else:
249
  print(f"Image generation failed (image attempt {image_attempt + 1}, total attempt {total_attempts}): No images returned")
250
  if image_attempt == max_retries - 1:
251
+ # Last image attempt in this cycle
252
  if total_attempts == max_total_attempts:
253
+ # Max total attempts reached, use a gray placeholder
254
  image = Image.new('RGB', (360, 640), color='gray')
255
  buffered = BytesIO()
256
  image.save(buffered, format="PNG")
 
261
  'video_base64': None,
262
  'ideas': ideas
263
  }
264
+ # Otherwise, continue to next cycle
265
+ break # Exit inner loop to retry with new idea
266
  except Exception as e:
267
  print(f"Error generating image (image attempt {image_attempt + 1}, total attempt {total_attempts}): {e}")
268
  if image_attempt == max_retries - 1:
 
279
  'video_base64': None,
280
  'ideas': ideas
281
  }
282
+ # Otherwise, continue to next cycle
283
+ break # Exit inner loop to retry with new idea
284
 
285
  # Step 2: Generate video if enabled (with retries using the same image)
286
+ if generate_video and generated_image is not None:
287
  max_video_retries_per_image = 2 # Try video generation twice per image
288
+ video_generated = False
289
+
290
+ # First, try image-to-video generation
291
  for video_attempt in range(max_video_retries_per_image):
292
  try:
293
  # Base video prompt
 
305
  Use a static close-up shot of the subject in a realistic style.
306
  """
307
 
308
+ print(f"Attempting image-to-video generation (video attempt {video_attempt + 1}, total attempt {total_attempts}): {video_prompt}")
309
  operation = client.models.generate_videos(
310
  model="veo-2.0-generate-001",
311
  prompt=video_prompt,
 
314
  aspect_ratio="9:16",
315
  number_of_videos=1,
316
  duration_seconds=8,
317
+ negative_prompt="blurry, low quality, text, letters"
 
318
  )
319
  )
320
  # Wait for video to generate
 
368
  video_bytes = video_buffer.getvalue()
369
  # Encode the video bytes as base64
370
  video_base64 = base64.b64encode(video_bytes).decode()
371
+ video_generated = True
372
  # Successfully generated video, return the result
373
  return {
374
  'text': text,
 
379
  else:
380
  raise ValueError("No video was generated")
381
  except Exception as e:
382
+ print(f"Error generating video (image-to-video attempt {video_attempt + 1}, total attempt {total_attempts}): {e}")
383
  if video_attempt == max_video_retries_per_image - 1:
384
+ print("Image-to-video generation failed after all attempts. Falling back to text-to-video generation.")
385
+ break
386
+ continue # Retry image-to-video generation with a modified prompt
387
+
388
+ # If image-to-video generation failed, try text-to-video generation
389
+ if not video_generated:
390
+ for video_attempt in range(max_video_retries_per_image):
391
+ try:
392
+ # Use the same video prompt but without the image
393
+ video_prompt_base = f"""
394
+ The user concept is "{user_input}". Based on this and the scene: {image_prompt}, create a video.
395
+ Use a close-up shot with a slow dolly shot circling around the subject,
396
+ using shallow focus on the main subject to emphasize details, in a realistic style with cinematic lighting.
397
+ """
398
+ if video_attempt == 0:
399
+ video_prompt = video_prompt_base
400
+ else:
401
+ video_prompt = f"""
402
+ The user concept is "{user_input}". Based on this and a simplified scene: {image_prompt}, create a video.
403
+ Use a static close-up shot of the subject in a realistic style.
404
+ """
405
+
406
+ print(f"Attempting text-to-video generation (video attempt {video_attempt + 1}, total attempt {total_attempts}): {video_prompt}")
407
+ operation = client.models.generate_videos(
408
+ model="veo-2.0-generate-001",
409
+ prompt=video_prompt,
410
+ config=types.GenerateVideosConfig(
411
+ aspect_ratio="9:16",
412
+ number_of_videos=1,
413
+ duration_seconds=8,
414
+ negative_prompt="blurry, low quality, text, letters"
415
+ )
416
+ )
417
+ # Wait for video to generate
418
+ while not operation.done:
419
+ time.sleep(20)
420
+ operation = client.operations.get(operation)
421
+
422
+ # Log detailed information about the operation
423
+ print(f"Video generation operation completed: {operation}")
424
+ print(f"Operation done: {operation.done}")
425
+ print(f"Operation error: {operation.error}")
426
+ if operation.error:
427
+ print(f"Operation error message: {operation.error.message}")
428
+ if hasattr(operation.error, 'code'):
429
+ print(f"Operation error code: {operation.error.code}")
430
+ if hasattr(operation.error, 'details'):
431
+ print(f"Operation error details: {operation.error.details}")
432
+ print(f"Operation response: {operation.response}")
433
+ if operation.response:
434
+ print(f"Operation response has generated_videos: {hasattr(operation.response, 'generated_videos')}")
435
+ if hasattr(operation.response, 'generated_videos'):
436
+ print(f"Generated videos: {operation.response.generated_videos}")
437
+ else:
438
+ print("No generated_videos attribute in response")
439
+
440
+ # Enhanced error handling for video generation response
441
+ if operation.error:
442
+ raise ValueError(f"Video generation operation failed with error: {operation.error.message}")
443
+ if operation.response is None:
444
+ raise ValueError("Video generation operation failed: No response")
445
+ if not hasattr(operation.response, 'generated_videos') or operation.response.generated_videos is None:
446
+ raise ValueError("Video generation operation failed: No generated_videos in response")
447
+
448
+ # Process the single generated video
449
+ if len(operation.response.generated_videos) > 0:
450
+ video = operation.response.generated_videos[0]
451
+ if video is None or not hasattr(video, 'video'):
452
+ raise ValueError("Video is invalid or missing video data")
453
+ fname = 'text_to_video.mp4'
454
+ print(f"Generated video: {fname}")
455
+ # Download the video and get the raw bytes
456
+ video_data = client.files.download(file=video.video)
457
+ # Ensure video_data is in bytes
458
+ if isinstance(video_data, bytes):
459
+ video_bytes = video_data
460
+ else:
461
+ # If video_data is a file-like object, read the bytes
462
+ video_buffer = BytesIO()
463
+ for chunk in video_data:
464
+ video_buffer.write(chunk)
465
+ video_bytes = video_buffer.getvalue()
466
+ # Encode the video bytes as base64
467
+ video_base64 = base64.b64encode(video_bytes).decode()
468
+ video_generated = True
469
+ # Successfully generated video, return the result
470
  return {
471
  'text': text,
472
  'image_base64': img_str,
473
  'video_base64': video_base64,
474
  'ideas': ideas
475
  }
476
+ else:
477
+ raise ValueError("No video was generated")
478
+ except Exception as e:
479
+ print(f"Error generating video (text-to-video attempt {video_attempt + 1}, total attempt {total_attempts}): {e}")
480
+ if video_attempt == max_video_retries_per_image - 1:
481
+ if total_attempts == max_total_attempts:
482
+ print("Max total attempts reached. Proceeding without video.")
483
+ video_base64 = None
484
+ return {
485
+ 'text': text,
486
+ 'image_base64': img_str,
487
+ 'video_base64': video_base64,
488
+ 'ideas': ideas
489
+ }
490
+ # Both image-to-video and text-to-video failed, break to outer loop to try a new image
491
+ print(f"Text-to-video generation failed after {max_video_retries_per_image} attempts. Selecting a new idea and generating a new image.")
492
+ break
493
+ continue # Retry text-to-video generation with a modified prompt
494
 
495
+ # If video generation is not enabled or image generation failed, return the result
496
+ if img_str is not None:
497
+ return {
498
+ 'text': text,
499
+ 'image_base64': img_str,
500
+ 'video_base64': video_base64,
501
+ 'ideas': ideas
502
+ }
503
+ # If img_str is None, continue to next cycle or fall back if max attempts reached
504
 
505
  # If max total attempts reached without success, use a gray placeholder image
506
  print("Max total attempts reached without successful image generation. Using placeholder.")