Wire up progress UI for tts embed

This commit is contained in:
Kovid Goyal 2024-10-17 14:48:44 +05:30
parent b4c2478948
commit aaa3d2f658
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
2 changed files with 40 additions and 13 deletions

View File

@ -494,7 +494,7 @@ def embed_tts(container, report_progress=None, callback_to_download_voices=None)
audio_map[s] = audio_data, duration
size_of_audio_data += len(audio_data)
snum += 1
if report_progress(stage, _('Sentence number: {}').format(snum), snum, total_num_sentences):
if report_progress(stage, _('Sentence: {0} of {1}').format(snum, total_num_sentences), snum, total_num_sentences):
return False
wav = io.BytesIO()
wav.write(wav_header_for_pcm_data(size_of_audio_data, HIGH_QUALITY_SAMPLE_RATE))

View File

@ -4,9 +4,11 @@
import os
import sys
import traceback
from time import monotonic
from qt.core import QDialogButtonBox, QHBoxLayout, QIcon, QStackedLayout, Qt, QTextBrowser, QVBoxLayout, QWidget, pyqtSignal
from qt.core import QDialog, QDialogButtonBox, QHBoxLayout, QIcon, QLabel, QProgressBar, QStackedLayout, Qt, QTextBrowser, QVBoxLayout, QWidget, pyqtSignal
from calibre.db.utils import human_readable_interval
from calibre.gui2 import error_dialog
from calibre.gui2.tweak_book.widgets import Dialog
from calibre.gui2.widgets import BusyCursor
@ -45,14 +47,39 @@ class Progress(QWidget):
cancel_requested: bool = False
current_stage: str = ''
stage_start_at: float = 0
def __init__(self, parent: QWidget = None):
super().__init__(parent)
self.v = v = QVBoxLayout(self)
v.setAlignment(Qt.AlignmentFlag.AlignCenter)
v.setContentsMargins(0, 0, 0, 0)
v.addStretch(10)
self.stage_label = la = QLabel(self)
v.addWidget(la, alignment=Qt.AlignmentFlag.AlignCenter)
self.bar = b = QProgressBar(self)
v.addWidget(b)
self.detail_label = la = QLabel(self)
v.addWidget(la, alignment=Qt.AlignmentFlag.AlignCenter)
self.time_left = la = QLabel(self)
v.addWidget(la, alignment=Qt.AlignmentFlag.AlignCenter)
v.addStretch(10)
def __call__(self, stage: str, item: str, count: int, total: int) -> bool:
self.stage_label.setText('<b>' + stage)
self.detail_label.setText(item)
self.detail_label.setVisible(bool(item))
self.bar.setRange(0, total)
self.bar.setValue(count)
now = monotonic()
if self.current_stage != stage:
self.stage_start_at = now
self.current_stage = stage
if (time_elapsed := now - self.stage_start_at) >= 5:
rate = count / time_elapsed
time_left = (total - count) / rate
self.time_left.setText(_('Time to complete this stage: {1}').format(stage, human_readable_interval(time_left)))
else:
self.time_left.setText(_('Estimating time left'))
return self.cancel_requested
@ -64,13 +91,13 @@ class TTSEmbed(Dialog):
def __init__(self, container, parent=None):
self.container = container
super().__init__(_('Add Text-to-speech narration'), 'tts-overlay-dialog', parent=parent)
def setup_ui(self):
from threading import Thread
self.worker_thread = Thread(target=self.worker, daemon=True)
self.worker_done.connect(self.on_worker_done, type=Qt.ConnectionType.QueuedConnection)
self.ensure_voices_downloaded_signal.connect(self.do_ensure_voices_downloaded, type=Qt.ConnectionType.QueuedConnection)
super().__init__(_('Add Text-to-speech narration'), 'tts-overlay-dialog', parent=parent)
def setup_ui(self):
self.v = v = QVBoxLayout(self)
self.engine_settings_widget = e = EngineSettingsWidget(self)
self.stack = s = QStackedLayout()
@ -152,10 +179,11 @@ class TTSEmbed(Dialog):
with BusyCursor():
self.progress.cancel_requested = True
self.bb.setEnabled(False)
self.setWindowTitle(_('Cancelling, please wait...'))
self.worker_thread.join()
return super().reject()
def develop():
from calibre.ebooks.oeb.polish.container import get_container
from calibre.gui2 import Application
@ -163,14 +191,13 @@ def develop():
container = get_container(path, tweak_mode=True)
app = Application([])
d = TTSEmbed(container)
d.exec()
del d
del app
if d.exec() == QDialog.DialogCode.Accepted:
b, e = os.path.splitext(path)
outpath = b + '-tts' + e
container.commit(outpath)
print('Output saved to:', outpath)
del d
del app
if __name__ == '__main__':