diff --git a/.python-version b/.python-version new file mode 100644 index 0000000..fdcfcfd --- /dev/null +++ b/.python-version @@ -0,0 +1 @@ +3.12 \ No newline at end of file diff --git a/WINDOWS_INSTALL.bat b/WINDOWS_INSTALL.bat index f5a0250..81a1f02 100644 --- a/WINDOWS_INSTALL.bat +++ b/WINDOWS_INSTALL.bat @@ -8,9 +8,6 @@ cd /d "%~dp0" :: Japanese: "ja" set MISAKI_LANG=en -:: Set PyTorch CUDA version -set CUDA_VERSION=128 - ::: ::: _ ____ ___ ____ _____ _ _ ::: / \ | __ ) / _ \ / ___|| ____| \ | | @@ -23,6 +20,7 @@ set CUDA_VERSION=128 for /f "delims=: tokens=*" %%A in ('findstr /b ::: "%~f0"') do @echo(%%A set CURRENT_DIR="%CD%" +set "UV_CACHE_DIR=%~dp0.uv_cache" set NAME=abogen set PROJECTFOLDER=abogen set RUN=python_embedded\Scripts\abogen.exe @@ -32,6 +30,28 @@ set refrenv=%PROJECTFOLDER%\refrenv.bat set PYTHON_PATH=python_embedded\pythonw.exe set PYTHON_CONSOLE_PATH=python_embedded\python.exe +:: --------------------------------------------------------- +:: Version Selection +:: --------------------------------------------------------- +echo. +echo Select installation version: +echo [1] Stable (PyPI) - Safer, recommended for most users. +echo [2] Dev (Local) - Install from current folder (may include commits after the latest release). +echo. +choice /C 12 /M "Your choice" + +if errorlevel 2 ( + set INSTALL_SOURCE=dev + echo. + echo Selected: Dev - Local Editable +) else ( + set INSTALL_SOURCE=pypi + echo. + echo Selected: Stable - PyPI +) +echo. +:: --------------------------------------------------------- + :: Check for updates echo Checking for updates... set VERSION_FILE=%PROJECTFOLDER%\VERSION @@ -139,10 +159,10 @@ if exist "%VERSION_FILE%" ( REM Python embedded download configuration for different architectures if "%PROCESSOR_ARCHITECTURE%"=="x86" ( set PYTHON_EMBEDDED_FILE=%PROJECTFOLDER%\python_embedded_win32.zip - set PYTHON_EMBEDDED_URL=https://github.com/wojiushixiaobai/Python-Embed-Win64/releases/download/3.12.8/python-3.12.8-embed-win32.zip + set PYTHON_EMBEDDED_URL=https://github.com/wojiushixiaobai/Python-Embed-Win64/releases/download/3.12.12/python-3.12.12-embed-win32.zip ) else ( set PYTHON_EMBEDDED_FILE=%PROJECTFOLDER%\python_embedded_amd64.zip - set PYTHON_EMBEDDED_URL=https://github.com/wojiushixiaobai/Python-Embed-Win64/releases/download/3.12.8/python-3.12.8-embed-amd64.zip + set PYTHON_EMBEDDED_URL=https://github.com/wojiushixiaobai/Python-Embed-Win64/releases/download/3.12.12/python-3.12.12-embed-amd64.zip ) :: Check if Python exists @@ -200,18 +220,19 @@ if not "%~1"=="" ( echo Open with: "%~1" ) -:: Update pip -echo Updating pip... +:: Update pip and install uv +echo Updating pip and installing uv... %PYTHON_CONSOLE_PATH% -m pip install --upgrade pip --no-warn-script-location +%PYTHON_CONSOLE_PATH% -m pip install uv --no-warn-script-location if errorlevel 1 ( - echo Failed to update pip. + echo Failed to install uv. pause exit /b ) :: Install docopt's fixed version echo Installing fixed version of docopt... -%PYTHON_CONSOLE_PATH% -m pip install --force-reinstall https://github.com/denizsafak/abogen/raw/refs/heads/main/abogen/resources/docopt-0.6.2-py2.py3-none-any.whl --no-warn-script-location +%PYTHON_CONSOLE_PATH% -m uv pip install --system --force-reinstall https://github.com/denizsafak/abogen/raw/refs/heads/main/abogen/resources/docopt-0.6.2-py2.py3-none-any.whl if errorlevel 1 ( echo Failed to install fixed version of docopt. pause @@ -220,7 +241,7 @@ if errorlevel 1 ( :: Install progress's fixed version echo Installing fixed version of progress... -%PYTHON_CONSOLE_PATH% -m pip install --force-reinstall https://github.com/denizsafak/abogen/raw/refs/heads/main/abogen/resources/progress-1.6-py3-none-any.whl --no-warn-script-location +%PYTHON_CONSOLE_PATH% -m uv pip install --system --force-reinstall https://github.com/denizsafak/abogen/raw/refs/heads/main/abogen/resources/progress-1.6-py3-none-any.whl if errorlevel 1 ( echo Failed to install fixed version of progress. pause @@ -229,7 +250,7 @@ if errorlevel 1 ( :: Install setup requirements echo Installing setup requirements... -%PYTHON_CONSOLE_PATH% -m pip install --upgrade setuptools setuptools-scm wheel sphinx hatchling editables --no-warn-script-location +%PYTHON_CONSOLE_PATH% -m uv pip install --system --upgrade setuptools setuptools-scm wheel sphinx hatchling editables if errorlevel 1 ( echo Failed to install setup requirements. pause @@ -238,32 +259,43 @@ if errorlevel 1 ( :: Install gpustat echo Installing gpustat... -%PYTHON_CONSOLE_PATH% -m pip install gpustat --no-warn-script-location +%PYTHON_CONSOLE_PATH% -m uv pip install --system gpustat if errorlevel 1 ( echo Failed to install gpustat. pause exit /b ) -:: Install project and dependencies from pyproject.toml -echo Checking and installing project dependencies... -if exist %PYPROJECT_FILE% ( - echo Installing project from pyproject.toml... - %PYTHON_CONSOLE_PATH% -m pip install -e . --no-warn-script-location +:: Install project based on user selection +if "%INSTALL_SOURCE%"=="pypi" ( + echo Installing stable version from PyPI... + %PYTHON_CONSOLE_PATH% -m uv pip install --system abogen if errorlevel 1 ( - echo Failed to install from pyproject.toml. + echo Failed to install abogen from PyPI. pause exit /b ) ) else ( - echo Warning: pyproject.toml not found in current directory. - pause + echo Checking and installing project dependencies... + if exist %PYPROJECT_FILE% ( + echo Installing project from pyproject.toml using uv... + :: Using uv pip install --system --editable + %PYTHON_CONSOLE_PATH% -m uv pip install --system --editable . + if errorlevel 1 ( + echo Failed to install from pyproject.toml. + pause + exit /b + ) + ) else ( + echo Warning: pyproject.toml not found in current directory. + pause + ) ) -:: Install misaki again if MISAKI_LANG is not set to "en" +:: Install misaki again if MISAKI_LANG is not set to "en" via uv if "%MISAKI_LANG%" NEQ "en" ( echo Configuring language pack: %MISAKI_LANG% - %PYTHON_CONSOLE_PATH% -m pip install misaki[%MISAKI_LANG%] --upgrade --no-warn-script-location + %PYTHON_CONSOLE_PATH% -m uv pip install --system misaki[%MISAKI_LANG%] --upgrade if errorlevel 1 ( echo Failed to install misaki language pack. pause @@ -281,8 +313,10 @@ if /I "%IS_NVIDIA%"=="true" ( for /f %%i in ('%PYTHON_CONSOLE_PATH% -c "from torch.cuda import is_available; print(is_available())"') do set cuda_available=%%i if "%cuda_available%"=="False" ( - echo Installing PyTorch with CUDA %CUDA_VERSION% support... - %PYTHON_CONSOLE_PATH% -m pip install torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cu%CUDA_VERSION% --no-warn-script-location + echo "Installing PyTorch with CUDA (12.8) support..." + :: We need to use an older version of PyTorch (2.8.0) until this issue is fixed: https://github.com/pytorch/pytorch/issues/166628 + :: Solution mentioned by @mazenemam19 in #99: + %PYTHON_CONSOLE_PATH% -m uv pip install --system torch==2.8.0+cu128 torchvision==0.23.0+cu128 torchaudio==2.8.0 --index-url https://download.pytorch.org/whl/cu128 echo. if errorlevel 1 ( echo Failed to install PyTorch. @@ -305,8 +339,10 @@ if /I "%IS_NVIDIA%"=="true" ( if errorlevel 2 ( echo Skipping PyTorch installation. ) else ( - echo Installing PyTorch with CUDA %CUDA_VERSION% support... - %PYTHON_CONSOLE_PATH% -m pip install torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cu%CUDA_VERSION% --no-warn-script-location + echo "Installing PyTorch with CUDA (12.8) support..." + :: We need to use an older version of PyTorch (2.8.0) until this issue is fixed: https://github.com/pytorch/pytorch/issues/166628 + :: Solution mentioned by @mazenemam19 in #99: + %PYTHON_CONSOLE_PATH% -m uv pip install --system torch==2.8.0+cu128 torchvision==0.23.0+cu128 torchaudio==2.8.0 --index-url https://download.pytorch.org/whl/cu128 if errorlevel 1 ( echo Failed to install PyTorch. pause diff --git a/abogen/VERSION b/abogen/VERSION index a5e4282..3a1f10e 100644 --- a/abogen/VERSION +++ b/abogen/VERSION @@ -1 +1 @@ -1.1.9 \ No newline at end of file +1.2.5 \ No newline at end of file diff --git a/abogen/constants.py b/abogen/constants.py index fa88ee7..87bc87b 100644 --- a/abogen/constants.py +++ b/abogen/constants.py @@ -2,9 +2,7 @@ from abogen.utils import get_version # Program Information PROGRAM_NAME = "abogen" -PROGRAM_DESCRIPTION = ( - "Generate audiobooks from EPUBs, PDFs and text with synchronized captions." -) +PROGRAM_DESCRIPTION = "Generate audiobooks from EPUBs, PDFs, text and subtitles with synchronized captions." GITHUB_URL = "https://github.com/denizsafak/abogen" VERSION = get_version() @@ -44,6 +42,7 @@ SUPPORTED_SOUND_FORMATS = [ SUPPORTED_SUBTITLE_FORMATS = [ "srt", "ass", + "vtt", ] # Supported input formats @@ -51,6 +50,9 @@ SUPPORTED_INPUT_FORMATS = [ "epub", "pdf", "txt", + "srt", + "ass", + "vtt", ] # Supported languages for subtitle generation @@ -59,10 +61,7 @@ SUPPORTED_INPUT_FORMATS = [ # Please refer to: https://github.com/hexgrad/kokoro/blob/6d87f4ae7abc2d14dbc4b3ef2e5f19852e861ac2/kokoro/pipeline.py # 383 English processing (unchanged) # 384 if self.lang_code in 'ab': -SUPPORTED_LANGUAGES_FOR_SUBTITLE_GENERATION = [ - "a", - "b", -] +SUPPORTED_LANGUAGES_FOR_SUBTITLE_GENERATION = list(LANGUAGE_DESCRIPTIONS.keys()) # Voice and sample text constants VOICES_INTERNAL = [ @@ -148,6 +147,7 @@ COLORS = { "BLUE_BORDER_HOVER": "#6ab0de", "YELLOW_BACKGROUND": "rgba(255, 221, 51, 0.40)", "GREY_BACKGROUND": "rgba(128, 128, 128, 0.15)", + "GREY_BORDER": "#808080", "RED_BACKGROUND": "rgba(232, 78, 60, 0.15)", "RED_BG": "rgba(232, 78, 60, 0.10)", "RED_BG_HOVER": "rgba(232, 78, 60, 0.15)", diff --git a/abogen/queued_item.py b/abogen/queued_item.py index f8c9ece..38d4054 100644 --- a/abogen/queued_item.py +++ b/abogen/queued_item.py @@ -13,5 +13,9 @@ class QueuedItem: subtitle_mode: str output_format: str total_char_count: int - replace_single_newlines: bool = False + replace_single_newlines: bool = True + use_silent_gaps: bool = False + subtitle_speed_method: str = "tts" save_base_path: str = None + save_chapters_separately: bool = None + merge_chapters_at_end: bool = None diff --git a/demo/abogen.png b/demo/abogen.png index 6ece4fc..5c4a840 100644 Binary files a/demo/abogen.png and b/demo/abogen.png differ diff --git a/demo/abogen2.png b/demo/abogen2.png index 6857f92..cedaa5d 100644 Binary files a/demo/abogen2.png and b/demo/abogen2.png differ diff --git a/demo/queue.png b/demo/queue.png index bc16a2e..ab2d312 100644 Binary files a/demo/queue.png and b/demo/queue.png differ diff --git a/pyproject.toml b/pyproject.toml index 1acff9c..bcfdacd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,12 +13,13 @@ license = "MIT" requires-python = ">=3.10, <3.13" keywords = ["audiobook", "epub", "pdf", "text-to-speech", "subtitle", "tts", "kokoro", "accessibility", "book-converter", "voice-synthesis", "multilingual", "chapter-management", "subtitles", "content-creation", "media-generation"] dependencies = [ + "pip", "kokoro>=0.9.4", "misaki[zh]>=0.9.4", "supertonic>=0.1.0", "ebooklib>=0.19", "beautifulsoup4>=4.13.4", - "spacy>=3.5,<4.0", + "spacy>=3.8.7,<4.0", "en-core-web-sm @ https://github.com/explosion/spacy-models/releases/download/en_core_web_sm-3.8.0/en_core_web_sm-3.8.0-py3-none-any.whl", "PyMuPDF>=1.25.5", "platformdirs>=4.3.7", @@ -90,4 +91,80 @@ include = [ [tool.hatch.version] path = "abogen/VERSION" -pattern = "^(?P.+)$" \ No newline at end of file +pattern = "^(?P.+)$" + +# --- OPTIONAL DEPENDENCIES --- + +[project.optional-dependencies] +# NVIDIA GPU (Windows) (CUDA 12.6) # uv tool install abogen[cuda126] +cuda126 = ["torch"] +# NVIDIA GPU (Windows) (CUDA 12.8) # uv tool install abogen[cuda] +cuda = ["torch"] +# NVIDIA GPU (Windows) (CUDA 13.0) # uv tool install abogen[cuda130] +cuda130 = ["torch"] +# AMD GPU (Linux) (ROCm 6.4) # uv tool install abogen[rocm] +rocm = ["torch", "pytorch-triton-rocm"] +# Development dependencies # uv tool install abogen[dev] +dev = ["build"] + +# --- KOKORO CONFIGURATION (for macOS) --- + +[tool.uv.sources] +kokoro = [ + { git = "https://github.com/hexgrad/kokoro.git", marker = "sys_platform == 'darwin'" }, + { index = "pypi", marker = "sys_platform != 'darwin'" } +] + +# --- TORCH CONFIGURATION --- + +torch = [ + # ROCm 6.4 Nightly (AMD) + { index = "pytorch-rocm-64-nightly", marker = "extra == 'rocm'" }, + + # CUDA 13.0 (NVIDIA) + { index = "pytorch-cuda-130", marker = "extra == 'cuda130' and extra != 'rocm'" }, + + # CUDA 12.6 (NVIDIA) + { index = "pytorch-cuda-126", marker = "extra == 'cuda126' and extra != 'rocm' and extra != 'cuda130'" }, + + # CUDA 12.8 (NVIDIA) + { index = "pytorch-cuda-128", marker = "extra == 'cuda' and extra != 'rocm' and extra != 'cuda130' and extra != 'cuda126'" } +] + +# --- TRITON CONFIGURATION --- + +pytorch-triton-rocm = [ + { index = "pytorch-rocm-64-nightly", marker = "extra == 'rocm'" } +] + +# --- INDEX DEFINITIONS --- + +# PyPI Index +[[tool.uv.index]] +name = "pypi" +url = "https://pypi.org/simple" +default = true + +# CUDA 12.6 Index +[[tool.uv.index]] +name = "pytorch-cuda-126" +url = "https://download.pytorch.org/whl/cu126" +explicit = true + +# CUDA 12.8 Index +[[tool.uv.index]] +name = "pytorch-cuda-128" +url = "https://download.pytorch.org/whl/cu128" +explicit = true + +# CUDA 13.0 Index +[[tool.uv.index]] +name = "pytorch-cuda-130" +url = "https://download.pytorch.org/whl/cu130" +explicit = true + +# ROCm 6.4 Nightly Index +[[tool.uv.index]] +name = "pytorch-rocm-64-nightly" +url = "https://download.pytorch.org/whl/nightly/rocm6.4" +explicit = true