90 lines
3.1 KiB
TypeScript
90 lines
3.1 KiB
TypeScript
export default function handleArticleReader() {
|
|
const button = document.getElementById('speak-btn');
|
|
const article = document.querySelector('.article-content');
|
|
|
|
// Contrôles de paramètres (optionnels)
|
|
const rateControl = document.getElementById('speech-rate') as HTMLInputElement;
|
|
const pitchControl = document.getElementById('speech-pitch') as HTMLInputElement;
|
|
const volumeControl = document.getElementById('speech-volume') as HTMLInputElement;
|
|
const voiceSelect = document.getElementById('speech-voice') as HTMLSelectElement;
|
|
|
|
let utterance: SpeechSynthesisUtterance;
|
|
let voices: SpeechSynthesisVoice[] = [];
|
|
|
|
// Charger les voix disponibles
|
|
function loadVoices() {
|
|
voices = speechSynthesis.getVoices();
|
|
if (voiceSelect && voices.length > 0) {
|
|
voiceSelect.innerHTML = '';
|
|
voices
|
|
.filter((voice) => voice.lang.startsWith('fr')) // Filtrer les voix françaises
|
|
.forEach((voice, index) => {
|
|
const option = document.createElement('option');
|
|
option.value = index.toString();
|
|
option.textContent = `${voice.name} (${voice.lang})`;
|
|
voiceSelect.appendChild(option);
|
|
});
|
|
}
|
|
}
|
|
|
|
// Charger les voix au démarrage et quand elles changent
|
|
loadVoices();
|
|
speechSynthesis.onvoiceschanged = loadVoices;
|
|
|
|
// Configuration par défaut
|
|
const defaultSettings = {
|
|
rate: 0.9, // Vitesse (0.1 à 10)
|
|
pitch: 1, // Tonalité (0 à 2)
|
|
volume: 1, // Volume (0 à 1)
|
|
voice: null, // Voix (null = voix par défaut)
|
|
};
|
|
|
|
function createUtterance(text: string): SpeechSynthesisUtterance {
|
|
utterance = new SpeechSynthesisUtterance(text);
|
|
utterance.lang = 'fr-FR';
|
|
|
|
// Appliquer les paramètres depuis les contrôles ou les valeurs par défaut
|
|
utterance.rate = rateControl ? parseFloat(rateControl.value) : defaultSettings.rate;
|
|
utterance.pitch = pitchControl ? parseFloat(pitchControl.value) : defaultSettings.pitch;
|
|
utterance.volume = volumeControl ? parseFloat(volumeControl.value) : defaultSettings.volume;
|
|
|
|
// Sélectionner la voix
|
|
if (voiceSelect && voices.length > 0) {
|
|
const selectedVoiceIndex = parseInt(voiceSelect.value);
|
|
const frenchVoices = voices.filter((voice) => voice.lang.startsWith('fr'));
|
|
if (frenchVoices[selectedVoiceIndex]) {
|
|
utterance.voice = frenchVoices[selectedVoiceIndex];
|
|
}
|
|
}
|
|
|
|
utterance.onend = () => {
|
|
button.textContent = '🔊 Lire en vocal';
|
|
};
|
|
|
|
utterance.onerror = (event) => {
|
|
console.error('Erreur lors de la lecture:', event);
|
|
button.textContent = '🔊 Lire en vocal';
|
|
};
|
|
|
|
return utterance;
|
|
}
|
|
|
|
if (button) {
|
|
button.addEventListener('click', () => {
|
|
if (speechSynthesis.speaking) {
|
|
speechSynthesis.cancel();
|
|
button.textContent = '🔊 Lire en vocal';
|
|
} else {
|
|
if (article) {
|
|
const text = article.innerText.trim();
|
|
if (text) {
|
|
createUtterance(text);
|
|
speechSynthesis.speak(utterance);
|
|
button.textContent = '⏹️ Arrêter la lecture';
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}
|