product2204's picture
Update app.py
fcff35c verified
raw
history blame
6.85 kB
import re
import requests
from gtts import gTTS
import moviepy.editor as mpe
from moviepy.editor import concatenate_videoclips
import ffmpeg
# API key and basic setup for Pixabay
API_KEY = '43444686-8ab8011dcadf5ec78f23cbff8'
PIXABAY_URL = f"https://pixabay.com/api/?key={API_KEY}"
import pixabay.core
import google.generativeai as genai
def gemini_ai_config():
#@title Configure Gemini API key
#Access your Gemini API key
try:
GOOGLE_API_KEY="AIzaSyD3XZWTlW3S5a2qDoWAFSH3lsOpzVYVpSs"
genai.configure(api_key=GOOGLE_API_KEY)
model = genai.GenerativeModel('gemini-pro')
return model
except Exception as e:
# unknown error
print(f"There was an unknown error. Ensure you have a secret stored in Colab and it's a valid key from https://makersuite.google.com/app/apikey")
raise e
def generate_voice_from_text(text, query,lang='en'):
"""Generates an MP3 file from the given text using gTTS."""
tts = gTTS(text=text, lang=lang)
audio_path = f'temp_{query}_audio.mp3'
tts.save(audio_path)
save_and_return_file(audio_path)
return audio_path
def save_and_return_file(filename):
print("save",filename)
def read_script(content):
"""Reads a script file and returns a list of text and queries."""
'''with open(filename, "r") as file:
content = file.read().strip()
# This pattern assumes there could be multiple lines between ####TEXT: and ####QUERY:'''
pattern = r"###TEXT:\s*(.*?)\s*###QUERY:\s*(.*?)(?=###TEXT:|$)"
segments = re.findall(pattern, content, re.DOTALL)
if not segments:
print("No valid segments found in the script. Please check the script format.")
return segments
def fetch_video_from_pixabay(query, i):
try:
px = pixabay.core(API_KEY)
space = px.queryVideo(query)
print("{} hits".format(len(space)))
filename = f"{query}_{i}.mp4"
space[0].download(filename, "large")
return filename
except Exception as e:
print(f"Error fetching video for query '{query}': {e}")
return None
def process_segment(text, query, index):
video_url = fetch_video_from_pixabay(query, index)
print("index",index,"query",query)
if video_url:
video_clip = mpe.VideoFileClip(video_url)
audio_path = generate_voice_from_text(text, query)
audio_clip = mpe.AudioFileClip(audio_path)
# Trim the video to the desired duration
if video_clip.duration > audio_clip.duration:
video_clip = video_clip.subclip(0, audio_clip.duration)
else:
if video_clip.duration < audio_clip.duration:
loop_count = int( audio_clip.duration// video_clip.duration)
video_clip = mpe.concatenate_videoclips([video_clip] * loop_count)
# Combine the audio and video
final_clip = video_clip.set_audio(audio_clip)
final_clip = video_clip.set_audio(audio_clip)
video_file_path = f"{query}_{index}.mp4" # Removed the redundant assignment here
final_clip.write_videofile(video_file_path, codec="libx264", fps=24)
save_and_return_file(video_file_path)
return video_file_path
else:
print(f"Skipping segment due to no available video for query: {query}")
return None
# Main process
def process_video_paragraph(text):
model=gemini_ai_config()
response = model.generate_content(text)
print(f'**You**: what is add\n\n**Gemini**:\n{response.text}')
video_segments = read_script(response.text)
video_clips=[]
print(f"Number of segments: {len(video_segments)}")
for index, segment in enumerate(video_segments):
text, query = segment[0],segment[1]
print(f"Processing segment {index + 1}/{len(video_segments)} - Text: {text} Query: {query}")
video_clip_path=process_segment(text, query,index)
if video_clip_path:
# Load the video clip and add to the list
video_clip = mpe.VideoFileClip(video_clip_path)
video_clips.append(video_clip)
else:
print("No video segments to concatenate.")
if video_clips:
final_video = concatenate_videoclips(video_clips,method="compose")
final_output_path = "final_concatenated_video.mp4"
final_video.write_videofile(final_output_path, codec="libx264", fps=24)
print(f"Final concatenated video created: {final_output_path}")
save_and_return_file(final_output_path)
return final_output_path
import gradio as gr
text="""
You are attention deficit coach , for a college student, write about best way to productive if you have attention deficit disorder
We will provide you with an idea of the video along with some reference content. Using the idea create a 1-2 min video for it.
Create a text for 1-2 min minute video (around 200-400 words),
video title (make it clickbait super interesting, include numbers into title and maybe open question), video description (optimize for more tags for youtube and google search).
For actual video content I will be using pixelbay content to compose a series of videos
into my video. So for the text you provide you have to provide a search query for every
part so i can search it in pixelbay and pick videos from there.
Make video, engaging, include different stories, history, make it fun at some points.
Make it as interesting as possible.
Avoid any
kind of lists 1), 2) .. in the text part in the video, also avoid everything
which is usually not said by humans in the video including various symbols and etc. use just
words and numbers because the video text will be used for voice over.
Please provide the output to meet the following format:
###TEXT: <text of what you will say in the video, this should complement to the query video which will be shown in the video>
###QUERY: <text of what video i should search on storyblocks to match the text above, the query should be short, 1-2 words max, should be as general as possible but on the given topic>
Always include pair of ###QUERY and ###TEXT for next parts, a video should have a new query around every 10-30 seconds. Initial 1st minute of video should be more
dynamic and contain more queries 10s each.
End video asking to like and subscribe to channel, like and share."""
# Define the Gradio interface
interface = gr.Interface(
fn=process_video_paragraph,
inputs=gr.Textbox(label="Input Paragraph", placeholder=text),
outputs=gr.Video(label="video"),
title="Paragraph to Video Generator",
description="Enter a paragraph of text and receive a filepath to the generated video."
)
# Run the Gradio app
if __name__ == "__main__":
interface.launch(debug=True,share=True)