feat: add volume control

This commit is contained in:
verbiricha 2023-09-10 14:03:13 +02:00
parent 216311951b
commit fc37cfe92d
5 changed files with 33 additions and 6 deletions

View File

@ -404,6 +404,9 @@
"x82IOl": {
"defaultMessage": "Mute"
},
"y867Vs": {
"defaultMessage": "Volume"
},
"yzKwBQ": {
"defaultMessage": "eg. nsec1xyz"
},

View File

@ -27,6 +27,7 @@ function ZapAlertConfiguration({ npub, baseUrl }: ZapAlertConfigurationProps) {
const [textToSpeech, setTextToSpeech] = useState<boolean>(false);
const [voice, setVoice] = useState<string | null>(null);
const [minSatsForTextToSpeech, setMinSatsForTextToSpeech] = useState<string>("21");
const [volume, setVolume] = useState<number>(1);
// Google propietary voices are not available on OBS browser
const voices = getVoices().filter(v => !v.name.includes("Google"));
@ -47,14 +48,15 @@ function ZapAlertConfiguration({ npub, baseUrl }: ZapAlertConfigurationProps) {
const params = toTextToSpeechParams({
voiceURI: voice,
minSats: voice ? Number(minSatsForTextToSpeech) : null,
volume,
});
const queryParams = params.toString();
return queryParams.length > 0 ? `?${queryParams}` : "";
}, [voice, minSatsForTextToSpeech]);
}, [voice, volume, minSatsForTextToSpeech]);
function testVoice() {
if (selectedVoice) {
speak(selectedVoice, testText);
speak(selectedVoice, testText, volume);
}
}
@ -103,6 +105,20 @@ function ZapAlertConfiguration({ npub, baseUrl }: ZapAlertConfigurationProps) {
onChange={ev => setMinSatsForTextToSpeech(ev.target.value)}
/>
</div>
<div className="paper labeled-input">
<label htmlFor="volume">
<FormattedMessage defaultMessage="Volume" />
</label>
<input
id="volume"
type="number"
min="0"
max="1"
step="0.1"
value={volume}
onChange={ev => setVolume(Number(ev.target.value))}
/>
</div>
<div className="paper labeled-input">
<label htmlFor="voice-selector">
<FormattedMessage defaultMessage="Voice" />

View File

@ -39,7 +39,7 @@ export function ZapAlerts({ link }: { link: NostrLink }) {
const zaps = useZaps(currentLink, true);
const zap = useZapQueue(zaps);
const mutedPubkeys = useMutedPubkeys(host, true);
const { voiceURI, minSats } = useTextToSpeechParams();
const { voiceURI, minSats, volume } = useTextToSpeechParams();
const voices = getVoices();
const voice = useMemo(() => {
return voices.find(v => v.voiceURI === voiceURI);
@ -56,7 +56,7 @@ export function ZapAlerts({ link }: { link: NostrLink }) {
if (text.length > 0 && voice) {
try {
if (zap.amount >= minSats) {
speak(voice, text);
speak(voice, text, volume);
}
} catch (e) {
console.error(e);

View File

@ -9,18 +9,21 @@ function useQuery() {
interface TextToSpeechConfig {
voiceURI: string | null;
minSats: number;
volume: number;
}
export function useTextToSpeechParams(): TextToSpeechConfig {
const q = useQuery();
const voiceURI = q.get("voiceURI");
const minSats = Number(q.get("minSats")) ?? 21;
return { voiceURI, minSats };
const volume = Number(q.get("volume")) ?? 1;
return { voiceURI, minSats, volume };
}
interface TextToSpeechConfigParams {
voiceURI: string | null;
minSats: number | null;
volume: number | null;
}
export function toTextToSpeechParams(config: TextToSpeechConfigParams): URLSearchParams {
@ -31,6 +34,9 @@ export function toTextToSpeechParams(config: TextToSpeechConfigParams): URLSearc
if (config.minSats) {
params.set("minSats", String(config.minSats));
}
if (config.volume) {
params.set("volume", String(config.volume));
}
return params;
}
@ -41,10 +47,11 @@ export function getVoices() {
return [];
}
export function speak(voice: SpeechSynthesisVoice, text: string) {
export function speak(voice: SpeechSynthesisVoice, text: string, volume: number) {
try {
const utterance = new SpeechSynthesisUtterance(text);
utterance.voice = voice;
utterance.volume = volume;
utterance.rate = 0.8;
speechSynthesis.speak(utterance);
} catch (e) {

View File

@ -134,6 +134,7 @@
"wOy57k": "Add stream goal",
"wzWWzV": "Top zappers",
"x82IOl": "Mute",
"y867Vs": "Volume",
"yzKwBQ": "eg. nsec1xyz",
"zVDHAu": "Zap Alert"
}