diff --git a/README.md b/README.md index 4b388f5..adbeb2c 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@

Python Beginner-Friendly Projects

- A curated collection of 9 simple yet practical Python projects — perfect for beginners learning loops, functions, logic, and file handling. + A curated collection of 10 simple yet practical Python projects — perfect for beginners learning loops, functions, logic, and file handling.

@@ -35,6 +35,8 @@ You'll find small but useful programs — great for understanding **core syntax, | 7️⃣ | ✅ [To-Do List](To-Do-list/) | Manage daily tasks with add/remove features. | | 8️⃣ | 🗂️ [File Organizer](file-organizer/) | Automatically sort files into folders by extension. | | 9️⃣ | 🔢 [Unit Converter](unit-converter/) | Convert between common measurement units. | +| 🔟 | 🔊 [Document to Audio Converter](document-to-audio-converter/) | Convert text from documents (`.docx`) into spoken audio. | + --- diff --git a/document-to-audio-converter/Readme.md b/document-to-audio-converter/Readme.md new file mode 100644 index 0000000..168c7dc --- /dev/null +++ b/document-to-audio-converter/Readme.md @@ -0,0 +1,89 @@ +# Document to Audio Converter + +A simple Python utility to convert text from Microsoft Word (`.docx`) documents into spoken audio. You can either listen to the audio directly or save it as a `.wav` file. + +This script uses a simple, dialog-based interface for file selection and options. + +## Features + +- Reads text content from `.docx` files. +- Converts the extracted text into speech. +- **Option 1:** Speak the text aloud, paragraph by paragraph. +- **Option 2:** Save the entire text as a single `.wav` audio file. +- Handles missing dependencies and file-opening errors gracefully. + +## Requirements + +- Python 3.x +- The following Python libraries: + - `pyttsx3` + - `python-docx` + - `pypiwin32` (often required by `pyttsx3` on Windows) + +## Installation + +1. Clone this repository or download the `Pdftoaudio.py` script. + +2. Install the required libraries using pip: + + ```bash + pip install pyttsx3 python-docx pypiwin32 + ``` + +## How to Use + +1. Run the script from your terminal: + + ```bash + python Pdftoaudio.py + ``` + +2. A file dialog will open. Select the `.docx` document you want to convert. + +3. A dialog box will ask if you want to save the audio to a file. + - Click **"Yes"** to open a "Save As" dialog and save the output as a `.wav` file. + - Click **"No"** to have the script speak the document's text aloud directly. + +4. Follow the on-screen prompts. Status messages will be printed to the console. + +## Recent Code Improvements + +The script was recently refactored to improve its quality, robustness, and maintainability. Key improvements include: + +- **Dependency Management:** Imports are now organized at the top of the file. A startup check was added to ensure the `python-docx` library is installed, providing a user-friendly error message if it's missing. +- **Robustness:** + - The `tkinter` root window is now managed with a `contextmanager`, ensuring it is always properly destroyed. + - A `try...finally` block was added around the text-to-speech engine logic to guarantee that `engine.stop()` is called, preventing the engine from hanging in case of an error. +- **Code Structure & Readability:** + - The `pyttsx3` engine setup was moved into its own helper function (`_initialize_engine`) to keep the main logic clean. + - Type hints and docstrings were added to all functions, making the code self-documenting and easier to understand. + +## Future Roadmap + +This project is a great starting point, and there are several exciting features planned for the future to make it more powerful and user-friendly. + +- **Support for More File Formats:** + - Add support for reading text from **PDF files** (`.pdf`). + - Add support for plain text files (`.txt`). + +- **Full Graphical User Interface (GUI):** + - Move away from simple dialog boxes to a complete GUI built with a framework like `tkinter` or `PyQt`. + - The GUI would include features like a progress bar, play/pause/stop controls for live playback, and status displays. + +- **Enhanced Audio Controls:** + - Allow the user to select from available system voices. + - Provide a slider or input box to adjust the speech rate and volume directly from the UI. + +- **Cross-Platform Compatibility:** + - Test and ensure the script works seamlessly on macOS and Linux. This may involve handling different text-to-speech engine backends. + +- **Application Packaging:** + - Package the application as a standalone executable (e.g., using `PyInstaller`) so that users can run it without needing to have Python or any libraries installed. + +## Contributing + +Contributions are welcome! If you'd like to help with any of the features on the roadmap or fix a bug, please feel free to fork the repository and submit a pull request. + +## License + +This project is licensed under the MIT License. See the `LICENSE` file for details. \ No newline at end of file diff --git a/document-to-audio-converter/WordtoAudio.py b/document-to-audio-converter/WordtoAudio.py new file mode 100644 index 0000000..c4cf4f2 --- /dev/null +++ b/document-to-audio-converter/WordtoAudio.py @@ -0,0 +1,85 @@ +import pyttsx3 +from tkinter import Tk, messagebox +from tkinter.filedialog import askopenfilename, asksaveasfilename +from contextlib import contextmanager + +try: + import docx +except ImportError: + # Use a dummy Tk instance for the error message if docx is not installed + root = Tk() + root.withdraw() + messagebox.showerror("Dependency Error", "python-docx library not found.\nPlease install it with: pip install python-docx") + root.destroy() + exit() + +@contextmanager +def tkinter_root(): + """Context manager for a withdrawn tkinter root window.""" + root = Tk() + root.withdraw() + try: + yield root + finally: + root.destroy() + +def _initialize_engine() -> pyttsx3.Engine: + """Initializes and configures the pyttsx3 engine.""" + engine = pyttsx3.init() + rate = engine.getProperty("rate") + engine.setProperty("rate", max(100, rate - 50)) # Slow down a bit more for clarity + engine.setProperty("volume", 1.0) + return engine + +def docx_to_audio(docx_path: str): + """Reads a .docx file and converts its text to audio.""" + try: + document = docx.Document(docx_path) + except Exception as e: + messagebox.showerror("Error", f"Failed to open Word document:\n{e}") + return + + paragraphs = [p.text for p in document.paragraphs if p.text.strip()] + if not paragraphs: + messagebox.showwarning("No text", "No text found in the Word document.") + return + + save_file = messagebox.askyesno("Save audio", "Save audio to a file instead of speaking?") + engine = _initialize_engine() + + try: + if save_file: + out_path = asksaveasfilename(title="Save audio as", defaultextension=".wav", + filetypes=[("WAV files", "*.wav"), ("All files", "*.*")]) + if not out_path: + messagebox.showinfo("Cancelled", "Save cancelled.") + return + text_to_speak = "\n\n".join(paragraphs) + engine.save_to_file(text_to_speak, out_path) + engine.runAndWait() + messagebox.showinfo("Done", f"Audio saved to:\n{out_path}") + else: + # speak paragraph by paragraph to keep responsiveness + for i, paragraph_text in enumerate(paragraphs, start=1): + if not paragraph_text.strip(): + continue + print(f"Speaking paragraph {i}/{len(paragraphs)}...") + engine.say(paragraph_text) + engine.runAndWait() + except Exception as e: + messagebox.showerror("Error", f"Failed during speech processing:\n{e}") + finally: + engine.stop() + +def main(): + """Main function to run the docx to audio converter.""" + with tkinter_root(): + docx_path = askopenfilename(title="Select Word Document", filetypes=[("Word Documents", "*.docx")]) + if not docx_path: + print("No file selected. Exiting.") + return + + docx_to_audio(docx_path) + +if __name__ == "__main__": + main() \ No newline at end of file