├── AI-Audiobook-Maker.sh ├── README.md ├── preview.jpg └── split-pdf-by-page.sh /AI-Audiobook-Maker.sh: -------------------------------------------------------------------------------- 1 | # Function to exit if user presses 'Cancel' on the final confirmation 2 | handle_cancel() { 3 | exit_status=$? 4 | if [ $exit_status -ne 0 ]; then 5 | echo "User pressed Cancel. Exiting script. 👋" 6 | exit 7 | fi 8 | } 9 | 10 | # Function to handle the SIGINT signal (Ctrl-C) 11 | handle_sigint() { 12 | clear 13 | echo -e "\n\n👋 Goodbye! Thank you for using AI-Audiobook-Maker. Have a great day! 🌟\n" 14 | exit 15 | } 16 | 17 | # Trap SIGINT and call handle_sigint function 18 | trap handle_sigint SIGINT 19 | 20 | # Function to calculate the number of parts and cost 21 | calculate_parts_and_cost() { 22 | local input_file=$1 23 | local max_length=$2 24 | local total_chars=$(wc -m < "$input_file") 25 | local total_parts=$((total_chars / max_length)) 26 | [ $((total_chars % max_length)) -gt 0 ] && ((total_parts++)) 27 | echo "$total_parts" 28 | local cost=$(echo "scale=2; $total_chars / 1000 * 0.015" | bc) 29 | printf "$%.2f USD" $cost 30 | } 31 | 32 | split_text_file() { 33 | local input_file=$1 34 | local max_length=$2 35 | local part_prefix=$3 36 | local part_num=1 37 | local buffer="" 38 | local buffer_len=0 39 | 40 | while IFS= read -r line || [ -n "$line" ]; do 41 | if [[ -z $line ]]; then 42 | if (( buffer_len + 2 > max_length )); then 43 | echo "$buffer" > "${part_prefix}${part_num}.txt" 44 | ((part_num++)) 45 | buffer="" 46 | buffer_len=0 47 | fi 48 | buffer+=$'\n\n' 49 | buffer_len=$(( buffer_len + 2 )) 50 | else 51 | if (( buffer_len + ${#line} + 1 > max_length )); then 52 | local last_period_pos=$(echo "$buffer" | grep -o '\.\(.*\)' | tail -1 | wc -c) 53 | local split_pos=$(( ${#buffer} - last_period_pos + 1 )) 54 | if [[ $split_pos -gt 1 ]]; then 55 | local part=${buffer:0:$split_pos} 56 | echo "$part" > "${part_prefix}${part_num}.txt" 57 | ((part_num++)) 58 | buffer=${buffer:$split_pos} 59 | buffer_len=${#buffer} 60 | else 61 | echo "$buffer" > "${part_prefix}${part_num}.txt" 62 | ((part_num++)) 63 | buffer=$line$'\n' 64 | buffer_len=${#line} + 1 65 | fi 66 | else 67 | buffer+=$line$'\n' 68 | buffer_len=$(( buffer_len + ${#line} + 1 )) 69 | fi 70 | fi 71 | done < "$input_file" 72 | 73 | if [ -n "$buffer" ]; then 74 | echo "$buffer" > "${part_prefix}${part_num}.txt" 75 | fi 76 | } 77 | 78 | show_welcome_screen() { 79 | local total_cost=$(calculate_parts_and_cost "input.txt" 4000 | tail -n1) 80 | local welcome_message="Welcome to the Text-to-Speech Conversion Wizard! 🎙️✨\n\nThis tool helps you convert large text files into spoken words, split across multiple MP3 files.\n\n- It respects sentence boundaries, ensuring coherent audio segments.\n- You can choose different voices and control the speech speed.\n- The estimated cost for processing 'input.txt' is $total_cost (as of Jan 2024).\n\nPress OK to start configuring your conversion process." 81 | 82 | dialog --title "Welcome" --msgbox "$welcome_message" 20 60 83 | } 84 | 85 | # Call the welcome screen function at the beginning of the script 86 | show_welcome_screen 87 | 88 | # Ask if the user wants to process a PDF file 89 | exec 3>&1 90 | PROCESS_PDF=$(dialog --title "Process PDF?" --yesno "Do you want to process a PDF file?" 10 50 2>&1 1>&3) 91 | pdf_response=$? 92 | exec 3>&- 93 | 94 | # Check response for processing PDF 95 | if [ $pdf_response -eq 0 ]; then 96 | # Ask for the path to the PDF file 97 | exec 3>&1 98 | PDF_FILE=$(dialog --title "PDF File 📄" --inputbox "Enter the path to the PDF file:" 8 50 2>&1 1>&3) 99 | exec 3>&- 100 | 101 | # Check if the PDF file exists 102 | if [ ! -f "$PDF_FILE" ]; then 103 | dialog --title "File Not Found ❌" --msgbox "The PDF file '$PDF_FILE' was not found. Please place the file in the directory and run the script again." 10 50 104 | exit 1 105 | fi 106 | 107 | dialog --title "Confirmation ✅" --msgbox "PDF file set to '$PDF_FILE' 🗂️" 6 50 108 | # Convert PDF to text and split the text (the function needs to be defined) 109 | convert_pdf_to_text_and_split "$PDF_FILE" "output_txt" 110 | INPUT_FILE="output_txt/full_text.txt" 111 | else 112 | # Ask for input file 113 | exec 3>&1 114 | INPUT_FILE=$(dialog --title "Input File 📄" --inputbox "Enter the path to the input file (default: input.txt):" 8 50 "input.txt" 2>&1 1>&3) 115 | exec 3>&- 116 | 117 | dialog --title "Confirmation ✅" --msgbox "Input file set to '$INPUT_FILE' 🗂️" 6 50 118 | split_text_file "$INPUT_FILE" 4000 "part_" 119 | fi 120 | 121 | # Check for OPENAI_API_KEY 122 | if [ -z "${OPENAI_API_KEY}" ]; then 123 | exec 3>&1 124 | OPENAI_API_KEY=$(dialog --title "OpenAI API Key 🔑" --inputbox "Enter your OpenAI API key:" 8 50 2>&1 1>&3) 125 | exec 3>&- 126 | dialog --title "Confirmation ✅" --msgbox "API Key entered 🌐" 6 50 127 | fi 128 | 129 | # Get voice option 130 | exec 3>&1 131 | VOICE=$(dialog --title "Choose Voice 🗣️" --menu "Choose a voice:" 15 50 6 \ 132 | "alloy" "Alloy voice" \ 133 | "echo" "Echo voice" \ 134 | "fable" "Fable voice" \ 135 | "onyx" "Onyx voice" \ 136 | "nova" "Nova voice" \ 137 | "shimmer" "Shimmer voice" \ 138 | "all" "All voices" 2>&1 1>&3) 139 | exec 3>&- 140 | dialog --title "Confirmation ✅" --msgbox "Voice selected: $VOICE 🎙️" 6 50 141 | 142 | # Get model with additional info 143 | exec 3>&1 144 | MODEL=$(dialog --title "Model Selection 🧠" --menu "Choose the model (tts-1 for speed, tts-1-hd for quality):\n\nPricing: $0.015 per 1,000 characters.\n\nSelect a model:" 15 60 2 \ 145 | "tts-1" "Optimized for speed" \ 146 | "tts-1-hd" "Optimized for quality" 2>&1 1>&3) 147 | exec 3>&- 148 | dialog --title "Confirmation ✅" --msgbox "Model selected: $MODEL 🤖\n\n- tts-1: Best for faster processing.\n- tts-1-hd: Best for high-quality audio." 10 60 149 | 150 | 151 | # Get speed 152 | exec 3>&1 153 | SPEED=$(dialog --title "Speech Speed ⏩" --inputbox "Enter the speed (0.25 - 4.0, default: 1.0):" 8 50 "1.0" 2>&1 1>&3) 154 | exec 3>&- 155 | dialog --title "Confirmation ✅" --msgbox "Speed adjusted to $SPEED ✨" 6 50 156 | 157 | # Calculate parts and cost 158 | TOTAL_PARTS=$(calculate_parts_and_cost "$INPUT_FILE" 4000 | head -n1) 159 | FORMATTED_COST=$(calculate_parts_and_cost "$INPUT_FILE" 4000 | tail -n1) 160 | dialog --title "Estimation 📊" --msgbox "Estimated number of files: $TOTAL_PARTS 📈\nEstimated cost: $FORMATTED_COST 💰" 8 50 161 | 162 | # Final confirmation with cancel check 163 | exec 3>&1 164 | dialog --title "Final Confirmation 🚀" --yesno \ 165 | "Ready to start conversion with these settings?\n\n- Voice: $VOICE\n- Model: $MODEL\n- Speed: $SPEED\n- Estimated number of files: $TOTAL_PARTS\n- Estimated cost: $FORMATTED_COST\n\nPress 'Yes' to start, 'No' to exit." 15 60 166 | exec 3>&- 167 | handle_cancel 168 | 169 | # Check response 170 | if [ $response -eq 1 ]; then 171 | echo "Conversion canceled." 172 | exit 0 173 | fi 174 | clear 175 | # Split and convert logic 176 | split_text_file "$INPUT_FILE" 4000 "part_" 177 | 178 | # Convert each part to an MP3 file 179 | for ((current_part = 1; current_part <= TOTAL_PARTS; current_part++)); do 180 | file="part_${current_part}.txt" 181 | echo -e "Converting part $current_part of $TOTAL_PARTS to MP3 at ${SPEED} speed with voice ${VOICE}... ️🎶" | lolcat 182 | 183 | # Use a pipe to send the content of the file to ospeak with the chosen speed and voice 184 | cat "$file" | ospeak --voice $VOICE --speed $SPEED -o "${file%.txt}.mp3" 185 | if [ $? -ne 0 ]; then 186 | echo -e "❌ Error occurred while converting part $current_part. Exiting." | lolcat 187 | exit 1 188 | fi 189 | done 190 | 191 | # Concatenate all MP3 files 192 | echo -e "Stitching all MP3 files together... 🧵🎵" | lolcat 193 | ffmpeg -f concat -safe 0 -i <(for f in part_*.mp3; do echo "file '$PWD/$f'"; done) -c copy output.mp3 194 | 195 | if [ $? -ne 0 ]; then 196 | clear 197 | echo -e "❌ Error occurred while stitching MP3 files. Exiting." | lolcat 198 | exit 1 199 | fi 200 | clear 201 | echo -e "Final output file 'output.mp3' is ready! 🌟🎉" | lolcat 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # 📖 AI-Audiobook-Maker 🎧 3 | 4 | ## Introduction 5 | Welcome to the **AI-Audiobook-Maker**! 🚀 6 | 7 | This free tool transforms your books, textbooks, or any text document into fantastic sounding audiobooks using OpenAI's state-of-the-art TTS technology. 8 | 9 | Say goodbye to expensive subscriptions on shitty sites, crappy TTS, and other junk, and embrace the freedom of creating audiobooks on demand via API. 🌟 10 | 11 | ## Features 12 | - 📘 **Versatile Text Conversion**: From books to articles, convert any text to audio. 13 | - 🎙️ **Diverse Voice Options**: A wide range of voices to suit your preference. 14 | - 🎚️ **Speed Customization**: Control the narration speed for optimal listening. 15 | - 📊 **Transparent and Affordable Pricing**: Pay as you go without hidden costs via OpenAI. 16 | - 🛠️ **Open Source and Customizable**: Freedom to modify and enhance. 17 | 18 | ## Pricing 19 | Simple, pay-per-use pricing (provided by OpenAI API): 20 | 21 | Rough costs as of Jan 2024: 22 | | Text Length | Estimated Cost | Context | 23 | |----------------------------------|----------------|-----------------------------------| 24 | | 250 words | $0.01875 | Average email | 25 | | 500 words | $0.0375 | Average letter | 26 | | 1,000 words | $0.075 | Blog post, short article | 27 | | 2,500 words | $0.1875 | Long article, short report | 28 | | 5,000 words | $0.375 | Research paper, short story | 29 | | 10,000 words | $0.75 | Long story, small e-book | 30 | | 25,000 words | $1.875 | Novella, thesis | 31 | | 50,000 words (average novel) | $3.75 | Approximate average book length | 32 | | 100,000 words | $7.50 | Long novel, comprehensive guide | 33 | | 200,000 words | $15.00 | Epic novel, extensive research | 34 | 35 | 36 | | Number of Characters | Estimated Cost | Context | 37 | |----------------------|----------------|------------------------------------| 38 | | 1,000 | $0.015 | Short email, brief memo | 39 | | 5,000 | $0.075 | Average email, short article | 40 | | 10,000 | $0.15 | Detailed report, newsletter | 41 | | 25,000 | $0.375 | Long article, short story | 42 | | 50,000 | $0.75 | Extensive report, small e-book | 43 | | 100,000 | $1.50 | Comprehensive guide, long story | 44 | | 250,000 | $3.75 | Novella, academic thesis | 45 | | 500,000 | $7.50 | Full-length novel, extensive guide | 46 | | 1,000,000 | $15.00 | Epic novel, in-depth analysis | 47 | 48 | 49 | **Example**: Converting "Fuzzing The Machine" (240 pages) cost approximately $5.50. 📘💰 50 | 51 | ## How It Works 52 | 1. **Prepare Your Text**: Have your text file ready. 53 | 2. **Run the AI-Audiobook-Maker**: Follow the simple wizard. 54 | 3. **Choose Settings**: Select voice and speed. 55 | 4. **Convert**: Watch as your text becomes an audiobook. 56 | 5. **Listen and Enjoy**: On your favorite device! 57 | 58 | ## Getting Started 59 | ```bash 60 | git clone https://github.com/wowitsjack/AI-Audiobook-Maker.git 61 | cd AI-Audiobook-Maker 62 | ./audiobook_maker.sh 63 | ``` 64 | 65 | ## Dependencies (The script ahould handle this, yo) 66 | - `dialog`: For user interface. 67 | - `lolcat`: For colorful terminal output. 68 | - `ffmpeg`: For audio file processing. 69 | - `ospeak`: OpenAI's text-to-speech CLI tool. 70 | 71 | ![Image 1](preview.jpg) 72 | 73 | ## Contributing 74 | Contributions make the open-source community thrive. Your contributions are **deeply appreciated**. 75 | 76 | ## License 77 | Distributed under the MIT License. See `LICENSE`. 78 | 79 | ## Contact 80 | Don't. 81 | 82 | ## Badges 83 | ## Badges 84 | 85 | [![GitHub stars](https://img.shields.io/github/stars/wowitsjack/AI-Audiobook-Maker.svg?style=social&label=Star)](https://github.com/wowitsjack/AI-Audiobook-Maker) 86 | [![GitHub forks](https://img.shields.io/github/forks/wowitsjack/AI-Audiobook-Maker.svg?style=social&label=Fork)](https://github.com/wowitsjack/AI-Audiobook-Maker/fork) 87 | [![GitHub watchers](https://img.shields.io/github/watchers/wowitsjack/AI-Audiobook-Maker.svg?style=social&label=Watch)](https://github.com/wowitsjack/AI-Audiobook-Maker) 88 | [![GitHub followers](https://img.shields.io/github/followers/wowitsjack.svg?style=social&label=Follow)](https://github.com/wowitsjack) 89 | 90 | -------------------------------------------------------------------------------- /preview.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wowitsjack/AI-Audiobook-Maker/c032f8674dddfaca9f0f09f5172283ee9f19cacf/preview.jpg -------------------------------------------------------------------------------- /split-pdf-by-page.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | input_pdf="notbad.pdf" 4 | output_directory="output_txt" 5 | 6 | # Create output directory if it doesn't exist 7 | mkdir -p "$output_directory" 8 | 9 | # Convert PDF to text 10 | pdftotext "$input_pdf" "$output_directory/full_text.txt" 11 | 12 | # Split text file into parts based on pages and rename 13 | cd "$output_directory" 14 | csplit -s -z full_text.txt '/^$/' {*} 15 | counter=1 16 | 17 | for file in xx*; do 18 | mv "$file" "$(printf "part_%04d.txt" "$counter")" 19 | ((counter++)) 20 | done 21 | 22 | echo "Conversion completed. Text files saved in $output_directory." 23 | --------------------------------------------------------------------------------