from dotenv import load_dotenv import gradio as gr import os from pathlib import Path import tempfile from datetime import datetime # Added for date formatting from numpy.matlib import result_type from sympy import true from extract_metadata import get_metadata, get_scenes_metadata from find_steps import find_all_steps from video_editing import crop_video, get_final_video import json from video_editing_ffmpeg import concatenate_videos from grok_analyze import create_caps_with_grok, get_story_with_grok from concurrent.futures import ThreadPoolExecutor import random import string import json from upload_to_s3 import upload_multiple_files import ast from create_captions import create_caps, add_captions_to_video from transcripts_editing import get_dialog load_dotenv() # Access the variables bucket = os.getenv("BUCKET") def generate_storyline(metadata, filenames,selected_date): if not metadata or not filenames: return None, "No metadata or files provided." print("Metadata:", metadata) print("Filenames:", filenames) if selected_date: try: formatted_date = datetime.fromtimestamp(selected_date).strftime('%Y-%m-%d') print("Selected Date:", formatted_date) dialog=get_dialog(formatted_date) except (TypeError, ValueError): formatted_date = "Invalid date provided" else: dialog="" metadata=get_scenes_metadata(metadata) steps=get_story_with_grok(metadata,"",dialog) print("here are the steps", steps) caps=create_caps(steps) final_video=concatenate_videos(steps) final_video=add_captions_to_video(final_video,False,caps) result = [] for start, end, description in caps: # Format the time range and description, skipping empty descriptions if description.strip(): # Only include if description is not empty result.append(f"{start:.3f}-{end:.3f}, {description.strip()}") else: result.append(f"{start:.3f}-{end:.3f}") # Join all entries into a single string with newlines output = "\n".join(result) return steps,output,final_video #,steps,caps # Placeholder function for video generation def generate_video(steps,caps): """ Generate a video using context and metadata. In a real implementation, this would process metadata to create a video. """ # caps=ast.literal_eval(caps) result = [] for line in caps.strip().split('\n'): # Split the line into time range and description (if present) parts = line.split(',', 1) time_range = parts[0].strip() description = parts[1].strip() if len(parts) > 1 else '' # Split the time range into start and end start, end = map(float, time_range.split('-')) # Append tuple to result result.append((start, end, description)) caps=result # steps =ast.literal_eval(steps) print("CAPS",caps) print("STEPS",steps) final_video=concatenate_videos(steps) # steps=create_caps_with_grok(steps) final_video=add_captions_to_video(final_video,False,caps) return final_video,"done" # Function to handle file uploads def upload_files(uploaded_files): if not uploaded_files: return None, None, "No files uploaded." # Extract metadata and filenames metadata_file="" for file in uploaded_files: if file.name.lower().endswith('.json'): metadata_file=file.name if metadata_file=="": random_string = 'a'.join(random.choices(string.ascii_lowercase + string.digits, k=8)) tuple_list = [(path,random_string+"/"+os.path.splitext(os.path.basename(path))[0]) for path in uploaded_files] executor = ThreadPoolExecutor(max_workers=1) # Adjust max_workers as needed future = executor.submit(upload_multiple_files, tuple_list, bucket) metadata, filename = get_metadata(uploaded_files) # with ThreadPoolExecutor() as executor: # future = executor.submit(upload_multiple_files,tuple_list,bucket) else: with open(metadata_file, 'r') as file: metadata = json.load(file) return metadata, metadata_file, "Files uploaded successfully." print("Uploaded files:", filename) print("Metadata:", metadata) return metadata, filename, "Files uploaded successfully." # Gradio interface with gr.Blocks() as demo: gr.Markdown("# Story Generation App") with gr.Row(): with gr.Column(): file_input = gr.File(label="Upload Images, Videos or metadata", file_count="multiple", file_types=["image", "video",'.json']) date_picker = gr.DateTime(label="Select Date", info="Select the date in which you wore the device, if applicable") # Added datepicker upload_button = gr.Button("Upload Files (video, image, metadata)") gr.Markdown("Generate Video") generate_captions = gr.Button("Generate Video!") # steps = gr.Textbox(label="Generated Storyline",interactive=True) caps=gr.Textbox(label="Generated Captions",interactive=True) gr.Markdown("Modify and add new captions to the final video") generate_button = gr.Button("Modify Captions!") with gr.Column(): video_output = gr.Video(label="Generated Video") upload_output = gr.Textbox(label="Upload Status") generation_status = gr.Textbox(label="Generation Status") # State to store metadata and filenames metadata_state = gr.State() filenames_state = gr.State() # steps_state = gr.State() # caps_state = gr.State() steps=gr.State() # caps=gr.State() # steps.change( # fn=lambda x: x, # inputs=steps, # outputs=steps_state # ) # caps.change( # fn=lambda x: x, # inputs=caps, # outputs=caps_state # ) # Connect buttons to functions upload_button.click( fn=upload_files, inputs=file_input, outputs=[metadata_state, filenames_state, upload_output] ) generate_captions.click( fn=generate_storyline, inputs=[metadata_state, filenames_state,date_picker], # outputs=[steps_state, caps_state,steps, caps] outputs=[steps, caps,video_output] ) generate_button.click( fn=generate_video, inputs=[steps, caps], outputs=[video_output, generation_status] ) # Launch the app (Pyodide-compatible launch) # demo.launch(share=true) demo.launch()