|
|
import streamlit as st |
|
|
from openai import OpenAI |
|
|
from tenacity import retry, stop_after_attempt, wait_fixed |
|
|
import os |
|
|
|
|
|
|
|
|
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY")) |
|
|
|
|
|
@retry(stop=stop_after_attempt(3), wait=wait_fixed(1)) |
|
|
def call_openai_api(messages): |
|
|
""" |
|
|
Make API call to OpenAI with retry logic for reliability. |
|
|
""" |
|
|
return client.chat.completions.create( |
|
|
model="gpt-4", |
|
|
messages=messages, |
|
|
max_tokens=400, |
|
|
temperature=0.9 |
|
|
) |
|
|
|
|
|
def generate_video_hooks(script): |
|
|
""" |
|
|
Generate compelling video hooks based on the provided script. |
|
|
""" |
|
|
messages = [{ |
|
|
"role": "system", |
|
|
"content": """You are an expert at creating viral video hooks for real estate content. |
|
|
Your specialty is writing opening lines that stop scrollers and make viewers watch the entire video. |
|
|
|
|
|
CRITICAL: Every hook you write MUST directly relate to the specific topic, facts, and content of the script provided. Do not write generic hooks - each hook should only make sense for THIS particular video. |
|
|
|
|
|
Your hooks should: |
|
|
- Be 15 words or less (can be 2 short sentences if needed) |
|
|
- Reference specific details, statistics, locations, or insights from the script |
|
|
- Create immediate curiosity or urgency about the script's actual topic |
|
|
- Use power words that grab attention |
|
|
- Avoid generic openings like "Hey guys" or "In today's video" |
|
|
- Make viewers think "I need to know this" |
|
|
|
|
|
Generate exactly 10 different hook options using these styles: |
|
|
1. Question hook (about the script's specific topic) |
|
|
2. Shocking statement (using a fact from the script) |
|
|
3. "What if" scenario (related to the script's subject) |
|
|
4. Contrarian/surprising angle (on the script's theme) |
|
|
5. Fear-based urgency (tied to the script's content) |
|
|
6. Benefit-focused (highlighting what the script teaches) |
|
|
7. Story teaser (hinting at something specific in the script) |
|
|
8. Number/list hook (using data from the script if available) |
|
|
9. Problem-focused (addressing the problem the script solves) |
|
|
10. Secret/insider knowledge (from the script's insights) |
|
|
|
|
|
Format as a numbered list with each hook on its own line.""" |
|
|
}, { |
|
|
"role": "user", |
|
|
"content": f"""Analyze this script carefully and create 10 hooks that are specifically about its content. Each hook must only work for THIS video, not be a generic hook that could apply to any video. |
|
|
|
|
|
SCRIPT TO ANALYZE: |
|
|
{script} |
|
|
|
|
|
Generate 10 content-specific hooks:""" |
|
|
}] |
|
|
|
|
|
response = call_openai_api(messages) |
|
|
return response.choices[0].message.content |
|
|
|
|
|
|
|
|
st.set_page_config(layout="wide", page_title="Video Hook Generator") |
|
|
|
|
|
|
|
|
if "generated_hooks" not in st.session_state: |
|
|
st.session_state["generated_hooks"] = None |
|
|
if "show_notice" not in st.session_state: |
|
|
st.session_state["show_notice"] = False |
|
|
|
|
|
|
|
|
st.markdown("<h1 style='text-align: center; color: black;'>π£ Video Hook Generator</h1>", unsafe_allow_html=True) |
|
|
st.markdown("<p style='text-align: center; color: gray; font-size: 18px;'>Turn any script into scroll-stopping content</p>", unsafe_allow_html=True) |
|
|
|
|
|
|
|
|
st.markdown("<h2 style='text-align: center; color: black;'>Paste Your Script</h2>", unsafe_allow_html=True) |
|
|
|
|
|
|
|
|
col1, col2, col3 = st.columns([1, 3, 1]) |
|
|
|
|
|
with col2: |
|
|
user_script = st.text_area( |
|
|
"", |
|
|
placeholder="Paste your complete video script here...\n\nThe more detailed your script, the better hooks I can create for you.", |
|
|
height=200 |
|
|
) |
|
|
|
|
|
generate_button = st.button('π― Generate 10 Hooks', use_container_width=True) |
|
|
|
|
|
|
|
|
if generate_button and user_script.strip(): |
|
|
st.session_state["show_notice"] = True |
|
|
|
|
|
with st.spinner("π£ Creating irresistible hooks..."): |
|
|
st.session_state["generated_hooks"] = generate_video_hooks(user_script) |
|
|
st.session_state["show_notice"] = False |
|
|
|
|
|
elif generate_button and not user_script.strip(): |
|
|
st.error("Please paste your script first!") |
|
|
|
|
|
|
|
|
if st.session_state["show_notice"]: |
|
|
st.info("π¬ Analyzing your script and generating hooks... This will just take a moment!") |
|
|
|
|
|
|
|
|
if st.session_state["generated_hooks"]: |
|
|
st.markdown("---") |
|
|
st.markdown("<h2 style='text-align: center; color: black;'>π₯ Your Hook Options</h2>", unsafe_allow_html=True) |
|
|
|
|
|
|
|
|
st.markdown(""" |
|
|
<div style='background-color: #f8f9fa; padding: 25px; border-radius: 10px; border-left: 4px solid #FF6B35; margin: 20px 0;'> |
|
|
""", unsafe_allow_html=True) |
|
|
|
|
|
st.markdown(st.session_state["generated_hooks"]) |
|
|
|
|
|
st.markdown("</div>", unsafe_allow_html=True) |