Story-Come / app.py
ageraustine's picture
Update app.py
0d700cd verified
raw
history blame
4.53 kB
import gradio as gr
from langchain.llms import OpenAI as LangChainOpenAI
from langchain.prompts import PromptTemplate
from langchain.chains import LLMChain
from openai import OpenAI
import os
import re
from pathlib import Path
from moviepy.editor import *
import requests
import tempfile
# Initialize OpenAI client
client = OpenAI()
# Create a prompt template
template = """
You are a creative teacher exclusively for kids. Given a topic, write a tutorial-based story of about 150 words teaching the child about the topic.
Divide the tutorial into 3 paragraphs. Each paragraph should be a distinct part of the tutorial.
Topic: {topic}
Story:
"""
prompt = PromptTemplate(template=template, input_variables=["topic"])
# Create an LLMChain
llm = LangChainOpenAI(temperature=0.7)
story_chain = LLMChain(llm=llm, prompt=prompt)
def generate_image(prompt):
try:
response = client.images.generate(
model="dall-e-3",
prompt=prompt,
size="256x256",
quality="standard",
n=1,
)
return response.data[0].url
except Exception as e:
print(f"Error generating image: {e}")
return None
def generate_speech(text, filename):
try:
response = client.audio.speech.create(
model="tts-1",
voice="alloy",
input=text
)
response.stream_to_file(filename)
return filename
except Exception as e:
print(f"Error generating speech: {e}")
return None
def download_image(url, filename):
response = requests.get(url)
with open(filename, 'wb') as f:
f.write(response.content)
def create_video(paragraphs, image_files, audio_files, output_file):
clips = []
for paragraph, image_file, audio_file in zip(paragraphs, image_files, audio_files):
audio_clip = AudioFileClip(audio_file)
duration = audio_clip.duration
image_clip = ImageClip(image_file).set_duration(duration)
text_clip = TextClip(paragraph, fontsize=30, color='white', bg_color='black',
size=(1024, 200), method='caption').set_position(('center', 'bottom')).set_duration(duration)
composite_clip = CompositeVideoClip([image_clip, text_clip])
composite_clip = composite_clip.set_audio(audio_clip)
clips.append(composite_clip)
final_clip = concatenate_videoclips(clips)
final_clip.write_videofile(output_file, fps=24)
def generate_story_with_video(topic):
# Generate the story
story = story_chain.run(topic)
# Split the story into paragraphs
paragraphs = re.split(r'\n\n', story.strip())
# Ensure we have exactly 3 paragraphs
paragraphs = paragraphs[:3]
while len(paragraphs) < 3:
paragraphs.append("...")
with tempfile.TemporaryDirectory() as temp_dir:
image_files = []
audio_files = []
for i, paragraph in enumerate(paragraphs):
# Generate and download image
image_url = generate_image(paragraph)
image_file = os.path.join(temp_dir, f"image_{i}.png")
download_image(image_url, image_file)
image_files.append(image_file)
# Generate audio
audio_file = os.path.join(temp_dir, f"audio_{i}.mp3")
generate_speech(paragraph, audio_file)
audio_files.append(audio_file)
# Create video
output_file = os.path.join(temp_dir, "story_video.mp4")
create_video(paragraphs, image_files, audio_files, output_file)
# Read the video file
with open(output_file, "rb") as f:
video_data = f.read()
return story, video_data
# Create the Gradio interface
def gradio_interface(topic):
try:
story, video_data = generate_story_with_video(topic)
return story, video_data
except Exception as e:
print(f"Error in gradio_interface: {e}")
return "An error occurred while generating the story and video.", None
iface = gr.Interface(
fn=gradio_interface,
inputs=gr.Textbox(lines=2, placeholder="Enter a topic for the story..."),
outputs=[
gr.Textbox(label="Generated Story"),
gr.Video(label="Story Video")
],
title="Story Generator with Video",
description="Enter a topic, and the AI will generate a short story with a video combining images, captions, and narration."
)
# Launch the Gradio app
iface.launch()