Spaces:
Sleeping
Sleeping
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) | |