mirror of
https://github.com/denizsafak/abogen.git
synced 2026-07-18 13:40:27 +02:00
Add label for m4b output format, improvements
This commit is contained in:
+2
-1
@@ -1 +1,2 @@
|
|||||||
- Better approach for detemining the correct configuration folder for Linux and MacOS, using platformdirs.
|
- Added support for chapter metadata in m4b audio files, enabling proper chapter navigation in audiobooks. Special thanks to @jborza for implementing this feature in PR #10.
|
||||||
|
- Better approach for determining the correct configuration folder for Linux and MacOS, using platformdirs.
|
||||||
@@ -12,6 +12,7 @@ from utils import clean_text
|
|||||||
from constants import PROGRAM_NAME, LANGUAGE_DESCRIPTIONS, SAMPLE_VOICE_TEXTS
|
from constants import PROGRAM_NAME, LANGUAGE_DESCRIPTIONS, SAMPLE_VOICE_TEXTS
|
||||||
from voice_formulas import get_new_voice
|
from voice_formulas import get_new_voice
|
||||||
import static_ffmpeg
|
import static_ffmpeg
|
||||||
|
import threading # for efficient waiting
|
||||||
|
|
||||||
def get_sample_voice_text(lang_code):
|
def get_sample_voice_text(lang_code):
|
||||||
return SAMPLE_VOICE_TEXTS.get(lang_code, SAMPLE_VOICE_TEXTS["a"])
|
return SAMPLE_VOICE_TEXTS.get(lang_code, SAMPLE_VOICE_TEXTS["a"])
|
||||||
@@ -128,6 +129,7 @@ class ConversionThread(QThread):
|
|||||||
use_gpu=True,
|
use_gpu=True,
|
||||||
): # Add use_gpu parameter
|
): # Add use_gpu parameter
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
self._chapter_options_event = threading.Event()
|
||||||
self.np = np_module
|
self.np = np_module
|
||||||
self.KPipeline = kpipeline_class
|
self.KPipeline = kpipeline_class
|
||||||
self.file_name = file_name
|
self.file_name = file_name
|
||||||
@@ -252,18 +254,12 @@ class ConversionThread(QThread):
|
|||||||
and not self.chapter_options_set
|
and not self.chapter_options_set
|
||||||
):
|
):
|
||||||
|
|
||||||
self.waiting_for_user_input = True
|
# Emit signal to main thread and wait
|
||||||
# Emit signal to main thread to show dialog
|
|
||||||
self.chapters_detected.emit(total_chapters)
|
self.chapters_detected.emit(total_chapters)
|
||||||
|
self._chapter_options_event.wait()
|
||||||
# Wait for chapter options to be set
|
|
||||||
while self.waiting_for_user_input and not self.cancel_requested:
|
|
||||||
time.sleep(0.1)
|
|
||||||
|
|
||||||
if self.cancel_requested:
|
if self.cancel_requested:
|
||||||
self.conversion_finished.emit("Cancelled", None)
|
self.conversion_finished.emit("Cancelled", None)
|
||||||
return
|
return
|
||||||
|
|
||||||
self.chapter_options_set = True
|
self.chapter_options_set = True
|
||||||
|
|
||||||
# Log all detected chapters at the beginning
|
# Log all detected chapters at the beginning
|
||||||
@@ -607,6 +603,7 @@ class ConversionThread(QThread):
|
|||||||
self.save_chapters_separately = options["save_chapters_separately"]
|
self.save_chapters_separately = options["save_chapters_separately"]
|
||||||
self.merge_chapters_at_end = options["merge_chapters_at_end"]
|
self.merge_chapters_at_end = options["merge_chapters_at_end"]
|
||||||
self.waiting_for_user_input = False
|
self.waiting_for_user_input = False
|
||||||
|
self._chapter_options_event.set()
|
||||||
|
|
||||||
def _generate_m4b_with_chapters(self, out_path, chapters_time):
|
def _generate_m4b_with_chapters(self, out_path, chapters_time):
|
||||||
# generate chapters.txt in the same folder as the output file
|
# generate chapters.txt in the same folder as the output file
|
||||||
|
|||||||
+11
-6
@@ -670,13 +670,18 @@ class abogen(QWidget):
|
|||||||
format_layout = QVBoxLayout()
|
format_layout = QVBoxLayout()
|
||||||
format_layout.addWidget(QLabel("Output Format:", self))
|
format_layout.addWidget(QLabel("Output Format:", self))
|
||||||
self.format_combo = QComboBox(self)
|
self.format_combo = QComboBox(self)
|
||||||
self.format_combo.setStyleSheet(
|
self.format_combo.setStyleSheet("QComboBox { min-height: 20px; padding: 6px 12px; }")
|
||||||
"QComboBox { min-height: 20px; padding: 6px 12px; }"
|
# Add items with display labels and underlying keys
|
||||||
|
for key, label in [("wav","wav"),("flac","flac"),("mp3","mp3"),("m4b","m4b (with chapters)")]:
|
||||||
|
self.format_combo.addItem(label, key)
|
||||||
|
# Initialize selection by matching saved key
|
||||||
|
idx = self.format_combo.findData(self.selected_format)
|
||||||
|
if idx >= 0:
|
||||||
|
self.format_combo.setCurrentIndex(idx)
|
||||||
|
# Map selection back to key on change
|
||||||
|
self.format_combo.currentIndexChanged.connect(
|
||||||
|
lambda i: self.on_format_changed(self.format_combo.itemData(i))
|
||||||
)
|
)
|
||||||
format_options = ["wav", "flac", "mp3", "m4b"]
|
|
||||||
self.format_combo.addItems(format_options)
|
|
||||||
self.format_combo.setCurrentText(self.selected_format)
|
|
||||||
self.format_combo.currentTextChanged.connect(self.on_format_changed)
|
|
||||||
format_layout.addWidget(self.format_combo)
|
format_layout.addWidget(self.format_combo)
|
||||||
controls_layout.addLayout(format_layout)
|
controls_layout.addLayout(format_layout)
|
||||||
# Save location
|
# Save location
|
||||||
|
|||||||
Reference in New Issue
Block a user