# Global variables for dropdown and checkbox character_accent = None use_narrator_voice_y_n = None # List of languages for character accents languages = ['en', 'es', 'fr', 'de', 'it', 'pt', 'pl', 'tr', 'ru', 'nl', 'cs', 'ar', 'zh-cn', 'hu', 'ko', 'ja', 'hi'] # Function to process the ebook and start the subprocess def process_ebook(ebook_file, character_accent, use_narrator_voice_y_n, state): if not ebook_file: return "No file uploaded.", state # Pre-download the xtts TOS agreed file import download_tos_agreed_file import nltk nltk.download('averaged_perceptron_tagger_eng') nltk.download('punkt_tab') # Download the en_core_web_sm spacy model subprocess.run(["python", "-m", "spacy", "download", "en_core_web_sm"]) # Create input_files directory if it doesn't exist input_dir = "input_files" if not os.path.exists(input_dir): os.mkdir(input_dir) # Copy the uploaded file to input_files folder input_file_path = os.path.join(input_dir, os.path.basename(ebook_file)) shutil.copy(ebook_file, input_file_path) # Print the name of the uploaded file ebook_file_name = os.path.basename(ebook_file) initial_output = f"Uploaded file: {ebook_file_name}\n" # Initialize state with subprocess info state = { "process": None, "output": initial_output, "lock": threading.Lock() } # Start the subprocess in a separate thread thread = threading.Thread(target=run_subprocess, args=(input_file_path, character_accent, use_narrator_voice_y_n, state), daemon=True) thread.start() return initial_output, state # Function to run the subprocess and capture its output def run_subprocess(input_file_path, character_accent, use_narrator_voice_y_n, state): try: # Start the subprocess with additional arguments process = subprocess.Popen( ["python3", "Headless_VoxNovel.py", input_file_path, character_accent, use_narrator_voice_y_n], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, bufsize=1 # Line-buffered ) with state["lock"]: state["process"] = process # Continuously read the subprocess output for line in iter(process.stdout.readline, ''): with state["lock"]: state["output"] += line process.stdout.close() process.wait() with state["lock"]: state["output"] += "\nProcess finished." except Exception as e: with state["lock"]: state["output"] += f"\nError: {str(e)}" # Gradio Interface with gr.Blocks() as gui: gr.Markdown("### Ebook to Audiobook Converter") with gr.Row(): with gr.Column(): ebook_input = gr.File( label="Upload your ebook file (epub, pdf, etc.)", type='filepath' # Specify that we want the file path ) # Add dropdown for character accent accent_dropdown = gr.Dropdown( label="Character Accent", choices=languages, value="en" # Default to English ) # Add checkbox for narrator voice narrator_checkbox = gr.Checkbox( label="Use Narrator Voice for All", value=False # Default is 'n' (false) ) process_button = gr.Button("Start Processing") status_output = gr.Textbox(label="Status", lines=20) # Initialize state state = gr.State() # Start processing and update status in real-time process_button.click( process_ebook, inputs=[ebook_input, accent_dropdown, narrator_checkbox, state], outputs=[status_output, state] ) with gr.Column(): gr.Markdown("### Subprocess Input") # Textbox to allow user to send input to subprocess user_input_box = gr.Textbox(label="Send Input to Subprocess") submit_input_button = gr.Button("Submit Input") submit_input_button.click( send_input, inputs=[user_input_box, state], outputs=status_output # Corrected to pass the actual Gradio component ) with gr.Column(): gr.Markdown("### Download Generated Audiobook Files") download_button = gr.Button("Reload Files") file_output = gr.File( label="Generated Audiobook Files", file_count="multiple", type='filepath' # Corrected the type to 'filepath' ) # Update the file_output component with the list of output files download_button.click(fn=list_output_files, inputs=[], outputs=file_output) # Periodically update the status_output textbox def periodic_update(state): return get_output(state) # Use Gradio's `every` method to update every second gui.load( periodic_update, inputs=state, outputs=status_output, every=1 # Update every second ) gui.launch()