Spaces:
Sleeping
Sleeping
File size: 9,642 Bytes
292ead2 ec95cd7 292ead2 ec95cd7 292ead2 e149ed2 292ead2 e149ed2 292ead2 571198c 292ead2 e149ed2 292ead2 571198c 292ead2 571198c 292ead2 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 |
import os
import logging
import streamlit as st
from functools import lru_cache
from audio_gen import audio_generation
from caption_gen import caption_generation
from image_gen import image_generation_change_background
from video_gen import video_generation
from prompt_generator import generate_segments_payload, VeoInputs
from dotenv import load_dotenv
load_dotenv()
# --- Logger ---
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s | %(levelname)s | %(name)s | %(message)s",
)
logger = logging.getLogger("video_generator_tools")
st.set_page_config(page_title="Video Generator Tools", layout="wide")
def main_app():
st.title("Video Generator Tools")
tabs = st.tabs([
"JSON Prompt Generator",
"Audio Generator",
"Image Generation",
"Generate Caption",
])
# JSON Prompt Generator
with tabs[0]:
st.subheader("JSON Prompt Generator")
with st.form("json_prompt_form", clear_on_submit=False):
script = st.text_area("Script", height=200, placeholder="Paste the full script...")
style = st.text_input("Style", value="clean, lifestyle UGC")
json_format = st.selectbox("jsonFormat", ["standard", "compact", "verbose"], index=0)
continuation = st.toggle("continuationMode", value=True)
voice_type = st.text_input("voiceType", value="")
energy_level = st.text_input("energyLevel", value="")
setting_mode = st.text_input("settingMode", ["single"])
camera_style = st.text_input("cameraStyle", value="handheld steadicam")
energy_arc = st.text_input("energyArc", value="")
narrative_style = st.text_input("narrativeStyle", value="direct address")
accent_region = st.text_input("accentRegion", value="")
image_upload = st.file_uploader("First frame image (optional)", type=["png", "jpg", "jpeg", "webp"])
submitted = st.form_submit_button("Generate Segments Payload")
if submitted:
try:
image_bytes = image_upload.read() if image_upload else None
logger.info("JSON Prompt: script_len=%d style='%s' jsonFormat='%s' img=%s",
len(script or ""), style, json_format, bool(image_bytes))
inputs = VeoInputs(
script=script or "",
style=style or "",
jsonFormat=json_format,
continuationMode=continuation,
voiceType=voice_type or None,
energyLevel=energy_level or None,
settingMode=setting_mode,
cameraStyle=camera_style or None,
energyArc=energy_arc or None,
narrativeStyle=narrative_style or None,
accentRegion=accent_region or None,
)
with st.spinner("Generating segments payload..."):
payload = generate_segments_payload(inputs, image_path=image_bytes, model="gpt-4o")
st.success("Segments payload generated")
st.json(payload)
st.toast("Segments JSON ready", icon="✅")
except Exception as e:
logger.exception("JSON Prompt Generator failed")
st.error(f"Error: {e}")
# Audio Generator
with tabs[1]:
st.subheader("Audio Generator")
with st.form("audio_generation_form", clear_on_submit=False):
scripts = st.text_area("Scripts", height=180, placeholder="Enter narration text…")
voice_id = st.selectbox("Voice ID", ["Wise_Woman", "Friendly_Person", "Inspirational_girl", "Deep_Voice_Man", "Calm_Woman", "Casual_Guy", "Lively_Girl", "Patient_Man", "Young_Knight", "Determined_Man", "Lovely_Girl", "Decent_Boy", "Imposing_Manner", "Elegant_Man", "Abbess", "Sweet_Girl_2", "Exuberant_Girl"], index=0)
speed = st.slider("Speed", min_value=0.5, max_value=2.0, value=1.0, step=0.1)
volume = st.slider("Volume", min_value=1.0, max_value=5.0, value=1.0, step=0.5)
pitch = st.slider("Pitch (semitones)", min_value=-12, max_value=12, value=0, step=1)
emotion = st.selectbox("Emotion", ["neutral", "confident", "warm", "excited", "serious"], index=0)
make_audio = st.form_submit_button("Generate Audio")
if make_audio:
if not scripts.strip():
st.error("Please enter scripts text.")
else:
try:
logger.info("Audio Gen: voice_id=%s speed=%.2f volume=%.2f pitch=%d emotion=%s text_len=%d",
voice_id, speed, volume, pitch, emotion, len(scripts or ""))
with st.spinner("Generating audio..."):
url = audio_generation(scripts, voice_id, speed, volume, pitch, emotion)
if url:
st.success("Audio generated")
st.audio(url)
st.write(url)
st.toast("Audio ready", icon="🔊")
else:
st.error("No audio URL returned.")
logger.warning("Audio Gen: empty URL")
except Exception as e:
logger.exception("Audio Generation failed")
st.error(f"Error: {e}")
# Image Generation (BG Change)
with tabs[2]:
st.subheader("Image Generation (for changing character's background)")
with st.form("image_generation_form", clear_on_submit=False):
img = st.file_uploader("Input image", type=["png", "jpg", "jpeg", "webp"])
img_prompt = st.text_input("Prompt", placeholder="New background description, style cues, lighting…")
ar = st.selectbox("Aspect ratio", ["9:16", "16:9"], index=0)
gen_img = st.form_submit_button("Generate Image")
if gen_img:
if not img:
st.error("Please upload an image.")
else:
try:
raw = img.read()
logger.info("Image Gen: bytes=%d ar=%s prompt_len=%d", len(raw or b""), ar, len(img_prompt or ""))
with st.spinner("Generating image..."):
url = image_generation_change_background(raw, img_prompt, ar)
if url:
st.success("Image processed")
cols = st.columns(2)
with cols[0]:
st.caption("Input")
st.image(img, use_container_width=True)
with cols[1]:
st.caption("Output")
st.image(url, use_container_width=True)
st.write(url)
st.toast("Image ready", icon="🖼️")
else:
st.error("No image URL returned.")
logger.warning("Image Gen: empty URL")
except Exception as e:
logger.exception("Image Generation failed")
st.error(f"Error: {e}")
# Generate Caption
with tabs[3]:
st.subheader("Generate Caption")
with st.form("caption_form", clear_on_submit=False):
cap_video = st.file_uploader("Input video", type=["mp4", "mov", "mkv"])
cap_size = st.slider("Caption size (characters)", min_value=10, max_value=100, value=30, step=5)
color = st.text_input("Highlight color (hex)", value="#FFD400")
make_caps = st.form_submit_button("Generate Captions")
if make_caps:
if not cap_video:
st.error("Please upload a video.")
else:
try:
vbytes = cap_video.read()
logger.info("Caption Gen: video_bytes=%d cap_size=%d color=%s",
len(vbytes or b""), int(cap_size), color)
with st.spinner("Generating captions..."):
url = caption_generation(vbytes, cap_size, color)
if url:
st.success("Captions generated")
st.video(url)
st.write(url)
st.toast("Captioned video ready", icon="🎞️")
else:
st.error("No captioned video URL returned.")
logger.warning("Caption Gen: empty URL")
except Exception as e:
logger.exception("Caption Generation failed")
st.error(f"Error: {e}")
@lru_cache(maxsize=1)
def check_token_cached(user_token: str):
ACCESS_TOKEN = os.getenv("ACCESS_TOKEN")
if not ACCESS_TOKEN:
return False, "Server error: Access token not configured."
if user_token == ACCESS_TOKEN:
return True, ""
return False, "Invalid token."
def main():
if "authenticated" not in st.session_state:
st.session_state["authenticated"] = False
if not st.session_state["authenticated"]:
st.markdown("## Access Required")
token_input = st.text_input("Enter Access Token", type="password")
if st.button("Unlock App"):
ok, error_msg = check_token_cached(token_input)
if ok:
st.session_state["authenticated"] = True
st.rerun()
else:
st.error(error_msg)
else:
main_app()
if __name__ == "__main__":
main() |