drewThomasson commited on
Commit
4a45bb8
1 Parent(s): a105e1c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +136 -81
app.py CHANGED
@@ -2,12 +2,38 @@ print("starting...")
2
 
3
  import argparse
4
 
5
- # Argument parser to handle optional parameters
6
- parser = argparse.ArgumentParser(description="Launch the Gradio app with optional share parameter.")
7
- parser.add_argument("--share", type=bool, default=False, help="Set to True to enable Gradio share link.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
  args = parser.parse_args()
9
 
10
 
 
11
  import os
12
  import shutil
13
  import subprocess
@@ -15,7 +41,6 @@ import re
15
  from pydub import AudioSegment
16
  import tempfile
17
  from pydub import AudioSegment
18
- import os
19
  import nltk
20
  from nltk.tokenize import sent_tokenize
21
  import sys
@@ -162,15 +187,24 @@ def create_m4b_from_chapters(input_dir, ebook_file, output_dir):
162
  except Exception as e:
163
  print(f"Error extracting eBook metadata or cover: {e}")
164
  return None
165
- # Combine WAV files into a single file
166
- def combine_wav_files(chapter_files, output_path):
167
  # Initialize an empty audio segment
168
  combined_audio = AudioSegment.empty()
169
-
170
- # Sequentially append each file to the combined_audio
171
- for chapter_file in chapter_files:
172
- audio_segment = AudioSegment.from_wav(chapter_file)
173
- combined_audio += audio_segment
 
 
 
 
 
 
 
 
 
174
  # Export the combined audio to the output file path
175
  combined_audio.export(output_path, format='wav')
176
  print(f"Combined audio saved to {output_path}")
@@ -234,7 +268,7 @@ def create_m4b_from_chapters(input_dir, ebook_file, output_dir):
234
 
235
 
236
 
237
- #this code right here isnt the book grabbing thing but its before to refrence in ordero to create the sepecial chapter labeled book thing with calibre idk some systems cant seem to get it so just in case but the next bit of code after this is the book grabbing code with booknlp
238
  import os
239
  import subprocess
240
  import ebooklib
@@ -682,78 +716,99 @@ def download_audiobooks():
682
  return list_audiobook_files(audiobook_output_path)
683
 
684
 
685
- language_options = [
686
- "en", "es", "fr", "de", "it", "pt", "pl", "tr", "ru", "nl", "cs", "ar", "zh-cn", "ja", "hu", "ko"
687
- ]
688
-
689
- theme = gr.themes.Soft(
690
- primary_hue="blue",
691
- secondary_hue="blue",
692
- neutral_hue="blue",
693
- text_size=gr.themes.sizes.text_md,
694
- )
695
-
696
  # Gradio UI setup
697
- with gr.Blocks(theme=theme) as demo:
698
- gr.Markdown(
699
- """
700
- # eBook to Audiobook Converter
701
-
702
- Transform your eBooks into immersive audiobooks with optional custom TTS models.
703
-
704
- This interface is based on [Ebook2AudioBookXTTS](https://github.com/DrewThomasson/ebook2audiobookXTTS).
705
- """
706
- )
707
-
708
- with gr.Row():
709
- with gr.Column(scale=3):
710
- ebook_file = gr.File(label="eBook File")
711
- target_voice_file = gr.File(label="Target Voice File (Optional)")
712
- language = gr.Dropdown(label="Language", choices=language_options, value="en")
713
-
714
- with gr.Column(scale=3):
715
- use_custom_model = gr.Checkbox(label="Use Custom Model")
716
- custom_model_file = gr.File(label="Custom Model File (Optional)", visible=False)
717
- custom_config_file = gr.File(label="Custom Config File (Optional)", visible=False)
718
- custom_vocab_file = gr.File(label="Custom Vocab File (Optional)", visible=False)
719
- custom_model_url = gr.Textbox(label="Custom Model Zip URL (Optional)", visible=False)
720
-
721
- convert_btn = gr.Button("Convert to Audiobook", variant="primary")
722
- output = gr.Textbox(label="Conversion Status")
723
- audio_player = gr.Audio(label="Audiobook Player", type="filepath")
724
- download_btn = gr.Button("Download Audiobook Files")
725
- download_files = gr.File(label="Download Files", interactive=False)
726
-
727
- convert_btn.click(
728
- convert_ebook_to_audio,
729
- inputs=[ebook_file, target_voice_file, language, use_custom_model, custom_model_file, custom_config_file, custom_vocab_file, custom_model_url],
730
- outputs=[output, audio_player]
731
- )
732
-
733
- use_custom_model.change(
734
- lambda x: [gr.update(visible=x)] * 4,
735
- inputs=[use_custom_model],
736
- outputs=[custom_model_file, custom_config_file, custom_vocab_file, custom_model_url]
737
- )
738
-
739
- download_btn.click(
740
- download_audiobooks,
741
- outputs=[download_files]
742
  )
743
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
744
 
 
 
 
 
 
 
745
 
 
 
746
 
747
- #demo.launch(share=True)
748
- #demo.launch() # Removing share = True for Gradio Interface
749
-
750
- # Get the correct local IP or localhost
751
- hostname = socket.gethostname()
752
- local_ip = socket.gethostbyname(hostname)
753
-
754
- # Ensure Gradio runs and prints the correct local IP
755
- print(f"Running on local URL: http://{local_ip}:7860")
756
- print(f"Running on local URL: http://localhost:7860")
757
-
758
- # Your Gradio launch command
759
- demo.launch(server_name="0.0.0.0", server_port=7860, share=args.share)
 
2
 
3
  import argparse
4
 
5
+ language_options = [
6
+ "en", "es", "fr", "de", "it", "pt", "pl", "tr", "ru", "nl", "cs", "ar", "zh-cn", "ja", "hu", "ko"
7
+ ]
8
+
9
+ # Convert the list of languages to a string to display in the help text
10
+ language_options_str = ", ".join(language_options)
11
+
12
+ # Argument parser to handle optional parameters with descriptions
13
+ parser = argparse.ArgumentParser(
14
+ description="Convert eBooks to Audiobooks using a Text-to-Speech model. You can either launch the Gradio interface or run the script in headless mode for direct conversion.",
15
+ epilog="Example: python script.py --headless --ebook path_to_ebook --voice path_to_voice --language en --use_custom_model True --custom_model model.pth --custom_config config.json --custom_vocab vocab.json"
16
+ )
17
+ parser.add_argument("--share", type=bool, default=False, help="Set to True to enable a public shareable Gradio link. Defaults to False.")
18
+ parser.add_argument("--headless", type=bool, default=False, help="Set to True to run in headless mode without the Gradio interface. Defaults to False.")
19
+ parser.add_argument("--ebook", type=str, help="Path to the ebook file for conversion. Required in headless mode.")
20
+ parser.add_argument("--voice", type=str, help="Path to the target voice file for TTS. Optional, uses a default voice if not provided.")
21
+ parser.add_argument("--language", type=str, default="en",
22
+ help=f"Language for the audiobook conversion. Options: {language_options_str}. Defaults to English (en).")
23
+ parser.add_argument("--use_custom_model", type=bool, default=False,
24
+ help="Set to True to use a custom TTS model. Defaults to False. Must be True to use custom models, otherwise you'll get an error.")
25
+ parser.add_argument("--custom_model", type=str, help="Path to the custom model file (.pth). Required if using a custom model.")
26
+ parser.add_argument("--custom_config", type=str, help="Path to the custom config file (config.json). Required if using a custom model.")
27
+ parser.add_argument("--custom_vocab", type=str, help="Path to the custom vocab file (vocab.json). Required if using a custom model.")
28
+ parser.add_argument("--custom_model_url", type=str,
29
+ help=("URL to download the custom model as a zip file. Optional, but will be used if provided. "
30
+ "Examples include David Attenborough's model: "
31
+ "'https://huggingface.co/drewThomasson/xtts_David_Attenborough_fine_tune/resolve/main/Finished_model_files.zip?download=true'. "
32
+ "More XTTS fine-tunes can be found on my Hugging Face at 'https://huggingface.co/drewThomasson'."))
33
  args = parser.parse_args()
34
 
35
 
36
+
37
  import os
38
  import shutil
39
  import subprocess
 
41
  from pydub import AudioSegment
42
  import tempfile
43
  from pydub import AudioSegment
 
44
  import nltk
45
  from nltk.tokenize import sent_tokenize
46
  import sys
 
187
  except Exception as e:
188
  print(f"Error extracting eBook metadata or cover: {e}")
189
  return None
190
+ # Combine WAV files into a single file
191
+ def combine_wav_files(chapter_files, output_path, batch_size=256):
192
  # Initialize an empty audio segment
193
  combined_audio = AudioSegment.empty()
194
+
195
+ # Process the chapter files in batches
196
+ for i in range(0, len(chapter_files), batch_size):
197
+ batch_files = chapter_files[i:i + batch_size]
198
+ batch_audio = AudioSegment.empty() # Initialize an empty AudioSegment for the batch
199
+
200
+ # Sequentially append each file in the current batch to the batch_audio
201
+ for chapter_file in batch_files:
202
+ audio_segment = AudioSegment.from_wav(chapter_file)
203
+ batch_audio += audio_segment
204
+
205
+ # Combine the batch audio with the overall combined_audio
206
+ combined_audio += batch_audio
207
+
208
  # Export the combined audio to the output file path
209
  combined_audio.export(output_path, format='wav')
210
  print(f"Combined audio saved to {output_path}")
 
268
 
269
 
270
 
271
+ #this code right here isnt the book grabbing thing but its before to refrence in order to create the sepecial chapter labeled book thing with calibre idk some systems cant seem to get it so just in case but the next bit of code after this is the book grabbing code with booknlp
272
  import os
273
  import subprocess
274
  import ebooklib
 
716
  return list_audiobook_files(audiobook_output_path)
717
 
718
 
 
 
 
 
 
 
 
 
 
 
 
719
  # Gradio UI setup
720
+ def run_gradio_interface():
721
+ language_options = [
722
+ "en", "es", "fr", "de", "it", "pt", "pl", "tr", "ru", "nl", "cs", "ar", "zh-cn", "ja", "hu", "ko"
723
+ ]
724
+
725
+ theme = gr.themes.Soft(
726
+ primary_hue="blue",
727
+ secondary_hue="blue",
728
+ neutral_hue="blue",
729
+ text_size=gr.themes.sizes.text_md,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
730
  )
731
 
732
+ with gr.Blocks(theme=theme) as demo:
733
+ gr.Markdown(
734
+ """
735
+ # eBook to Audiobook Converter
736
+
737
+ Transform your eBooks into immersive audiobooks with optional custom TTS models.
738
+
739
+ This interface is based on [Ebook2AudioBookXTTS](https://github.com/DrewThomasson/ebook2audiobookXTTS).
740
+ """
741
+ )
742
+
743
+ with gr.Row():
744
+ with gr.Column(scale=3):
745
+ ebook_file = gr.File(label="eBook File")
746
+ target_voice_file = gr.File(label="Target Voice File (Optional)")
747
+ language = gr.Dropdown(label="Language", choices=language_options, value="en")
748
+
749
+ with gr.Column(scale=3):
750
+ use_custom_model = gr.Checkbox(label="Use Custom Model")
751
+ custom_model_file = gr.File(label="Custom Model File (Optional)", visible=False)
752
+ custom_config_file = gr.File(label="Custom Config File (Optional)", visible=False)
753
+ custom_vocab_file = gr.File(label="Custom Vocab File (Optional)", visible=False)
754
+ custom_model_url = gr.Textbox(label="Custom Model Zip URL (Optional)", visible=False)
755
+
756
+ convert_btn = gr.Button("Convert to Audiobook", variant="primary")
757
+ output = gr.Textbox(label="Conversion Status")
758
+ audio_player = gr.Audio(label="Audiobook Player", type="filepath")
759
+ download_btn = gr.Button("Download Audiobook Files")
760
+ download_files = gr.File(label="Download Files", interactive=False)
761
+
762
+ convert_btn.click(
763
+ convert_ebook_to_audio,
764
+ inputs=[ebook_file, target_voice_file, language, use_custom_model, custom_model_file, custom_config_file, custom_vocab_file, custom_model_url],
765
+ outputs=[output, audio_player]
766
+ )
767
+
768
+ use_custom_model.change(
769
+ lambda x: [gr.update(visible=x)] * 4,
770
+ inputs=[use_custom_model],
771
+ outputs=[custom_model_file, custom_config_file, custom_vocab_file, custom_model_url]
772
+ )
773
+
774
+ download_btn.click(
775
+ download_audiobooks,
776
+ outputs=[download_files]
777
+ )
778
+
779
+ # Get the correct local IP or localhost
780
+ hostname = socket.gethostname()
781
+ local_ip = socket.gethostbyname(hostname)
782
+
783
+ # Ensure Gradio runs and prints the correct local IP
784
+ print(f"Running on local URL: http://{local_ip}:7860")
785
+ print(f"Running on local URL: http://localhost:7860")
786
+
787
+ # Launch Gradio app
788
+ demo.launch(server_name="0.0.0.0", server_port=7860, share=args.share)
789
+
790
+
791
+
792
+ # Check if running in headless mode
793
+ if args.headless:
794
+ if not args.ebook:
795
+ print("Error: In headless mode, you must specify an ebook file using --ebook.")
796
+ exit(1)
797
+
798
+ ebook_file_path = args.ebook
799
+ target_voice = args.voice if args.voice else None
800
+ custom_model = None
801
 
802
+ if args.use_custom_model:
803
+ custom_model = {
804
+ 'model': args.custom_model,
805
+ 'config': args.custom_config,
806
+ 'vocab': args.custom_vocab
807
+ }
808
 
809
+ # Example headless execution
810
+ convert_ebook_to_audio(ebook_file_path, target_voice, args.language, args.use_custom_model, args.custom_model, args.custom_config, args.custom_vocab)
811
 
812
+ else:
813
+ # Launch Gradio UI
814
+ run_gradio_interface()