guda / app.py
sharul62628's picture
Update app.py
e915688 verified
import os
import gradio as gr
import subprocess
import cv2
from PIL import Image
import google.generativeai as genai
import base64
# ========== SETUP ==========
def set_api_key(api_key):
os.environ["GOOGLE_API_KEY"] = api_key
genai.configure(api_key=api_key)
# ========== TEXT TO IMAGE ==========
def text_to_image(api_key, prompt, image_file, resolution):
try:
set_api_key(api_key)
model = genai.GenerativeModel("imagen-3.0")
if image_file:
final_prompt = {"text": prompt, "image": Image.open(image_file)}
else:
final_prompt = prompt
result = model.generate_content(final_prompt)
if not result.candidates:
return None, "❌ Gagal: tiada kandidat dihasilkan"
image_bytes = result.candidates[0].content.parts[0].inline_data.data
fname = "output_img.png"
with open(fname, "wb") as f:
f.write(base64.b64decode(image_bytes))
return fname, "βœ… Gambar berjaya dihasilkan!"
except Exception as e:
return None, f"❌ Error: {str(e)}"
# ========== SHORT VIDEO ==========
def text_to_video(api_key, prompt, image_file, duration, aspect_ratio, resolution):
try:
set_api_key(api_key)
model = genai.GenerativeModel("veo-3")
# aspect ratio & res
if aspect_ratio == "9:16":
res = {"width": 720 if resolution == "720p" else 1080,
"height": 1280 if resolution == "720p" else 1920}
else:
res = {"width": 1280 if resolution == "720p" else 1920,
"height": 720 if resolution == "720p" else 1080}
if image_file:
final_prompt = {"text": prompt, "image": Image.open(image_file)}
else:
final_prompt = prompt
result = model.generate_content({
"text": prompt,
"config": {
"duration_seconds": int(duration),
"fps": 12,
"video": {"width": res["width"], "height": res["height"]}
}
})
if not result.candidates:
return None, "❌ Gagal: tiada kandidat video dihasilkan"
video_bytes = result.candidates[0].content.parts[0].inline_data.data
fname = "output_vid.mp4"
with open(fname, "wb") as f:
f.write(base64.b64decode(video_bytes))
return fname, "βœ… Video berhasil dibuat!"
except Exception as e:
return None, f"❌ Error: {str(e)}"
# ========== LONG VIDEO ==========
def auto_segment_long_video(api_key, prompt, start_img, num_segments, duration_each, aspect_ratio, resolution):
try:
set_api_key(api_key)
model = genai.GenerativeModel("veo-3")
if aspect_ratio == "9:16":
res = {"width": 720 if resolution == "720p" else 1080,
"height": 1280 if resolution == "720p" else 1920}
else:
res = {"width": 1280 if resolution == "720p" else 1920,
"height": 720 if resolution == "720p" else 1080}
words = prompt.split()
chunk_size = max(1, len(words) // num_segments)
seg_prompts = [" ".join(words[i:i+chunk_size]) for i in range(0, len(words), chunk_size)][:num_segments]
carry_image = Image.open(start_img) if start_img else None
segment_files = []
for idx, text in enumerate(seg_prompts):
if carry_image:
final_prompt = {"text": text, "image": carry_image}
else:
final_prompt = text
result = model.generate_content({
"text": text,
"config": {
"duration_seconds": int(duration_each),
"fps": 12,
"video": {"width": res["width"], "height": res["height"]}
}
})
if not result.candidates:
return None, f"❌ Gagal buat segmen {idx}"
video_bytes = result.candidates[0].content.parts[0].inline_data.data
fname = f"seg_{idx}.mp4"
with open(fname, "wb") as f:
f.write(base64.b64decode(video_bytes))
segment_files.append(fname)
cap = cv2.VideoCapture(fname)
cap.set(cv2.CAP_PROP_POS_FRAMES, cap.get(cv2.CAP_PROP_FRAME_COUNT) - 1)
ret, frame = cap.read()
cap.release()
if ret:
framefile = f"carry_{idx}.jpg"
cv2.imwrite(framefile, frame)
carry_image = Image.open(framefile)
# gabung semua segmen
list_file = "segments.txt"
with open(list_file, "w") as f:
for seg in segment_files:
f.write(f"file '{seg}'\n")
final_out = "final_long.mp4"
subprocess.run(
["ffmpeg", "-y", "-f", "concat", "-safe", "0", "-i", list_file, "-c", "copy", final_out],
check=True
)
return final_out, "βœ… Video panjang berhasil dibuat!"
except Exception as e:
return None, f"❌ Error: {str(e)}"
# ========== UI ==========
with gr.Blocks(css="""
body {background: linear-gradient(160deg,#0f0c29,#302b63,#24243e);}
.gradio-container {color:white;}
h1,h2,h3,h4,label {color:white !important;}
button {background: linear-gradient(90deg,#6a11cb,#2575fc) !important; color:white !important;}
""") as demo:
gr.HTML("<h1 style='text-align:center'>πŸŽ₯ Penjana Video VEO</h1>")
api_key = gr.Textbox(label="πŸ”‘ Masukkan Kunci API Gemini anda", type="password")
with gr.Tabs():
with gr.Tab("🎬 Video Pendek"):
prompt_vid = gr.Textbox(label="Prompt", placeholder="Tulis ide video...", lines=4)
vid_file = gr.File(label="Imej Rujukan (Opsional)", file_types=[".jpg",".png"], type="filepath")
duration = gr.Slider(3, 8, value=5, label="Tempoh (detik)")
aspect_ratio = gr.Dropdown(choices=["16:9", "9:16"], value="16:9", label="Nisbah Aspek")
resolution = gr.Dropdown(choices=["720p","1080p"], value="720p", label="Resolusi")
btn_vid = gr.Button("Hasilkan Video Pendek")
out_vid = gr.Video()
msg_vid = gr.Label()
btn_vid.click(fn=text_to_video,
inputs=[api_key, prompt_vid, vid_file, duration, aspect_ratio, resolution],
outputs=[out_vid, msg_vid])
with gr.Tab("🎞️ Video Panjang"):
full_prompt = gr.Textbox(label="Prompt Narasi Panjang", placeholder="Tulis cerita panjang...", lines=6)
start_img = gr.File(label="Imej Awal (Opsional)", file_types=[".jpg",".png"], type="filepath")
num_segments = gr.Slider(1, 10, value=3, step=1, label="Jumlah Segmen")
dur_each = gr.Slider(3, 8, value=5, step=1, label="Durasi/Segmen (detik)")
aspect_ratio_long = gr.Dropdown(choices=["16:9", "9:16"], value="16:9", label="Nisbah Aspek")
resolution_long = gr.Dropdown(choices=["720p","1080p"], value="720p", label="Resolusi")
btn_long = gr.Button("Hasilkan Video Panjang")
out_long = gr.Video()
msg_long = gr.Label()
btn_long.click(fn=auto_segment_long_video,
inputs=[api_key, full_prompt, start_img, num_segments, dur_each,
aspect_ratio_long, resolution_long],
outputs=[out_long, msg_long])
with gr.Tab("πŸ–ΌοΈ Imej"):
prompt_img = gr.Textbox(label="Prompt", placeholder="Tulis ide gambar...", lines=4)
img_file = gr.File(label="Imej Rujukan (Opsional)", file_types=[".jpg",".png"], type="filepath")
resolution_img = gr.Dropdown(choices=["720p","1080p"], value="720p", label="Resolusi (dummy)")
btn_img = gr.Button("Hasilkan Imej")
out_img = gr.Image()
msg_img = gr.Label()
btn_img.click(fn=text_to_image,
inputs=[api_key, prompt_img, img_file, resolution_img],
outputs=[out_img, msg_img])
if __name__ == "__main__":
demo.launch()