drewThomasson's picture
Create new_app.py
40c8999 verified
raw
history blame
5.24 kB
# 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()