Spaces:
Runtime error
Runtime error
File size: 9,072 Bytes
41c2ec8 d6725a0 41c2ec8 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 |
import os
import tempfile
import shutil
import gradio as gr
import requests
import subprocess
import json
import yt_dlp
from PIL import Image
from io import BytesIO
from dotenv import load_dotenv
# Load environment variables
load_dotenv()
# Get API key and base URL from environment variables
API_KEY = os.getenv('Key')
BASE_URL = os.getenv('Base')
def get_movie_or_tv_details(title):
search_url = f'{BASE_URL}/search/multi'
params = {
'api_key': API_KEY,
'query': title
}
response = requests.get(search_url, params=params)
response.raise_for_status()
results = response.json().get('results')
if not results:
raise ValueError(f"No results found for title: {title}")
details = results[0]
if details['media_type'] == 'movie':
release_date = details.get('release_date', '')
elif details['media_type'] == 'tv':
release_date = details.get('first_air_date', '')
else:
raise ValueError("Unsupported media type")
release_year = release_date.split('-')[0] if release_date else 'Unknown'
return details, release_year
def get_images_url(media_type, media_id):
if media_type == 'movie':
images_url = f'{BASE_URL}/movie/{media_id}/images'
elif media_type == 'tv':
images_url = f'{BASE_URL}/tv/{media_id}/images'
else:
raise ValueError("Unsupported media type")
params = {'api_key': API_KEY}
response = requests.get(images_url, params=params)
response.raise_for_status()
return response.json()
def save_summary_and_images(title, summary, images, media_type, year):
prefix = 'Movie' if media_type == 'movie' else 'TV Show'
if not os.path.exists('images'):
os.makedirs('images')
with open(f"{prefix} {title} {year}.txt", 'w', encoding='utf-8') as file:
file.write(summary)
for idx, image in enumerate(images[:12]):
image_url = f"https://image.tmdb.org/t/p/original{image['file_path']}"
response = requests.get(image_url)
response.raise_for_status()
img = Image.open(BytesIO(response.content))
img = img.resize((1080, 1920), Image.LANCZOS)
img.save(f"images/{prefix} {title} {idx + 1} ({year}).jpg")
def generate_voiceover(text, output_file):
edge_tts_command = [
"edge-tts",
"--text", text,
"--write-media", output_file
]
try:
subprocess.run(edge_tts_command, check=True)
print(f"Generated voiceover: {output_file}")
except subprocess.CalledProcessError as e:
print(f"Failed to generate voiceover: {e}")
def process_text_files(prefix, suffix):
current_dir = os.getcwd()
txt_files = [file for file in os.listdir(current_dir) if file.endswith('.txt')]
for txt_file in txt_files:
file_path = os.path.join(current_dir, txt_file)
file_name = os.path.splitext(txt_file)[0]
with open(file_path, 'r', encoding='utf-8') as file:
text = file.read().strip()
processed_text = f"{prefix} {file_name}: {text} {suffix}"
audio_file_path = f"{file_name}.mp3"
generate_voiceover(processed_text, audio_file_path)
print(f"Processed File: {txt_file}")
print("Exported Audio:", audio_file_path)
print()
def make_slideshow(images_folder, audio_file):
image_files = sorted([img for img in os.listdir(images_folder) if img.endswith((".jpg", ".png"))])
images = [os.path.join(images_folder, img) for img in image_files]
audio_duration = float(subprocess.run(['ffprobe', '-v', 'error', '-show_entries', 'format=duration', '-of', 'default=noprint_wrappers=1:nokey=1', audio_file], stdout=subprocess.PIPE, stderr=subprocess.STDOUT).stdout)
commands = []
for image in images:
commands.append(f"file '{image}'")
commands.append(f"duration {audio_duration / len(images)}")
with open('filelist.txt', 'w') as filelist:
filelist.write("\n".join(commands))
base_name = os.path.splitext(os.path.basename(audio_file))[0]
output_file = f'{base_name}.mp4'
subprocess.run(['ffmpeg', '-y', '-f', 'concat', '-safe', '0', '-i', 'filelist.txt', '-i', audio_file, '-c:v', 'libx264', '-pix_fmt', 'yuv420p', output_file])
os.remove('filelist.txt')
def download_music(search_query):
ydl_opts = {
'format': 'bestaudio/best',
'postprocessors': [{
'key': 'FFmpegExtractAudio',
'preferredcodec': 'mp3',
'preferredquality': '192',
}],
'outtmpl': 'background_music.%(ext)s'
}
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
try:
ydl.download([f"ytsearch1:{search_query}"])
return "background_music.mp3"
except:
print("Error downloading music. Please check your internet connection or try a different search query.")
return None
def trim_audio(audio_path, target_duration):
output_path = "trimmed_background_music.mp3"
cmd = ['ffprobe', '-v', 'quiet', '-print_format', 'json', '-show_format', '-show_streams', audio_path]
result = subprocess.run(cmd, capture_output=True, text=True)
data = json.loads(result.stdout)
audio_duration = float(data['format']['duration'])
if audio_duration > target_duration:
start_time = (audio_duration - target_duration) / 2
cmd = ['ffmpeg', '-i', audio_path, '-ss', str(start_time), '-t', str(target_duration), '-c', 'copy', output_path]
subprocess.run(cmd)
return output_path
else:
return audio_path
def combine_audio_with_video(video_path, bg_music_path, bg_music_volume=0.3):
temp_output = "temp_output.mp4"
cmd = [
'ffmpeg',
'-i', video_path,
'-i', bg_music_path,
'-filter_complex',
f'[1:a]volume={bg_music_volume}[bg];[0:a][bg]amix=inputs=2:duration=longest',
'-c:v', 'copy',
'-c:a', 'aac',
'-b:a', '192k',
temp_output
]
subprocess.run(cmd)
os.remove(video_path)
os.rename(temp_output, video_path)
def main(title):
# Create sessions directory if it doesn't exist
sessions_dir = "sessions"
os.makedirs(sessions_dir, exist_ok=True)
# Create session directory
session_dir = os.path.join(sessions_dir, next(tempfile._get_candidate_names()))
os.makedirs(session_dir, exist_ok=True)
os.chdir(session_dir)
try:
details, release_year = get_movie_or_tv_details(title)
media_type = details['media_type']
media_id = details['id']
summary = details.get('overview', 'No summary available.')
images_data = get_images_url(media_type, media_id)
images = images_data.get('backdrops', [])
save_summary_and_images(title, summary, images, media_type, release_year)
prefix_text = "Here is the summary of the"
suffix_text = "Have you watched it? Do tell us in the comments section."
process_text_files(prefix_text, suffix_text)
audio_file = next((f for f in os.listdir('.') if f.lower().endswith('.mp3')), None)
if audio_file:
make_slideshow('images', audio_file)
output_video_file = None
mp4_files = [f for f in os.listdir() if f.endswith('.mp4')]
for video_file in mp4_files:
video_duration = float(subprocess.run(['ffprobe', '-v', 'error', '-show_entries', 'format=duration', '-of', 'default=noprint_wrappers=1:nokey=1', video_file], stdout=subprocess.PIPE, stderr=subprocess.STDOUT).stdout)
search_query = f"{os.path.splitext(video_file)[0]} background music"
music_file = download_music(search_query)
if music_file:
trimmed_music = trim_audio(music_file, video_duration)
combine_audio_with_video(video_file, trimmed_music)
if os.path.exists(music_file):
os.remove(music_file)
if os.path.exists(trimmed_music) and trimmed_music != music_file:
os.remove(trimmed_music)
output_video_file = video_file
# Move the final video to the main directory
if output_video_file:
final_video_path = os.path.join("..", output_video_file)
shutil.move(output_video_file, final_video_path)
return gr.File(final_video_path)
else:
return "Error creating video."
except Exception as e:
return f"An error occurred: {e}"
finally:
# Ensure session_dir exists before deleting
if os.path.exists(session_dir):
shutil.rmtree(session_dir)
with gr.Blocks() as iface:
gr.Interface(
fn=main,
inputs=gr.Textbox(label="Enter the movie or TV show title:"),
outputs=gr.Video(label="Output Video"),
title="Movie/TV Show Video Summary Generator",
description="Enter a movie or TV show title to generate a summary video with voiceover and background music.<br><h2>Make sure to support me USDT (TRC-20): TAe7hsSVWtMEYz3G5V1UiUdYPQVqm28bKx</h2>"
)
iface.launch() |