ogeti siva satyanarayana commited on
Commit
fe21d8b
Β·
1 Parent(s): 1ac057d

Update video_enhancer.py

Browse files
Files changed (1) hide show
  1. video_enhancer.py +63 -86
video_enhancer.py CHANGED
@@ -1,100 +1,77 @@
1
- # streamlit_ui.py
2
- import streamlit as st
3
- import requests
4
- import base64
5
- import tempfile
6
- from backend.subtitle_utils import generate_srt_from_text, enhance_video_with_subtitles_and_bgm
7
 
8
- st.set_page_config(
9
- page_title="Prompta - Text to Media Generator",
10
- page_icon="πŸŽ™οΈ",
11
- layout="wide",
12
- initial_sidebar_state="expanded"
13
- )
14
- st.title("πŸŽ™οΈπŸ–ΌοΈπŸŽžοΈ Prompta - Text to Media Generator")
15
 
16
- API_BASE = "http://localhost:8000"
 
 
 
 
 
 
 
 
 
17
 
18
- def render_media(file_bytes, media_type, label):
19
- b64 = base64.b64encode(file_bytes).decode()
20
- if media_type == "audio":
21
- st.audio(f"data:audio/wav;base64,{b64}", format="audio/wav")
22
- elif media_type == "video":
23
- st.video(f"data:video/mp4;base64,{b64}")
24
- elif media_type == "image":
25
- st.image(file_bytes, caption=label, use_column_width=True)
26
 
27
- st.sidebar.header("πŸ› οΈ Settings")
28
- TOKEN = st.sidebar.text_input("πŸ”‘ API Token", type="password")
29
- HEADERS = {"Authorization": f"Bearer {TOKEN}"} if TOKEN else {}
 
30
 
31
- tab = st.sidebar.radio("Select Task", ["Text to Audio", "Text to Image", "Text to Video"])
 
32
 
33
- if tab == "Text to Audio":
34
- st.subheader("🎀 Text to Audio")
35
- text = st.text_area("Enter text")
36
- voice = st.selectbox("Choose voice/language", ["en-US", "hi-IN", "te-IN", "ta-IN"])
37
 
38
- if st.button("πŸ”Š Generate Audio"):
39
- with st.spinner("Generating audio..."):
40
- r = requests.post(f"{API_BASE}/audio/generate", json={"text": text, "voice": voice}, headers=HEADERS)
41
- if r.status_code == 200:
42
- render_media(r.content, "audio", "Generated Audio")
43
- else:
44
- st.error(f"❌ Failed: {r.json().get('detail')}")
 
 
 
 
 
 
45
 
46
- elif tab == "Text to Image":
47
- st.subheader("πŸ–ΌοΈ Text to Image")
48
- prompt = st.text_area("Enter image prompt")
49
- model = st.selectbox("Choose model", ["sdxl", "deepfloyd", "kandinsky"])
50
 
51
- if st.button("🧠 Generate Image"):
52
- with st.spinner("Generating image..."):
53
- r = requests.post(f"{API_BASE}/image/generate", json={"prompt": prompt, "model": model}, headers=HEADERS)
54
- if r.status_code == 200:
55
- render_media(r.content, "image", "Generated Image")
56
- else:
57
- st.error(f"❌ Failed: {r.json().get('detail')}")
 
 
58
 
59
- elif tab == "Text to Video":
60
- st.subheader("🎞️ Text to Video")
61
- prompt = st.text_area("Enter video prompt")
62
- tone = st.selectbox("Tone", ["formal", "casual", "emotional", "documentary"])
63
- domain = st.selectbox("Domain", ["health", "education", "governance", "entertainment"])
64
- environment = st.selectbox("Environment", ["urban", "rural", "nature", "futuristic"])
65
 
66
- transcript = st.text_area("Transcript (optional - for subtitles)", height=100)
67
- enhance = st.checkbox("✨ Add Subtitles and Background Music")
68
 
69
- if st.button("🎬 Generate Video"):
70
- with st.spinner("Generating video..."):
71
- r = requests.post(
72
- f"{API_BASE}/video/generate",
73
- json={"prompt": prompt, "tone": tone, "domain": domain, "environment": environment},
74
- headers=HEADERS
75
- )
76
- if r.status_code == 200:
77
- video_bytes = r.content
78
- if enhance and transcript:
79
- with tempfile.NamedTemporaryFile(delete=False, suffix=".mp4") as tmp_vid:
80
- tmp_vid.write(video_bytes)
81
- tmp_vid_path = tmp_vid.name
82
 
