mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-08 10:44:09 -04:00
Get configuring/rate change working with browser TTS backend
This commit is contained in:
parent
2be891d9dd
commit
6f59dfba54
@ -24,8 +24,14 @@ class Tracker:
|
|||||||
def parse_marked_text(self, marked_text):
|
def parse_marked_text(self, marked_text):
|
||||||
self.clear()
|
self.clear()
|
||||||
text = v'[]'
|
text = v'[]'
|
||||||
text_len = chunk_len = index_in_positions = 0
|
text_len = chunk_len = index_in_positions = offset_in_text = 0
|
||||||
limit = 4096
|
limit = 2048
|
||||||
|
|
||||||
|
def commit():
|
||||||
|
self.queue.push({
|
||||||
|
'text': ''.join(text), 'index_in_positions': index_in_positions,
|
||||||
|
'offset_in_text': offset_in_text, 'reached_offset': 0})
|
||||||
|
|
||||||
for x in marked_text:
|
for x in marked_text:
|
||||||
if jstype(x) is 'number':
|
if jstype(x) is 'number':
|
||||||
self.positions.push({'mark': x, 'offset_in_text': text_len})
|
self.positions.push({'mark': x, 'offset_in_text': text_len})
|
||||||
@ -34,14 +40,14 @@ class Tracker:
|
|||||||
chunk_len += x.length
|
chunk_len += x.length
|
||||||
text.push(x)
|
text.push(x)
|
||||||
if chunk_len > limit:
|
if chunk_len > limit:
|
||||||
self.queue.push({'text': ''.join(text), 'index_in_positions': index_in_positions})
|
commit()
|
||||||
chunk_len = 0
|
chunk_len = 0
|
||||||
text = v'[]'
|
text = v'[]'
|
||||||
index_in_positions = self.positions.length - 1
|
index_in_positions = max(0, self.positions.length - 1)
|
||||||
|
offset_in_text = text_len
|
||||||
if text.length:
|
if text.length:
|
||||||
self.queue.push({'text': ''.join(text), 'index_in_positions': index_in_positions})
|
commit()
|
||||||
self.marked_text = marked_text
|
self.marked_text = marked_text
|
||||||
console.log(self.queue)
|
|
||||||
return self.current_text()
|
return self.current_text()
|
||||||
|
|
||||||
def pop_first(self):
|
def pop_first(self):
|
||||||
@ -56,9 +62,20 @@ class Tracker:
|
|||||||
self.last_pos = 0
|
self.last_pos = 0
|
||||||
if self.queue.length:
|
if self.queue.length:
|
||||||
self.last_pos = self.queue[0].index_in_positions
|
self.last_pos = self.queue[0].index_in_positions
|
||||||
|
if self.queue[0].reached_offset:
|
||||||
|
o = self.queue[0].reached_offset
|
||||||
|
# make sure positions remain the same for word tracking
|
||||||
|
self.queue[0].text = (' ' * o) + self.queue[0].text[o:]
|
||||||
return self.current_text()
|
return self.current_text()
|
||||||
|
|
||||||
|
def boundary_reached(self, start):
|
||||||
|
if self.queue.length:
|
||||||
|
self.queue[0].reached_offset = start
|
||||||
|
|
||||||
def mark_word(self, start, length):
|
def mark_word(self, start, length):
|
||||||
|
if not self.queue.length:
|
||||||
|
return
|
||||||
|
start += self.queue[0].offset_in_text
|
||||||
end = start + length
|
end = start + length
|
||||||
matches = v'[]'
|
matches = v'[]'
|
||||||
while self.last_pos < self.positions.length:
|
while self.last_pos < self.positions.length:
|
||||||
@ -135,14 +152,18 @@ class Client:
|
|||||||
def utterance_failed(self, event):
|
def utterance_failed(self, event):
|
||||||
self.status = {'synthesizing': False, 'paused': False}
|
self.status = {'synthesizing': False, 'paused': False}
|
||||||
self.tracker.clear()
|
self.tracker.clear()
|
||||||
if event.error is not 'interrupted':
|
if event.error is not 'interrupted' and event.error is not 'canceled':
|
||||||
error_dialog(_('Speaking failed'), _(
|
if event.error is 'synthesis-unavailable':
|
||||||
'An error has occurred with speech synthesis: ' + event.error))
|
msg = _('Text-to-Speech not available in this browser. You may need to install some Text-to-Speech software.')
|
||||||
|
else:
|
||||||
|
msg = _('An error has occurred with speech synthesis: ') + event.error
|
||||||
|
error_dialog(_('Speaking failed'), msg)
|
||||||
self.onevent('cancel')
|
self.onevent('cancel')
|
||||||
|
|
||||||
def utterance_boundary_reached(self, event):
|
def utterance_boundary_reached(self, event):
|
||||||
|
self.tracker.boundary_reached(event.charIndex)
|
||||||
if event.name is 'word':
|
if event.name is 'word':
|
||||||
x = self.tracker.mark_word(event.charIndex, event.charLength)
|
x = self.tracker.mark_word(event.charIndex, event.charLength or 2)
|
||||||
if x:
|
if x:
|
||||||
first, last = x[0], x[1]
|
first, last = x[0], x[1]
|
||||||
self.onevent('mark', {'first': first, 'last': last})
|
self.onevent('mark', {'first': first, 'last': last})
|
||||||
@ -157,6 +178,13 @@ class Client:
|
|||||||
def resume(self):
|
def resume(self):
|
||||||
window.speechSynthesis.resume()
|
window.speechSynthesis.resume()
|
||||||
|
|
||||||
|
def pause_for_configure(self):
|
||||||
|
if self.current_utterance:
|
||||||
|
ut = self.current_utterance
|
||||||
|
self.current_utterance = None
|
||||||
|
ut.onstart = ut.onpause = ut.onend = ut.onerror = ut.onresume = None
|
||||||
|
window.speechSynthesis.cancel()
|
||||||
|
|
||||||
def resume_after_configure(self):
|
def resume_after_configure(self):
|
||||||
text = self.tracker.resume()
|
text = self.tracker.resume()
|
||||||
if text and text.length:
|
if text and text.length:
|
||||||
@ -197,8 +225,13 @@ class Client:
|
|||||||
rate /= 10
|
rate /= 10
|
||||||
rate = max(self.min_rate, min(rate, self.max_rate))
|
rate = max(self.min_rate, min(rate, self.max_rate))
|
||||||
if rate is not current_rate:
|
if rate is not current_rate:
|
||||||
|
is_speaking = bool(window.speechSynthesis.speaking)
|
||||||
|
if is_speaking:
|
||||||
|
self.pause_for_configure()
|
||||||
self.current_rate = rate
|
self.current_rate = rate
|
||||||
self.save_settings()
|
self.save_settings()
|
||||||
|
if is_speaking:
|
||||||
|
self.resume_after_configure()
|
||||||
|
|
||||||
def configure(self):
|
def configure(self):
|
||||||
voice_id = unique_id()
|
voice_id = unique_id()
|
||||||
@ -250,7 +283,12 @@ class Client:
|
|||||||
if changed:
|
if changed:
|
||||||
self.current_voice_uri = voice
|
self.current_voice_uri = voice
|
||||||
self.current_rate = rate
|
self.current_rate = rate
|
||||||
|
is_speaking = bool(window.speechSynthesis.speaking)
|
||||||
|
if is_speaking:
|
||||||
|
self.pause_for_configure()
|
||||||
self.save_settings()
|
self.save_settings()
|
||||||
|
if is_speaking:
|
||||||
|
self.resume_after_configure()
|
||||||
|
|
||||||
self.onevent('configured')
|
self.onevent('configured')
|
||||||
)
|
)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user