mirror of
https://github.com/open-webui/open-webui
synced 2025-03-03 19:07:21 +00:00
Merge pull request #5509 from open-webui/dev-playback-controls
feat: playback controls
This commit is contained in:
commit
9fc6b999d0
@ -1,15 +1,13 @@
|
||||
<script lang="ts">
|
||||
import { config, models, settings, showCallOverlay } from '$lib/stores';
|
||||
import { onMount, tick, getContext, onDestroy, createEventDispatcher } from 'svelte';
|
||||
import { DropdownMenu } from 'bits-ui';
|
||||
import Dropdown from '$lib/components/common/Dropdown.svelte';
|
||||
import { flyAndScale } from '$lib/utils/transitions';
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
import {
|
||||
blobToFile,
|
||||
calculateSHA256,
|
||||
extractSentencesForAudio,
|
||||
findWordIndices
|
||||
} from '$lib/utils';
|
||||
import { blobToFile } from '$lib/utils';
|
||||
import { generateEmoji } from '$lib/apis';
|
||||
import { synthesizeOpenAISpeech, transcribeAudio } from '$lib/apis/audio';
|
||||
|
||||
@ -360,6 +358,7 @@
|
||||
?.at(0) ?? undefined;
|
||||
|
||||
currentUtterance = new SpeechSynthesisUtterance(content);
|
||||
currentUtterance.rate = $settings.audio?.tts?.speedRate ?? 1;
|
||||
|
||||
if (voice) {
|
||||
currentUtterance.voice = voice;
|
||||
@ -381,11 +380,12 @@
|
||||
const playAudio = (audio) => {
|
||||
if ($showCallOverlay) {
|
||||
return new Promise((resolve) => {
|
||||
const audioElement = document.getElementById('audioElement');
|
||||
const audioElement = document.getElementById('audioElement') as HTMLAudioElement;
|
||||
|
||||
if (audioElement) {
|
||||
audioElement.src = audio.src;
|
||||
audioElement.muted = true;
|
||||
audioElement.playbackRate = $settings.audio?.tts?.speedRate ?? 1;
|
||||
|
||||
audioElement
|
||||
.play()
|
||||
|
@ -204,6 +204,8 @@
|
||||
const blob = await res.blob();
|
||||
const blobUrl = URL.createObjectURL(blob);
|
||||
const audio = new Audio(blobUrl);
|
||||
audio.playbackRate = $settings.audio?.tts?.speedRate ?? 1;
|
||||
|
||||
audioParts[idx] = audio;
|
||||
loadingSpeech = false;
|
||||
lastPlayedAudioPromise = lastPlayedAudioPromise.then(() => playAudio(idx));
|
||||
@ -226,6 +228,7 @@
|
||||
console.log(voice);
|
||||
|
||||
const speak = new SpeechSynthesisUtterance(message.content);
|
||||
speak.rate = $settings.audio?.tts?.speedRate ?? 1;
|
||||
|
||||
console.log(speak);
|
||||
|
||||
@ -410,7 +413,7 @@
|
||||
const isEnterPressed = e.key === 'Enter';
|
||||
|
||||
if (isCmdOrCtrlPressed && isEnterPressed) {
|
||||
document.getElementById('save-edit-message-button')?.click();
|
||||
document.getElementById('confirm-edit-message-button')?.click();
|
||||
}
|
||||
}}
|
||||
/>
|
||||
@ -418,7 +421,7 @@
|
||||
<div class=" mt-2 mb-1 flex justify-between text-sm font-medium">
|
||||
<div>
|
||||
<button
|
||||
id="close-edit-message-button"
|
||||
id="save-new-message-button"
|
||||
class=" px-4 py-2 bg-gray-50 hover:bg-gray-100 dark:bg-gray-800 dark:hover:bg-gray-700 border dark:border-gray-700 text-gray-700 dark:text-gray-200 transition rounded-3xl"
|
||||
on:click={() => {
|
||||
saveNewMessageHandler();
|
||||
|
@ -23,6 +23,10 @@
|
||||
let voices = [];
|
||||
let voice = '';
|
||||
|
||||
// Audio speed control
|
||||
let speechRate = 1;
|
||||
const speedOptions = [2, 1.75, 1.5, 1.25, 1, 0.75, 0.5];
|
||||
|
||||
const getVoices = async () => {
|
||||
if ($config.audio.tts.engine === '') {
|
||||
const getVoicesLoop = setInterval(async () => {
|
||||
@ -56,6 +60,7 @@
|
||||
};
|
||||
|
||||
onMount(async () => {
|
||||
speechRate = $settings.audio?.tts?.speedRate ?? 1;
|
||||
conversationMode = $settings.conversationMode ?? false;
|
||||
speechAutoSend = $settings.speechAutoSend ?? false;
|
||||
responseAutoPlayback = $settings.responseAutoPlayback ?? false;
|
||||
@ -83,6 +88,7 @@
|
||||
engine: STTEngine !== '' ? STTEngine : undefined
|
||||
},
|
||||
tts: {
|
||||
speedRate: speechRate,
|
||||
voice: voice !== '' ? voice : undefined,
|
||||
defaultVoice: $config?.audio?.tts?.voice ?? '',
|
||||
nonLocalVoices: $config.audio.tts.engine === '' ? nonLocalVoices : undefined
|
||||
@ -153,6 +159,21 @@
|
||||
{/if}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class=" py-0.5 flex w-full justify-between">
|
||||
<div class=" self-center text-xs font-medium">{$i18n.t('Speed Rate')}</div>
|
||||
|
||||
<div class="flex items-center relative">
|
||||
<select
|
||||
class="dark:bg-gray-900 w-fit pr-8 rounded px-2 p-1 text-xs bg-transparent outline-none text-right"
|
||||
bind:value={speechRate}
|
||||
>
|
||||
{#each speedOptions as option}
|
||||
<option value={option} selected={speechRate === option}>{option}x</option>
|
||||
{/each}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr class=" dark:border-gray-850" />
|
||||
|
Loading…
Reference in New Issue
Block a user