83
- srt_path = generate_srt_from_text(transcript, output_path="streamlit_subs.srt")
84
- enhanced_path = "streamlit_final_video.mp4"
85
- enhance_video_with_subtitles_and_bgm(
86
- video_path=tmp_vid_path,
87
- srt_path=srt_path,
88
- bgm_path="default_bgm.mp3",
89
- output_path=enhanced_path
90
- )
91
 
92
- with open(enhanced_path, "rb") as f:
93
- render_media(f.read(), "video", "Enhanced Video")
94
- else:
95
- render_media(video_bytes, "video", "Generated Video")
96
- else:
97
- st.error(f"❌ Failed: {r.json().get('detail')}")
98
-
99
- st.sidebar.markdown("---")
100
- st.sidebar.info("Built with ❀️ for AI GovTech Challenge 2025")
 
1
+ from moviepy.editor import VideoFileClip, TextClip, CompositeVideoClip, AudioFileClip, concatenate_audioclips
2
+ import os
3
+ from typing import List, Tuple
 
 
 
4
 
 
 
 
 
 
 
 
5
 
6
+ def export_srt(transcript: List[str], duration: float, output_path: str):
7
+ """
8
+ Exports transcript as a .srt subtitle file assuming equal spacing.
9
+ """
10
+ lines = []
11
+ segment_duration = duration / len(transcript)
12
+
13
+ for idx, line in enumerate(transcript):
14
+ start_time = segment_duration * idx
15
+ end_time = segment_duration * (idx + 1)
16
 
17
+ def format_time(t):
18
+ h = int(t // 3600)
19
+ m = int((t % 3600) // 60)
20
+ s = int(t % 60)
21
+ ms = int((t % 1) * 1000)
22
+ return f"{h:02}:{m:02}:{s:02},{ms:03}"
 
 
23
 
24
+ lines.append(f"{idx+1}")
25
+ lines.append(f"{format_time(start_time)} --> {format_time(end_time)}")
26
+ lines.append(line.strip())
27
+ lines.append("") # Empty line for spacing
28
 
29
+ with open(output_path, "w", encoding="utf-8") as f:
30
+ f.write("\n".join(lines))
31
 
 
 
 
 
32
 
33
+ def add_subtitles_and_bgm(
34
+ video_path: str,
35
+ transcript: List[str],
36
+ output_path: str = "final_output.mp4",
37
+ bgm_path: str = None,
38
+ subtitle_font: str = "Arial",
39
+ subtitle_size: int = 24,
40
+ subtitle_color: str = "white",
41
+ subtitle_position: Tuple[int, int] = ("center", "bottom")
42
+ ):
43
+ """
44
+ Adds subtitles and optional background music to a video.
45
+ """
46
 
47
+ clip = VideoFileClip(video_path)
48
+ duration = clip.duration
49
+ segment_duration = duration / len(transcript)
50
+ subtitle_clips = []
51
 
52
+ for i, line in enumerate(transcript):
53
+ txt = TextClip(
54
+ line,
55
+ fontsize=subtitle_size,
56
+ font=subtitle_font,
57
+ color=subtitle_color,
58
+ method='caption',
59
+ size=(clip.w * 0.8, None) # 80% width
60
+ ).set_position(subtitle_position).set_duration(segment_duration).set_start(i * segment_duration)
61
 
62
+ subtitle_clips.append(txt)
 
 
 
 
 
63
 
64
+ final_video = CompositeVideoClip([clip, *subtitle_clips])
 
65
 
66
+ if bgm_path and os.path.exists(bgm_path):
67
+ bgm = AudioFileClip(bgm_path).volumex(0.2).set_duration(duration)
68
+ original_audio = clip.audio
69
+ if original_audio:
70
+ mixed_audio = original_audio.volumex(1.0).audio_fadein(0.5).audio_fadeout(0.5)
71
+ final_audio = CompositeVideoClip([mixed_audio.set_start(0), bgm.set_start(0)]).audio
72
+ else:
73
+ final_audio = bgm
74
+ final_video = final_video.set_audio(final_audio)
 
 
 
 
75
 
76
+ final_video.write_videofile(output_path, codec="libx264", audio_codec="aac")
 
 
 
 
 
 
 
77