diff --git a/CHANGELOG.md b/CHANGELOG.md index a6c1ffd..8effa8b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,10 @@ # v1.0.8 (pre-release) - Added support for AMD GPUs in Linux (Special thanks to @hg000125 for his contribution in #23) - Added extra metadata support for chaptered M4B files, ensuring better compatibility with audiobook players. +- Added new option: `Separate chapters audio format`, allowing to choose between `wav`, `mp4`, `flac` and `opus` formats for chaptered audio files. - Skipping PyTorch CUDA installation if GPU is not NVIDIA in WINDOWS_INSTALL.bat script, preventing unnecessary installation of PyTorch. - Fixed voice preview player keeps playing silently at the background after preview ends. +- Fixed not writing separate chapters audio when output is OPUS. - Improved input box background color handling, fixed display issues in Linux. - Better sleep state handling for Linux. - Improvements in documentation and code. diff --git a/abogen/conversion.py b/abogen/conversion.py index 779e3e3..823a26b 100644 --- a/abogen/conversion.py +++ b/abogen/conversion.py @@ -196,6 +196,9 @@ class ConversionThread(QThread): self.log_updated.emit( f"- Merge chapters at the end: {'Yes' if merge_at_end else 'No'}" ) + # Display the separate chapters format if it's set + separate_format = getattr(self, 'separate_chapters_format', 'wav') + self.log_updated.emit(f"- Separate chapters format: {separate_format}") if self.save_option == "Choose output folder": self.log_updated.emit( @@ -504,12 +507,14 @@ class ConversionThread(QThread): # Concatenate chapter audio and save chapter_audio = self.np.concatenate(chapter_audio_segments) - # Determine chapter extension (.wav for m4b output) - chapter_ext = 'wav' if self.output_format == 'm4b' else self.output_format + + # Use separate_chapters_format + separate_format = getattr(self, 'separate_chapters_format', 'wav') + chapter_out_path = os.path.join( - chapters_out_dir, f"{chapter_filename}.{chapter_ext}" + chapters_out_dir, f"{chapter_filename}.{separate_format}" ) - if self.output_format == "opus": + if separate_format == "opus": static_ffmpeg.add_paths() proc = create_process( [ @@ -541,7 +546,7 @@ class ConversionThread(QThread): chapter_out_path, chapter_audio, 24000, - format='wav' if self.output_format == 'm4b' else self.output_format, + format=separate_format, ) # Generate .srt subtitle file for chapter if not Disabled diff --git a/abogen/gui.py b/abogen/gui.py index 485cfc7..bde2a88 100644 --- a/abogen/gui.py +++ b/abogen/gui.py @@ -23,6 +23,7 @@ from PyQt5.QtWidgets import ( QCheckBox, QMenu, QAction, + QActionGroup, ) from PyQt5.QtCore import ( Qt, @@ -519,6 +520,7 @@ class abogen(QWidget): "max_subtitle_words", 50 ) # Default max words per subtitle self.selected_format = self.config.get("selected_format", "wav") + self.separate_chapters_format = self.config.get("separate_chapters_format", "wav") # Format for individual chapter files self.use_gpu = self.config.get( "use_gpu", True # Load GPU setting with default True ) @@ -1307,6 +1309,8 @@ class abogen(QWidget): self.conversion_thread.replace_single_newlines = ( self.replace_single_newlines ) + # Pass separate_chapters_format setting + self.conversion_thread.separate_chapters_format = self.separate_chapters_format # Pass chapter count for EPUB or PDF files if self.selected_file_type in ["epub", "pdf"] and hasattr( self, "selected_chapters" @@ -1620,8 +1624,8 @@ class abogen(QWidget): "Preview Error", "Preview error: No audio generated." ) self.btn_preview.setIcon(self.play_icon) - self.btn_preview.setToolTip("Preview selected voice") self.btn_preview.setEnabled(True) + self.btn_preview.setToolTip("Preview selected voice") self.voice_combo.setEnabled(True) self.btn_voice_formula_mixer.setEnabled(True) # Re-enable mixer button self.btn_start.setEnabled(True) @@ -1804,8 +1808,25 @@ class abogen(QWidget): max_words_action = QAction("Configure max words per subtitle", self) max_words_action.triggered.connect(self.set_max_subtitle_words) menu.addAction(max_words_action) + + # Add separate chapters format option + separate_chapters_format_menu = QMenu("Separate chapters audio format", self) + separate_chapters_format_menu.setToolTip("Choose the format for individual chapter files") + + format_group = QActionGroup(self) + format_group.setExclusive(True) + + for format_option in ["wav", "mp3", "flac", "opus"]: + format_action = QAction(format_option, self) + format_action.setCheckable(True) + format_action.setChecked(self.separate_chapters_format == format_option) + format_action.triggered.connect(lambda checked, fmt=format_option: self.set_separate_chapters_format(fmt)) + format_group.addAction(format_action) + separate_chapters_format_menu.addAction(format_action) + + menu.addMenu(separate_chapters_format_menu) - # Add seperator + # Add separator menu.addSeparator() # Add shortcut to desktop (Windows or Linux) @@ -2295,3 +2316,9 @@ Categories=AudioVideo;Audio;Utility; f"Maximum words per subtitle set to {value}.", ) + def set_separate_chapters_format(self, fmt): + """Set the format for separate chapters audio files.""" + self.separate_chapters_format = fmt + self.config["separate_chapters_format"] = fmt + save_config(self.config) +