mirror of
https://github.com/denizsafak/abogen.git
synced 2026-07-18 21:50:28 +02:00
Added new option Configure silence between chapters
This commit is contained in:
+3
-1
@@ -1,7 +1,9 @@
|
|||||||
# 1.1.8 (pre-release)
|
# 1.1.8 (pre-release)
|
||||||
- Added `.md` (Markdown) file extension support by @brianxiadong in PR #75
|
- Added `.md` (Markdown) file extension support by @brianxiadong in PR #75
|
||||||
|
- Added new option `Configure silence between chapters` that lets users configure the silence between chapters, mentioned by @lfperez1982 in #79
|
||||||
- Improved the markdown logic to better handle various markdown structures and edge cases.
|
- Improved the markdown logic to better handle various markdown structures and edge cases.
|
||||||
- Fixed `No Qt platform plugin could be initialized` error, mentioned in #59 by @sunrainxyz
|
- Fixed `No Qt platform plugin could be initialized` error, mentioned by @sunrainxyz in #59
|
||||||
|
- Improvements in code and documentation.
|
||||||
|
|
||||||
# 1.1.7
|
# 1.1.7
|
||||||
- Added MPS GPU acceleration support for Silicon Mac, mentioned in https://github.com/denizsafak/abogen/issues/32#issuecomment-3155902040 by @jefro108. **Please read the [Mac](https://github.com/denizsafak/abogen?tab=readme-ov-file#mac) section in the documentation again, as it requires additional configuration.**
|
- Added MPS GPU acceleration support for Silicon Mac, mentioned in https://github.com/denizsafak/abogen/issues/32#issuecomment-3155902040 by @jefro108. **Please read the [Mac](https://github.com/denizsafak/abogen?tab=readme-ov-file#mac) section in the documentation again, as it requires additional configuration.**
|
||||||
|
|||||||
@@ -151,6 +151,7 @@ Here’s Abogen in action: in this demo, it processes ∼3,000 characters of tex
|
|||||||
|---------|-------------|
|
|---------|-------------|
|
||||||
| **Theme** | Change the application's theme using `System`, `Light`, or `Dark` options. |
|
| **Theme** | Change the application's theme using `System`, `Light`, or `Dark` options. |
|
||||||
| **Configure max words per subtitle** | Configures the maximum number of words per subtitle entry. |
|
| **Configure max words per subtitle** | Configures the maximum number of words per subtitle entry. |
|
||||||
|
| **Configure silence between chapters** | Configures the duration of silence between chapters (in seconds). |
|
||||||
| **Configure max lines in log window** | Configures the maximum number of lines to display in the log window. |
|
| **Configure max lines in log window** | Configures the maximum number of lines to display in the log window. |
|
||||||
| **Separate chapters audio format** | Configures the audio format for separate chapters as `wav`, `flac`, `mp3`, or `opus`. |
|
| **Separate chapters audio format** | Configures the audio format for separate chapters as `wav`, `flac`, `mp3`, or `opus`. |
|
||||||
| **Create desktop shortcut** | Creates a shortcut on your desktop for easy access. |
|
| **Create desktop shortcut** | Creates a shortcut on your desktop for easy access. |
|
||||||
|
|||||||
@@ -176,6 +176,7 @@ class ConversionThread(QThread):
|
|||||||
self.waiting_for_user_input = False
|
self.waiting_for_user_input = False
|
||||||
self.use_gpu = use_gpu # Store the GPU setting
|
self.use_gpu = use_gpu # Store the GPU setting
|
||||||
self.max_subtitle_words = 50 # Default value, will be overridden from GUI
|
self.max_subtitle_words = 50 # Default value, will be overridden from GUI
|
||||||
|
self.silence_duration = 2.0 # Default value, will be overridden from GUI
|
||||||
|
|
||||||
def _stream_audio_in_chunks(
|
def _stream_audio_in_chunks(
|
||||||
self, segments, process_func, progress_prefix="Processing"
|
self, segments, process_func, progress_prefix="Processing"
|
||||||
@@ -286,6 +287,12 @@ class ConversionThread(QThread):
|
|||||||
f"- Separate chapters format: {separate_format}"
|
f"- Separate chapters format: {separate_format}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# If merge_at_end is True, display the silence duration
|
||||||
|
if getattr(self, "merge_chapters_at_end", True):
|
||||||
|
self.log_updated.emit(
|
||||||
|
f"- Silence between chapters: {self.silence_duration} seconds"
|
||||||
|
)
|
||||||
|
|
||||||
if self.save_option == "Choose output folder":
|
if self.save_option == "Choose output folder":
|
||||||
self.log_updated.emit(
|
self.log_updated.emit(
|
||||||
f"- Output folder: {self.output_folder or os.getcwd()}"
|
f"- Output folder: {self.output_folder or os.getcwd()}"
|
||||||
@@ -899,6 +906,22 @@ class ConversionThread(QThread):
|
|||||||
# Update progress more frequently (after each result)
|
# Update progress more frequently (after each result)
|
||||||
self.progress_updated.emit(percent, etr_str)
|
self.progress_updated.emit(percent, etr_str)
|
||||||
|
|
||||||
|
# Add silence between chapters for merged output (except after the last chapter)
|
||||||
|
if merge_chapters_at_end and chapter_idx < total_chapters:
|
||||||
|
silence_samples = int(self.silence_duration * 24000) # Silence duration at 24,000 Hz
|
||||||
|
silence_audio = self.np.zeros(silence_samples, dtype="float32")
|
||||||
|
silence_bytes = silence_audio.tobytes()
|
||||||
|
|
||||||
|
if merged_out_file:
|
||||||
|
merged_out_file.write(silence_audio)
|
||||||
|
elif ffmpeg_proc:
|
||||||
|
ffmpeg_proc.stdin.write(silence_bytes)
|
||||||
|
|
||||||
|
# Update timing for the silence
|
||||||
|
current_time += self.silence_duration
|
||||||
|
if chapter_out_file or chapter_ffmpeg_proc:
|
||||||
|
chapter_current_time += self.silence_duration
|
||||||
|
|
||||||
# Set chapter end time after processing
|
# Set chapter end time after processing
|
||||||
if merge_chapters_at_end:
|
if merge_chapters_at_end:
|
||||||
chapter_time["end"] = current_time
|
chapter_time["end"] = current_time
|
||||||
|
|||||||
@@ -689,6 +689,9 @@ class abogen(QWidget):
|
|||||||
self.max_subtitle_words = self.config.get(
|
self.max_subtitle_words = self.config.get(
|
||||||
"max_subtitle_words", 50
|
"max_subtitle_words", 50
|
||||||
) # Default max words per subtitle
|
) # Default max words per subtitle
|
||||||
|
self.silence_duration = self.config.get(
|
||||||
|
"silence_duration", 2.0
|
||||||
|
) # Default silence duration
|
||||||
self.selected_format = self.config.get("selected_format", "wav")
|
self.selected_format = self.config.get("selected_format", "wav")
|
||||||
self.separate_chapters_format = self.config.get(
|
self.separate_chapters_format = self.config.get(
|
||||||
"separate_chapters_format", "wav"
|
"separate_chapters_format", "wav"
|
||||||
@@ -1862,6 +1865,8 @@ class abogen(QWidget):
|
|||||||
self.conversion_thread.file_size_str = file_size_str
|
self.conversion_thread.file_size_str = file_size_str
|
||||||
# Pass max_subtitle_words from config
|
# Pass max_subtitle_words from config
|
||||||
self.conversion_thread.max_subtitle_words = self.max_subtitle_words
|
self.conversion_thread.max_subtitle_words = self.max_subtitle_words
|
||||||
|
# Pass silence_duration from config
|
||||||
|
self.conversion_thread.silence_duration = self.silence_duration
|
||||||
# Pass replace_single_newlines setting
|
# Pass replace_single_newlines setting
|
||||||
self.conversion_thread.replace_single_newlines = (
|
self.conversion_thread.replace_single_newlines = (
|
||||||
self.replace_single_newlines
|
self.replace_single_newlines
|
||||||
@@ -2815,6 +2820,11 @@ class abogen(QWidget):
|
|||||||
max_words_action.triggered.connect(self.set_max_subtitle_words)
|
max_words_action.triggered.connect(self.set_max_subtitle_words)
|
||||||
menu.addAction(max_words_action)
|
menu.addAction(max_words_action)
|
||||||
|
|
||||||
|
# Add silence between chapters option
|
||||||
|
silence_action = QAction("Configure silence between chapters", self)
|
||||||
|
silence_action.triggered.connect(self.set_silence_between_chapters)
|
||||||
|
menu.addAction(silence_action)
|
||||||
|
|
||||||
max_lines_action = QAction("Configure max lines in log window", self)
|
max_lines_action = QAction("Configure max lines in log window", self)
|
||||||
max_lines_action.triggered.connect(self.set_max_log_lines)
|
max_lines_action.triggered.connect(self.set_max_log_lines)
|
||||||
menu.addAction(max_lines_action)
|
menu.addAction(max_lines_action)
|
||||||
@@ -3471,6 +3481,40 @@ Categories=AudioVideo;Audio;Utility;
|
|||||||
f"Maximum words per subtitle set to {value}.",
|
f"Maximum words per subtitle set to {value}.",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def set_silence_between_chapters(self):
|
||||||
|
"""Open a dialog to set the silence duration between chapters"""
|
||||||
|
from PyQt5.QtWidgets import QInputDialog, QDialog
|
||||||
|
|
||||||
|
current_value = self.config.get("silence_duration", 2.0)
|
||||||
|
|
||||||
|
dlg = QInputDialog(self)
|
||||||
|
dlg.setWindowTitle("Silence Duration (seconds)")
|
||||||
|
dlg.setLabelText(
|
||||||
|
"Enter the duration of silence\nbetween chapters (in seconds):"
|
||||||
|
)
|
||||||
|
dlg.setInputMode(QInputDialog.DoubleInput)
|
||||||
|
dlg.setDoubleDecimals(1)
|
||||||
|
dlg.setDoubleMinimum(0.0)
|
||||||
|
dlg.setDoubleMaximum(60.0)
|
||||||
|
dlg.setDoubleValue(current_value)
|
||||||
|
dlg.setDoubleStep(0.1) # <-- set step to 0.1
|
||||||
|
|
||||||
|
if dlg.exec_() == QDialog.Accepted:
|
||||||
|
value = dlg.doubleValue()
|
||||||
|
# Round to one decimal to avoid floating-point representation noise
|
||||||
|
value = round(value, 1)
|
||||||
|
|
||||||
|
# Save the new value
|
||||||
|
self.silence_duration = value
|
||||||
|
self.config["silence_duration"] = value
|
||||||
|
save_config(self.config)
|
||||||
|
|
||||||
|
# Show confirmation (format with one decimal)
|
||||||
|
QMessageBox.information(
|
||||||
|
self,
|
||||||
|
"Setting Saved",
|
||||||
|
f"Silence duration between chapters set to {value:.1f} seconds.",
|
||||||
|
)
|
||||||
def set_separate_chapters_format(self, fmt):
|
def set_separate_chapters_format(self, fmt):
|
||||||
"""Set the format for separate chapters audio files."""
|
"""Set the format for separate chapters audio files."""
|
||||||
self.separate_chapters_format = fmt
|
self.separate_chapters_format = fmt
|
||||||
|
|||||||
Reference in New Issue
Block a user