{"id":17187,"date":"2025-12-01T15:33:46","date_gmt":"2025-12-01T13:33:46","guid":{"rendered":"https:\/\/www.beseit.net\/?p=17187"},"modified":"2025-12-01T15:33:46","modified_gmt":"2025-12-01T13:33:46","slug":"funcio-tts-dels-navegadors-speechsynthesis","status":"publish","type":"post","link":"https:\/\/www.beseit.net\/?p=17187","title":{"rendered":"Funci\u00f3 TTS dels navegadors: SpeechSynthesis"},"content":{"rendered":"\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;?php\n\n\/\/ ? ? ? CANVI 1: Mapeig de codis curts ('cat', 'eng', etc.) a codis d'idioma v\u00e0lids\nsession_start();\n\n\/\/ Mapeig de codis curts a codis d'idioma v\u00e0lids per a l'\u00e0udio\n\/\/ Mapeig de codis curts a codis d'idioma v\u00e0lids per a l'\u00e0udio\n$langMap = [\n    'cat' => 'ca-ES', \/\/ Catal\u00e0 (Espanya)\n    'eus' => 'eu-ES', \/\/ Euskera \/ Basc (Espanya)\n    'cas' => 'es-ES', \/\/ Castell\u00e0 \/ Espanyol (Espanya)\n    'eng' => 'en-US', \/\/ Angl\u00e8s (Estats Units)\n    'fra' => 'fr-FR', \/\/ Franc\u00e8s (Fran\u00e7a)\n    'ger' => 'de-DE', \/\/ Alemany (Alemanya)\n    'por' => 'pt-PT', \/\/ Portugu\u00e8s (Portugal)\n    'ita' => 'it-IT'  \/\/ Itali\u00e0 (It\u00e0lia)\n];\n\n\/\/ Comprovem si $_SESSION['lang'] est\u00e0 definit i \u00e9s v\u00e0lid\n$shortLang = $_SESSION['lang'] ; \/\/ Assigna 'cat' si $_SESSION['lang'] no est\u00e0 definit\n\n\/\/ Assignem el codi d'\u00e0udio corresponent\n$_SESSION['lang_audio'] = $langMap[$shortLang] ?? 'es-ES'; \/\/ Assegura que sigui 'ca-ES' si el codi no es troba al mapeig\n\n\/\/ Mostrem el resultat\n\/\/echo \"&lt;br>SESSION['lang_audio']: \" . $_SESSION['lang_audio'];\n\n\/\/ ? ? ? fi CANVI\n?>\n&lt;?php \n\/\/echo $_SESSION['resposta']; \/\/prova per veure que entra b\u00e9\n   \/\/ exit ('31');\n?>\n &lt;form id=\"cercaForm\" method=\"POST\" action=\"BD_conexions\/conexio_diccionari_bd.php\">\n \n             &lt;div class=\"search-container\">\n                &lt;!-- Camp de cerca -->\n                &lt;input \n            type=\"text\" \n            id=\"cercar\" \n            name=\"cercar\" \n            onkeyup=\"\" \n            placeholder=\"cercar..\" \n            autofocus \n            value=\"&lt;?php echo isset($_SESSION['cercar']) ? htmlspecialchars($_SESSION['cercar'], \n                    ENT_QUOTES, 'UTF-8') : ''; ?>\"\n                    >\n                &lt;!-- Bot\u00f3 de cerca -->\n                &lt;button type=\"submit\">Cercar\/Confirmar&lt;\/button>\n                &lt;button id=\"speakButton\" title=\"Llegir en veu alta\">\n                &lt;span>?&lt;\/span> \n                &lt;\/button>\n            &lt;\/div> \n    &lt;div>\n  \n    &lt;p>\n    &lt;input type=\"button\" value=\"&lt;?php echo '-num-'.  $_SESSION['num'].'--'; ?>\" style=\"display:none;\">\n    &lt;input type=\"button\" value=\"&lt;?php echo '-id-'.  $_SESSION['id'].'--'; ?>\" style=\"display:none;\">\n    &lt;input type=\"button\" value=\"&lt;?php echo '-retorn-'. $_SESSION['nom'].'--'; ?>\" style=\"display:none;\">\n    &lt;input type=\"button\" value=\"&lt;?php echo '--'.  $_SESSION['lang_r'].'--'; ?>\" style=\"display:none;\">\n    &lt;input type=\"button\" value=\"&lt;?php echo '-1-'. $_SESSION['diccionari'].'--'; ?>\" style=\"display:none;\">\n    &lt;input type=\"button\" value=\"&lt;?php echo '-2-'. $_SESSION['diccionari_r'].'--'; ?>\" style=\"display:none;\">\n    &lt;input type=\"button\" value=\"&lt;?php echo '-3-'. $_SESSION['dic'].'--'; ?>\" style=\"display:none;\">\n    &lt;input type=\"button\" value=\"&lt;?php echo '--'. $_SESSION['bd']; ?>\" style=\"display:none;\">\n    &lt;input type=\"button\" value=\"&lt;?php echo '--'. $_SESSION['bd_r']; ?>\" style=\"display:none;\">\n    &lt;input\n        type=\"text\" \n        id=\"dicionari_A\"\n        name=\"dicionari_AJ\" \n        onkeyup=\"\" \n        placeholder=&lt;?php echo htmlspecialchars($_SESSION['diccionari']); ?>\n        autofocus\n        data-diccionari=&lt;?php echo htmlspecialchars($_SESSION['diccionari']); ?>\n        style=\"display:none;\">\n&lt;\/p>\n&lt;script>\n        \/\/ Capturar elements del DOM\n        const entrada = document.getElementById('cercar'); \/\/ Primer camp de text\n        const boto = document.getElementById('boto');       \/\/ Bot\u00f3\n        const sortida = document.getElementById('replicar'); \/\/ Segon camp de text\n\n        \/\/ Afegir un event listener al bot\u00f3\n        boto.addEventListener('click', function() {\n            \/\/ Obtenir el valor de la primera entrada\n            const text = entrada.value;\n\n            \/\/ Assignar el valor a la segona entrada\n            sortida.value = text;\n        });\n        \n    &lt;\/script>\n\n\n\n&lt;script>\n  \n  document.addEventListener('DOMContentLoaded', () => {\n    const inputElement = document.getElementById('cercar');\n    const speakBtn = document.getElementById('speakButton');\n    let voices = [];\n\n    \/\/ ? Carreguem l'idioma des de PHP\n    const userLang = '&lt;?php echo addslashes($_SESSION[\"lang_audio\"]); ?>';\n\n    function loadVoices() {\n      voices = speechSynthesis.getVoices();\n    }\n\n    speechSynthesis.onvoiceschanged = loadVoices;\n    loadVoices();\n\n    function speakText() {\n      const text = inputElement.value.trim();\n      if (!text) return;\n\n      const utterance = new SpeechSynthesisUtterance(text);\n\n      \/\/ ? Busquem una veu que suporti l'idioma de la sessi\u00f3 (ex: 'ca-ES')\n      let selectedVoice = voices.find(v => v.lang === userLang);\n\n      \/\/ Si no n'hi ha d'exacta, provem amb el codi base (ex: 'ca')\n      if (!selectedVoice) {\n        const baseLang = userLang.split('-')[0];\n        selectedVoice = voices.find(v => v.lang.startsWith(baseLang));\n      }\n\n      \/\/ Assignem la veu trobada (o nom\u00e9s l'idioma si no hi ha veu espec\u00edfica)\n      if (selectedVoice) {\n        utterance.voice = selectedVoice;\n        utterance.lang = selectedVoice.lang;\n      } else {\n        utterance.lang = userLang; \/\/ el navegador triar\u00e0 una veu\n      }\n\n      utterance.rate = 1;\n      utterance.pitch = 1;\n\n      speechSynthesis.cancel();\n      speechSynthesis.speak(utterance);\n    }\n\n    speakBtn.addEventListener('click', (e) => {\n      e.preventDefault();\n      speakText();\n    });\n  });\n\n&lt;\/script>\n\n\n    &lt;\/div>\n             &lt;!-- Contenidor de l'autocompletat -->\n             &lt;div id=\"resultats_autocompletar_container\">\n                &lt;ul id=\"resultats_autocompletar\">\n                    &lt;!-- Resultats din\u00e0mics via JavaScript -->\n                &lt;\/ul>\n            &lt;\/div>\n            \n\n\n        &lt;\/form>\n    <\/pre>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-17187","post","type-post","status-publish","format-standard","hentry","category-bloc-de-notes"],"_links":{"self":[{"href":"https:\/\/www.beseit.net\/index.php?rest_route=\/wp\/v2\/posts\/17187","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.beseit.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.beseit.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.beseit.net\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.beseit.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=17187"}],"version-history":[{"count":1,"href":"https:\/\/www.beseit.net\/index.php?rest_route=\/wp\/v2\/posts\/17187\/revisions"}],"predecessor-version":[{"id":17188,"href":"https:\/\/www.beseit.net\/index.php?rest_route=\/wp\/v2\/posts\/17187\/revisions\/17188"}],"wp:attachment":[{"href":"https:\/\/www.beseit.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=17187"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.beseit.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=17187"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.beseit.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=17187"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}