import gradio as gr import json import os from datetime import datetime import tempfile import io from gtts import gTTS import pytesseract from PIL import Image import zipfile # Global state for projects PROJECTS_FILE = "projects.json" current_project_id = None def load_projects(): """Load projects from JSON file""" if os.path.exists(PROJECTS_FILE): with open(PROJECTS_FILE, 'r') as f: return json.load(f) return { "projects": { "1": { "id": "1", "name": "Sample Script", "content": "Welcome to ScriptVoice! This is your first script. Start editing to create amazing voice content.", "notes": "This is a sample note for your script.", "created_at": datetime.now().isoformat(), "word_count": 0 } }, "settings": { "dyslexic_mode": False, "voice_speed": 1.0, "voice_volume": 1.0 } } def save_projects(data): """Save projects to JSON file""" with open(PROJECTS_FILE, 'w') as f: json.dump(data, f, indent=2) def get_word_count(text): """Count words in text""" if not text: return 0 return len(text.split()) def update_word_count(text): """Update word count display""" count = get_word_count(text) return f"**Word Count:** {count}" def create_new_project(name): """Create a new project""" if not name.strip(): return "Please enter a project name", None data = load_projects() new_id = str(len(data["projects"]) + 1) data["projects"][new_id] = { "id": new_id, "name": name.strip(), "content": "", "notes": "", "created_at": datetime.now().isoformat(), "word_count": 0 } save_projects(data) # Return updated project choices and select the new project choices = [(proj["name"], proj_id) for proj_id, proj in data["projects"].items()] return f"Project '{name}' created successfully!", gr.update(choices=choices, value=new_id) def load_project(project_id): """Load a specific project""" if not project_id: return "", "", "**Word Count:** 0" global current_project_id current_project_id = project_id data = load_projects() if project_id in data["projects"]: project = data["projects"][project_id] word_count = get_word_count(project["content"]) return project["content"], project["notes"], f"**Word Count:** {word_count}" return "", "", "**Word Count:** 0" def save_script_content(project_id, content, notes): """Save script content and notes""" if not project_id: return "No project selected" data = load_projects() if project_id in data["projects"]: data["projects"][project_id]["content"] = content data["projects"][project_id]["notes"] = notes data["projects"][project_id]["word_count"] = get_word_count(content) save_projects(data) return "✅ Saved successfully" return "❌ Error saving" def generate_tts(text, speed=1.0): """Generate TTS audio from text""" if not text.strip(): return None, "Please enter some text to convert to speech" try: # Create a temporary file for the audio tts = gTTS(text=text, lang='en', slow=(speed < 1.0)) # Use a temporary file with tempfile.NamedTemporaryFile(delete=False, suffix='.mp3') as tmp_file: tts.save(tmp_file.name) return tmp_file.name, "✅ Audio generated successfully" except Exception as e: return None, f"❌ Error generating audio: {str(e)}" def extract_text_from_image(image): """Extract text from uploaded image using OCR""" if image is None: return "", "Please upload an image" try: # Use pytesseract to extract text text = pytesseract.image_to_string(Image.open(image)) if text.strip(): return text.strip(), "✅ Text extracted successfully" else: return "", "No text found in the image" except Exception as e: return "", f"❌ Error extracting text: {str(e)}" def enhance_script_placeholder(text, enhancement_type): """Placeholder for AI script enhancement""" enhancements = { "dramatic": f"[DRAMATIC VERSION]\n{text}\n\n(Note: AI enhancement feature coming soon!)", "romantic": f"[ROMANTIC VERSION]\n{text}\n\n(Note: AI enhancement feature coming soon!)", "professional": f"[PROFESSIONAL VERSION]\n{text}\n\n(Note: AI enhancement feature coming soon!)", "casual": f"[CASUAL VERSION]\n{text}\n\n(Note: AI enhancement feature coming soon!)" } return enhancements.get(enhancement_type, text), "✅ Enhancement applied (demo mode)" def export_project(project_id, export_type): """Export project content""" if not project_id: return None, "No project selected" data = load_projects() if project_id not in data["projects"]: return None, "Project not found" project = data["projects"][project_id] if export_type == "text": # Create text file content = f"Project: {project['name']}\n" content += f"Created: {project['created_at']}\n" content += f"Word Count: {project['word_count']}\n\n" content += "SCRIPT:\n" + "="*50 + "\n" content += project['content'] + "\n\n" content += "NOTES:\n" + "="*50 + "\n" content += project['notes'] with tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='.txt', encoding='utf-8') as tmp_file: tmp_file.write(content) return tmp_file.name, "✅ Text file exported" elif export_type == "audio": # Generate TTS audio if not project['content'].strip(): return None, "No content to convert to audio" try: tts = gTTS(text=project['content'], lang='en') with tempfile.NamedTemporaryFile(delete=False, suffix='.mp3') as tmp_file: tts.save(tmp_file.name) return tmp_file.name, "✅ Audio file exported" except Exception as e: return None, f"❌ Error generating audio: {str(e)}" return None, "Invalid export type" # Initialize the Gradio interface def create_interface(): """Create the main Gradio interface""" # Load initial projects data = load_projects() project_choices = [(proj["name"], proj_id) for proj_id, proj in data["projects"].items()] with gr.Blocks(title="ScriptVoice - TTS Script Editor", theme=gr.themes.Soft()) as app: # Header gr.HTML("""
AI-Powered TTS Script Editor