{"id":17173,"date":"2025-11-24T20:38:03","date_gmt":"2025-11-24T18:38:03","guid":{"rendered":"https:\/\/www.beseit.net\/?p=17173"},"modified":"2026-09-11T13:00:53","modified_gmt":"2026-09-11T11:00:53","slug":"simple-text-a-veur","status":"publish","type":"post","link":"https:\/\/www.beseit.net\/?p=17173","title":{"rendered":"<span>\u2b50\u2b50<\/span>Simple text a veu"},"content":{"rendered":"<p><!DOCTYPE html><br \/>\n<html lang=\"ca\"><br \/>\n<head><br \/>\n  <meta charset=\"UTF-8\"><br \/>\n  <title>Conversor de text a veu<\/title><\/p>\n<style>\n    body {<br \/>\n      font-family: sans-serif;<br \/>\n      padding: 2em;<br \/>\n      background-color: #f4f4f4;<br \/>\n    }<br \/>\n    input {<br \/>\n      font-size: 1.2em;<br \/>\n      padding: 0.5em;<br \/>\n      margin-top: 1em;<br \/>\n      width: 100%;<br \/>\n      max-width: 500px;<br \/>\n    }<br \/>\n    #speakBtn {<br \/>\n      font-size: 2em;<br \/>\n      background: none;<br \/>\n      border: none;<br \/>\n      cursor: pointer;<br \/>\n      margin-top: 1em;<br \/>\n    }<br \/>\n    #speakBtn:hover {<br \/>\n      color: #0078D7;<br \/>\n    }<br \/>\n  <\/style>\n<p><\/head><br \/>\n<body><\/p>\n<h2> Conversor de text a veu<\/h2>\n<p>  <input type=\"text\" id=\"cercar\" placeholder=\"Escriu el text que vols escoltar\"><br \/>\n  <button id=\"speakBtn\" title=\"Escolta el text\"><\/button><\/p>\n<p>  <script><br \/>\n    document.addEventListener('DOMContentLoaded', () => {<br \/>\n      const inputElement = document.getElementById('cercar');<br \/>\n      const speakBtn = document.getElementById('speakBtn');<br \/>\n      let voices = [];<\/p>\n<p>      function loadVoices() {<br \/>\n        voices = speechSynthesis.getVoices();<br \/>\n      }<\/p>\n<p>      speechSynthesis.onvoiceschanged = loadVoices;<br \/>\n      loadVoices();<\/p>\n<p>      function speakText() {<br \/>\n        const text = inputElement.value.trim();<br \/>\n        if (!text) return;<\/p>\n<p>        const utterance = new SpeechSynthesisUtterance(text);<br \/>\n        const zira = voices.find(v => v.name === 'Microsoft Zira - English (United States)');<\/p>\n<p>        if (zira) {<br \/>\n          utterance.voice = zira;<br \/>\n          utterance.lang = zira.lang;<br \/>\n        }<\/p>\n<p>        utterance.rate = 1;<br \/>\n        utterance.pitch = 1;<\/p>\n<p>        speechSynthesis.cancel();<br \/>\n        speechSynthesis.speak(utterance);<br \/>\n      }<\/p>\n<p>      speakBtn.addEventListener('click', speakText);<\/p>\n<p>      \/\/  Repetir cada 10 segons<br \/>\n      setInterval(speakText, 10000);<br \/>\n    });<br \/>\n  <\/script><br \/>\n<\/body><br \/>\n<\/html><br \/>\n<!-- wp:enlighter\/codeblock mut--><\/p>\n\n\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;!DOCTYPE html>\n&lt;html lang=\"ca\">\n&lt;head>\n  &lt;meta charset=\"UTF-8\">\n  &lt;title>Conversor de text a veu&lt;\/title>\n  &lt;style>\n    body {\n      font-family: sans-serif;\n      padding: 2em;\n      background-color: #f4f4f4;\n    }\n    input {\n      font-size: 1.2em;\n      padding: 0.5em;\n      margin-top: 1em;\n      width: 100%;\n      max-width: 500px;\n    }\n    #speakBtn {\n      font-size: 2em;\n      background: none;\n      border: none;\n      cursor: pointer;\n      margin-top: 1em;\n    }\n    #speakBtn:hover {\n      color: #0078D7;\n    }\n  &lt;\/style>\n&lt;\/head>\n&lt;body>\n  &lt;h2>Conversor de text a veu&lt;\/h2>\n  &lt;input type=\"text\" id=\"cercar\" placeholder=\"Escriu el text que vols escoltar\">\n  &lt;button id=\"speakBtn\" title=\"Escolta el text\">&lt;\/button>\n\n  &lt;script>\n    document.addEventListener('DOMContentLoaded', () => {\n      const inputElement = document.getElementById('cercar');\n      const speakBtn = document.getElementById('speakBtn');\n      let voices = [];\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        const zira = voices.find(v => v.name === 'Microsoft Zira - English (United States)');\n\n        if (zira) {\n          utterance.voice = zira;\n          utterance.lang = zira.lang;\n        }\n\n        utterance.rate = 1;\n        utterance.pitch = 1;\n\n        speechSynthesis.cancel();\n        speechSynthesis.speak(utterance);\n      }\n\n      speakBtn.addEventListener('click', speakText);\n\n      \/\/ Repetir cada 10 segons\n      setInterval(speakText, 10000);\n    });\n  &lt;\/script>\n&lt;\/body>\n&lt;\/html>\n<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\"><mark style=\"background-color:rgba(0, 0, 0, 0);color:#eb0505\" class=\"has-inline-color\">Aquest script, mosta les veus que admet el navegador<\/mark><\/h2>\n\n\n\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=\"\">```html\n&lt;!DOCTYPE html>\n&lt;html lang=\"ca\">\n&lt;head>\n  &lt;meta charset=\"UTF-8\">\n  &lt;title>Conversor de text a veu&lt;\/title>\n\n  &lt;style>\n    body {\n      font-family: sans-serif;\n      padding: 2em;\n      background-color: #f4f4f4;\n    }\n\n    input {\n      font-size: 1.2em;\n      padding: 0.5em;\n      margin-top: 1em;\n      width: 100%;\n      max-width: 500px;\n      box-sizing: border-box;\n    }\n\n    select {\n      font-size: 1.1em;\n      padding: 0.5em;\n      margin-top: 1em;\n      width: 100%;\n      max-width: 500px;\n    }\n\n    #languageInfo {\n      margin-top: 1em;\n      padding: 0.7em;\n      background: white;\n      border: 1px solid #ccc;\n      border-radius: 6px;\n      max-width: 500px;\n    }\n\n    #speakBtn {\n      font-size: 2em;\n      background: none;\n      border: none;\n      cursor: pointer;\n      margin-top: 1em;\n    }\n\n    #speakBtn:hover {\n      color: #0078D7;\n    }\n\n    #status {\n      margin-top: 0.8em;\n      font-size: 0.95em;\n      color: #555;\n    }\n  &lt;\/style>\n&lt;\/head>\n\n&lt;body>\n\n  &lt;h2>Conversor de text a veu&lt;\/h2>\n\n  &lt;input\n    type=\"text\"\n    id=\"cercar\"\n    placeholder=\"Escriu el text que vols escoltar\"\n  >\n\n  &lt;br>\n\n  &lt;select id=\"voiceSelect\">\n    &lt;option value=\"\">Carregant veus...&lt;\/option>\n  &lt;\/select>\n\n  &lt;div id=\"languageInfo\">\n    &lt;strong>Llengua carregada:&lt;\/strong>\n    &lt;span id=\"currentLanguage\">--&lt;\/span>\n  &lt;\/div>\n\n  &lt;div id=\"status\">&lt;\/div>\n\n  &lt;button id=\"speakBtn\" title=\"Escolta el text\">\ud83d\udd0a&lt;\/button>\n\n\n  &lt;script>\n\n    document.addEventListener('DOMContentLoaded', () => {\n\n      const inputElement = document.getElementById('cercar');\n      const speakBtn = document.getElementById('speakBtn');\n      const voiceSelect = document.getElementById('voiceSelect');\n      const currentLanguage = document.getElementById('currentLanguage');\n      const status = document.getElementById('status');\n\n      let voices = [];\n\n\n      \/*\n       * Carrega totes les veus que Firefox posa a disposici\u00f3\n       *\/\n      function loadVoices() {\n\n        voices = speechSynthesis.getVoices();\n\n        console.log(\"Veus disponibles:\", voices);\n\n        voiceSelect.innerHTML = '';\n\n        if (voices.length === 0) {\n\n          const option = document.createElement('option');\n          option.textContent = 'No s\u2019han trobat veus';\n          voiceSelect.appendChild(option);\n\n          currentLanguage.textContent = 'Cap veu disponible';\n\n          return;\n        }\n\n\n        \/*\n         * Ordenem per llengua i despr\u00e9s per nom\n         *\/\n        voices.sort((a, b) => {\n\n          if (a.lang !== b.lang) {\n            return a.lang.localeCompare(b.lang);\n          }\n\n          return a.name.localeCompare(b.name);\n\n        });\n\n\n        \/*\n         * Afegim totes les veus al desplegable\n         *\/\n        voices.forEach((voice, index) => {\n\n          const option = document.createElement('option');\n\n          option.value = index;\n\n          option.textContent =\n            `${voice.lang} \u2014 ${voice.name}`;\n\n          voiceSelect.appendChild(option);\n\n        });\n\n\n        \/*\n         * Busquem primer una veu catalana\n         *\n         * ca\n         * ca-ES\n         * ca-ES-...\n         *\/\n        let catalanIndex = voices.findIndex(voice =>\n          voice.lang.toLowerCase() === 'ca' ||\n          voice.lang.toLowerCase().startsWith('ca-')\n        );\n\n\n        \/*\n         * Si existeix catal\u00e0, el seleccionem\n         *\/\n        if (catalanIndex !== -1) {\n\n          voiceSelect.value = catalanIndex;\n\n          updateLanguage(catalanIndex);\n\n          status.textContent =\n            '\u2713 S\u2019ha detectat una veu catalana.';\n\n        } else {\n\n          \/*\n           * Si no hi ha catal\u00e0, agafem la primera veu\n           *\/\n          voiceSelect.value = 0;\n\n          updateLanguage(0);\n\n          status.textContent =\n            '\u26a0 Firefox no ha detectat cap veu catalana.';\n\n        }\n\n      }\n\n\n      \/*\n       * Actualitza el bot\u00f3\/informaci\u00f3 de llengua\n       *\/\n      function updateLanguage(index) {\n\n        const voice = voices[index];\n\n        if (!voice) {\n          currentLanguage.textContent = '--';\n          return;\n        }\n\n        currentLanguage.textContent =\n          `${voice.lang} \u2014 ${voice.name}`;\n\n      }\n\n\n      \/*\n       * Quan l'usuari canvia la veu\n       *\/\n      voiceSelect.addEventListener('change', () => {\n\n        updateLanguage(voiceSelect.value);\n\n      });\n\n\n      \/*\n       * Parla el text\n       *\/\n      function speakText() {\n\n        const text = inputElement.value.trim();\n\n        if (!text) return;\n\n        const selectedIndex = parseInt(voiceSelect.value);\n\n        const voice = voices[selectedIndex];\n\n        if (!voice) {\n\n          status.textContent =\n            'No hi ha cap veu seleccionada.';\n\n          return;\n\n        }\n\n\n        const utterance =\n          new SpeechSynthesisUtterance(text);\n\n\n        \/*\n         * Utilitzem EXACTAMENT la veu seleccionada\n         *\/\n        utterance.voice = voice;\n\n        utterance.lang = voice.lang;\n\n        utterance.rate = 1;\n\n        utterance.pitch = 1;\n\n\n        speechSynthesis.cancel();\n\n        speechSynthesis.speak(utterance);\n\n\n        \/*\n         * Mostrem qu\u00e8 est\u00e0 parlant realment\n         *\/\n        currentLanguage.textContent =\n          `${voice.lang} \u2014 ${voice.name}`;\n\n      }\n\n\n      \/*\n       * Bot\u00f3 de reproducci\u00f3\n       *\/\n      speakBtn.addEventListener('click', speakText);\n\n\n      \/*\n       * Les veus poden arribar de manera as\u00edncrona\n       * a Firefox.\n       *\/\n      speechSynthesis.onvoiceschanged = loadVoices;\n\n      loadVoices();\n\n\n      \/*\n       * Repetir cada 10 segons\n       *\/\n      setInterval(speakText, 10000);\n\n    });\n\n  &lt;\/script>\n\n&lt;\/body>\n&lt;\/html>\n```\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">S\u00ed. El problema principal del teu codi \u00e9s que <strong>forces Microsoft Zira en angl\u00e8s<\/strong>, aix\u00ed que Firefox no t\u00e9 cap possibilitat d\u2019escollir catal\u00e0.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Et proposo aquesta versi\u00f3:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>mostra en un bot\u00f3 <strong>quina veu\/llengua est\u00e0 carregada<\/strong>;<\/li>\n\n\n\n<li>afegeix un <strong>desplegable amb totes les veus que Firefox detecti<\/strong>;<\/li>\n\n\n\n<li>permet seleccionar manualment la veu;<\/li>\n\n\n\n<li>indica si <strong>Catal\u00e0 (<code>ca<\/code>)<\/strong> est\u00e0 disponible;<\/li>\n\n\n\n<li>si hi ha una veu catalana, la selecciona autom\u00e0ticament;<\/li>\n\n\n\n<li>mant\u00e9 la reproducci\u00f3 cada 10 segons.<\/li>\n<\/ul>\n\n\n\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;!DOCTYPE html>\n&lt;html lang=\"ca\">\n&lt;head>\n  &lt;meta charset=\"UTF-8\">\n  &lt;title>Conversor de text a veu&lt;\/title>\n\n  &lt;style>\n    body {\n      font-family: sans-serif;\n      padding: 2em;\n      background-color: #f4f4f4;\n    }\n\n    input {\n      font-size: 1.2em;\n      padding: 0.5em;\n      margin-top: 1em;\n      width: 100%;\n      max-width: 500px;\n      box-sizing: border-box;\n    }\n\n    select {\n      font-size: 1.1em;\n      padding: 0.5em;\n      margin-top: 1em;\n      width: 100%;\n      max-width: 500px;\n    }\n\n    #languageInfo {\n      margin-top: 1em;\n      padding: 0.7em;\n      background: white;\n      border: 1px solid #ccc;\n      border-radius: 6px;\n      max-width: 500px;\n    }\n\n    #speakBtn {\n      font-size: 2em;\n      background: none;\n      border: none;\n      cursor: pointer;\n      margin-top: 1em;\n    }\n\n    #speakBtn:hover {\n      color: #0078D7;\n    }\n\n    #status {\n      margin-top: 0.8em;\n      font-size: 0.95em;\n      color: #555;\n    }\n  &lt;\/style>\n&lt;\/head>\n\n&lt;body>\n\n  &lt;h2>Conversor de text a veu&lt;\/h2>\n\n  &lt;input\n    type=\"text\"\n    id=\"cercar\"\n    placeholder=\"Escriu el text que vols escoltar\"\n  >\n\n  &lt;br>\n\n  &lt;select id=\"voiceSelect\">\n    &lt;option value=\"\">Carregant veus...&lt;\/option>\n  &lt;\/select>\n\n  &lt;div id=\"languageInfo\">\n    &lt;strong>Llengua carregada:&lt;\/strong>\n    &lt;span id=\"currentLanguage\">--&lt;\/span>\n  &lt;\/div>\n\n  &lt;div id=\"status\">&lt;\/div>\n\n  &lt;button id=\"speakBtn\" title=\"Escolta el text\">\ud83d\udd0a&lt;\/button>\n\n\n  &lt;script>\n\n    document.addEventListener('DOMContentLoaded', () => {\n\n      const inputElement = document.getElementById('cercar');\n      const speakBtn = document.getElementById('speakBtn');\n      const voiceSelect = document.getElementById('voiceSelect');\n      const currentLanguage = document.getElementById('currentLanguage');\n      const status = document.getElementById('status');\n\n      let voices = [];\n\n\n      \/*\n       * Carrega totes les veus que Firefox posa a disposici\u00f3\n       *\/\n      function loadVoices() {\n\n        voices = speechSynthesis.getVoices();\n\n        console.log(\"Veus disponibles:\", voices);\n\n        voiceSelect.innerHTML = '';\n\n        if (voices.length === 0) {\n\n          const option = document.createElement('option');\n          option.textContent = 'No s\u2019han trobat veus';\n          voiceSelect.appendChild(option);\n\n          currentLanguage.textContent = 'Cap veu disponible';\n\n          return;\n        }\n\n\n        \/*\n         * Ordenem per llengua i despr\u00e9s per nom\n         *\/\n        voices.sort((a, b) => {\n\n          if (a.lang !== b.lang) {\n            return a.lang.localeCompare(b.lang);\n          }\n\n          return a.name.localeCompare(b.name);\n\n        });\n\n\n        \/*\n         * Afegim totes les veus al desplegable\n         *\/\n        voices.forEach((voice, index) => {\n\n          const option = document.createElement('option');\n\n          option.value = index;\n\n          option.textContent =\n            `${voice.lang} \u2014 ${voice.name}`;\n\n          voiceSelect.appendChild(option);\n\n        });\n\n\n        \/*\n         * Busquem primer una veu catalana\n         *\n         * ca\n         * ca-ES\n         * ca-ES-...\n         *\/\n        let catalanIndex = voices.findIndex(voice =>\n          voice.lang.toLowerCase() === 'ca' ||\n          voice.lang.toLowerCase().startsWith('ca-')\n        );\n\n\n        \/*\n         * Si existeix catal\u00e0, el seleccionem\n         *\/\n        if (catalanIndex !== -1) {\n\n          voiceSelect.value = catalanIndex;\n\n          updateLanguage(catalanIndex);\n\n          status.textContent =\n            '\u2713 S\u2019ha detectat una veu catalana.';\n\n        } else {\n\n          \/*\n           * Si no hi ha catal\u00e0, agafem la primera veu\n           *\/\n          voiceSelect.value = 0;\n\n          updateLanguage(0);\n\n          status.textContent =\n            '\u26a0 Firefox no ha detectat cap veu catalana.';\n\n        }\n\n      }\n\n\n      \/*\n       * Actualitza el bot\u00f3\/informaci\u00f3 de llengua\n       *\/\n      function updateLanguage(index) {\n\n        const voice = voices[index];\n\n        if (!voice) {\n          currentLanguage.textContent = '--';\n          return;\n        }\n\n        currentLanguage.textContent =\n          `${voice.lang} \u2014 ${voice.name}`;\n\n      }\n\n\n      \/*\n       * Quan l'usuari canvia la veu\n       *\/\n      voiceSelect.addEventListener('change', () => {\n\n        updateLanguage(voiceSelect.value);\n\n      });\n\n\n      \/*\n       * Parla el text\n       *\/\n      function speakText() {\n\n        const text = inputElement.value.trim();\n\n        if (!text) return;\n\n        const selectedIndex = parseInt(voiceSelect.value);\n\n        const voice = voices[selectedIndex];\n\n        if (!voice) {\n\n          status.textContent =\n            'No hi ha cap veu seleccionada.';\n\n          return;\n\n        }\n\n\n        const utterance =\n          new SpeechSynthesisUtterance(text);\n\n\n        \/*\n         * Utilitzem EXACTAMENT la veu seleccionada\n         *\/\n        utterance.voice = voice;\n\n        utterance.lang = voice.lang;\n\n        utterance.rate = 1;\n\n        utterance.pitch = 1;\n\n\n        speechSynthesis.cancel();\n\n        speechSynthesis.speak(utterance);\n\n\n        \/*\n         * Mostrem qu\u00e8 est\u00e0 parlant realment\n         *\/\n        currentLanguage.textContent =\n          `${voice.lang} \u2014 ${voice.name}`;\n\n      }\n\n\n      \/*\n       * Bot\u00f3 de reproducci\u00f3\n       *\/\n      speakBtn.addEventListener('click', speakText);\n\n\n      \/*\n       * Les veus poden arribar de manera as\u00edncrona\n       * a Firefox.\n       *\/\n      speechSynthesis.onvoiceschanged = loadVoices;\n\n      loadVoices();\n\n\n      \/*\n       * Repetir cada 10 segons\n       *\/\n      setInterval(speakText, 10000);\n\n    });\n\n  &lt;\/script>\n\n&lt;\/body>\n&lt;\/html><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Qu\u00e8 veurem ara<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">El desplegable et mostrar\u00e0 coses semblants a:<\/p>\n\n\n\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=\"\">ca-ES \u2014 Veu catalana\nde-DE \u2014 German ...\nen-US \u2014 Microsoft Zira ...\nen-US \u2014 ...\nes-ES \u2014 Spanish ...\nfr-FR \u2014 French ...<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">I a sota:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Llengua carregada: <code>ca-ES \u2014 NOM_DE_LA_VEU<\/code><\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Aix\u00f2 \u00e9s especialment \u00fatil per al que estem investigant amb <strong>Firefox + Speech Dispatcher + Piper\/Ona<\/strong>, perqu\u00e8 podrem veure si Firefox <strong>realment rep una veu catalana<\/strong> o simplement no la t\u00e9 disponible.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Una cosa important: <strong>que Linux tingui una veu catalana instal\u00b7lada no vol dir necess\u00e0riament que Firefox la vegi a <code>speechSynthesis.getVoices()<\/code><\/strong>. Aquest \u00e9s precisament el test que faria amb aquesta p\u00e0gina.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Si vols, el seg\u00fcent pas pot ser fer que el desplegable mostri <strong>nom\u00e9s les lleng\u00fces<\/strong> (<code>Catal\u00e0<\/code>, <code>Espanyol<\/code>, <code>Angl\u00e8s<\/code>, etc.) i, en seleccionar-ne una, tri\u00ef autom\u00e0ticament la millor veu disponible.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p class=\"wp-block-paragraph\">S\u00ed. <strong>Ona \u00e9s un model de veu que es guarda com a fitxers<\/strong>, principalment:<\/p>\n\n\n\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=\"\">ca_ES-upc_ona-medium.onnx\nca_ES-upc_ona-medium.onnx.json<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">El <code>.onnx<\/code> \u00e9s el model neuronal de la veu i el <code>.json<\/code> cont\u00e9 la configuraci\u00f3\/metadades necess\u00e0ries. Piper funciona precisament amb aquesta parella de fitxers. (<a href=\"https:\/\/github.com\/rhasspy\/piper\/blob\/master\/VOICES.md?utm_source=chatgpt.com\">GitHub<\/a>)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I <strong>s\u00ed, hi ha veus Piper per a molts idiomes<\/strong>. El repositori oficial de veus actual indica <strong>35 idiomes<\/strong>, i inclou catal\u00e0, castell\u00e0, angl\u00e8s, franc\u00e8s, alemany, itali\u00e0, portugu\u00e8s, neerland\u00e8s, rus, xin\u00e8s, japon\u00e8s? etc.; per\u00f2 <strong>no tots els idiomes del m\u00f3n tenen una veu Piper disponible<\/strong>. (<a href=\"https:\/\/huggingface.co\/rhasspy\/piper-voices?utm_source=chatgpt.com\">Hugging Face<\/a>)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Per exemple, actualment tenim:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Llengua<\/th><th>Veus Piper<\/th><\/tr><\/thead><tbody><tr><td>\ud83c\udde8\ud83c\udde6 Catal\u00e0<\/td><td><code>upc_ona<\/code>, <code>upc_pau<\/code><\/td><\/tr><tr><td>\ud83c\uddea\ud83c\uddf8 Castell\u00e0<\/td><td><code>carlfm<\/code>, <code>davefx<\/code>, <code>mls<\/code>, <code>sharvard<\/code>&#8230;<\/td><\/tr><tr><td>\ud83c\uddec\ud83c\udde7 Angl\u00e8s UK<\/td><td><code>alan<\/code>, <code>alba<\/code>, <code>cori<\/code>&#8230;<\/td><\/tr><tr><td>\ud83c\uddfa\ud83c\uddf8 Angl\u00e8s US<\/td><td><code>amy<\/code>, <code>lessac<\/code>, <code>ryan<\/code>, <code>sam<\/code>&#8230;<\/td><\/tr><tr><td>\ud83c\uddeb\ud83c\uddf7 Franc\u00e8s<\/td><td><code>gilles<\/code>, <code>siwis<\/code>, <code>tom<\/code>, <code>upmc<\/code>&#8230;<\/td><\/tr><tr><td>\ud83c\udde9\ud83c\uddea Alemany<\/td><td><code>thorsten<\/code>, <code>karlsson<\/code>, <code>ramona<\/code>&#8230;<\/td><\/tr><tr><td>\ud83c\uddee\ud83c\uddf9 Itali\u00e0<\/td><td><code>paola<\/code>, <code>riccardo<\/code><\/td><\/tr><tr><td>\ud83c\uddf5\ud83c\uddf9 Portugu\u00e8s<\/td><td><code>tug\u00e3o<\/code>, <code>cadu<\/code>, <code>edresson<\/code>&#8230;<\/td><\/tr><tr><td>\ud83c\uddf3\ud83c\uddf1 Neerland\u00e8s<\/td><td>diverses<\/td><\/tr><tr><td>\ud83c\uddf7\ud83c\uddfa Rus<\/td><td><code>denis<\/code>, <code>dmitri<\/code>, <code>irina<\/code>, <code>ruslan<\/code><\/td><\/tr><tr><td>\ud83c\udde8\ud83c\uddf3 Xin\u00e8s<\/td><td><code>huayan<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">La llista oficial mostra que <strong>Catal\u00e0 (<code>ca_ES<\/code>) est\u00e0 molt ben representat<\/strong>, amb <code>upc_ona<\/code> i <code>upc_pau<\/code>. (<a href=\"https:\/\/github.com\/rhasspy\/piper\/blob\/master\/VOICES.md?utm_source=chatgpt.com\">GitHub<\/a>)<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">I aix\u00f2 encaixa molt b\u00e9 amb el que est\u00e0vem parlant del Synology<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Podr\u00edem tenir, per exemple:<\/p>\n\n\n\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=\"\">\/volume2\/web\/00-sapi_tts\/\n       \u2502\n       \u251c\u2500\u2500 voices\/\n       \u2502     \u251c\u2500\u2500 ca_ES-upc_ona-medium.onnx\n       \u2502     \u251c\u2500\u2500 ca_ES-upc_ona-medium.onnx.json\n       \u2502     \u251c\u2500\u2500 es_ES-davefx-medium.onnx\n       \u2502     \u251c\u2500\u2500 es_ES-davefx-medium.onnx.json\n       \u2502     \u251c\u2500\u2500 en_US-ryan-medium.onnx\n       \u2502     \u251c\u2500\u2500 en_US-ryan-medium.onnx.json\n       \u2502     \u2514\u2500\u2500 ...\n       \u2502\n       \u2514\u2500\u2500 servidor TTS<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">I el nostre servidor podria tenir un men\u00fa:<\/p>\n\n\n\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=\"\">\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502 Veu:                        \u2502\n\u2502                             \u2502\n\u2502 \u25bc Catal\u00e0 \u2014 Ona              \u2502\n\u2502   Catal\u00e0 \u2014 Pau              \u2502\n\u2502   Castell\u00e0 \u2014 DaveFX         \u2502\n\u2502   Castell\u00e0 \u2014 Sharvard       \u2502\n\u2502   English US \u2014 Ryan         \u2502\n\u2502   English US \u2014 Amy          \u2502\n\u2502   Fran\u00e7ais \u2014 Tom            \u2502\n\u2502   Deutsch \u2014 Thorsten        \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Aquesta \u00e9s probablement la millor arquitectura per al teu TTS de la intranet.<\/strong> No depenem de les veus d&#8217;Edge\/Firefox ni d&#8217;Internet: els models <code>.onnx<\/code> queden al Synology i Piper el<p>S\u00ed. <strong>La difer\u00e8ncia que veus entre Windows 11 i Deepin\/Linux \u00e9s real<\/strong>, i en el teu cas explica perfectament el missatge:<\/p><blockquote><p>\u26a0\ufe0f Firefox no ha detectat cap veu catalana.<\/p><\/blockquote><h3>Windows 11<\/h3><p>A Windows, Firefox pot accedir a les veus TTS disponibles al sistema, com la que veus a la captura:<\/p><blockquote><p><code>Microsoft Zira Desktop - English (United States)<\/code><\/p><\/blockquote><p>Per aix\u00f2 el teu JavaScript <code>speechSynthesis.getVoices()<\/code> rep una llista de veus i el selector les pot mostrar.<\/p><h3>Deepin\/Linux<\/h3><p>Aqu\u00ed Firefox funciona d&#8217;una manera diferent. <strong>Firefox per a Linux no porta un conjunt propi de veus<\/strong>. La seva implementaci\u00f3 de Web Speech synthesis utilitza <strong>Speech Dispatcher<\/strong> com a intermediari del sistema. Mozilla ho documenta expl\u00edcitament. (<a title=\"1003464 - Text to Speech API on Firefox for Linux\" href=\"https:\/\/bugzilla.mozilla.org\/show_bug.cgi?id=1003464&amp;utm_source=chatgpt.com\">Bugzilla<\/a>)<\/p><p>El cam\u00ed \u00e9s aproximadament:<\/p><pre><code class=\"language-text\">Firefox<br>   \u2193<br>Web Speech API<br>   \u2193<br>Speech Dispatcher<br>   \u2193<br>m\u00f2dul TTS<br>   \u2193<br>veu<\/code><\/pre><p>I aqu\u00ed apareix el problema interessant que ja est\u00e0vem treballant:<\/p><pre><code class=\"language-text\">Firefox<br>   \u2193<br>Speech Dispatcher<br>   \u2193<br>Piper<br>   \u2193<br>Ona<\/code><\/pre><p><strong>Aquesta arquitectura \u00e9s perfectament possible<\/strong>, per\u00f2 Firefox no necess\u00e0riament veu autom\u00e0ticament totes les veus que tu tens instal\u00b7lades a Piper.<\/p><p>De fet, Mozilla t\u00e9 fins i tot una incid\u00e8ncia espec\u00edfica sobre aix\u00f2: <strong>Piper est\u00e0 instal\u00b7lat com a m\u00f2dul de Speech Dispatcher per\u00f2 Firefox no incorpora les veus Piper a <code>speechSynthesis.getVoices()<\/code><\/strong>. (<a title=\"1907786 - piper module and voices not added for Web Speech API\" href=\"https:\/\/bugzilla.mozilla.org\/show_bug.cgi?id=1907786&amp;utm_source=chatgpt.com\">Bugzilla<\/a>)<\/p><h3>I aix\u00f2 explica exactament el que hem estat fent<\/h3><p>Tu ja tens:<\/p><pre><code class=\"language-bash\">spd-say -L<\/code><\/pre><p>i hi apareixen <strong>centenars\/milers de veus<\/strong>.<\/p><p>Aix\u00f2 significa que:<\/p><p><strong>Speech Dispatcher s\u00ed que t\u00e9 veus.<\/strong><\/p><p>Per\u00f2 el teu navegador est\u00e0 dient:<\/p><pre><code class=\"language-text\">Firefox \u2192 speechSynthesis.getVoices()<br>                         \u2193<br>                       []<\/code><\/pre><p>Per tant, el problema <strong>no \u00e9s que Deepin no tingui veus<\/strong>.<\/p><p>\u00c9s que hi ha una difer\u00e8ncia entre:<\/p><pre><code class=\"language-text\">veus disponibles per al sistema<\/code><\/pre><p>i<\/p><pre><code class=\"language-text\">veus que Firefox Linux exposa a la Web Speech API<\/code><\/pre><p>Mozilla reconeix precisament aquesta fragilitat de la implementaci\u00f3 Linux. (<a title=\"1837789 - You can't use speech synthesis because voices aren't available in Speech Dispatcher\" href=\"https:\/\/bugzilla.mozilla.org\/show_bug.cgi?id=1837789&amp;utm_source=chatgpt.com\">Bugzilla<\/a>)<\/p><h3>Aix\u00f2 tamb\u00e9 explica una cosa molt important<\/h3><p>La nostra infraestructura:<\/p><pre><code class=\"language-text\">Firefox \u2192 Speech Dispatcher \u2192 Piper \u2192 Ona<\/code><\/pre><p><strong>s\u00ed que pot funcionar per fer parlar Firefox<\/strong>, per\u00f2 hem de superar la capa de detecci\u00f3 de veus de <code>speechSynthesis<\/code>.<\/p><p>Per aix\u00f2 jo faria ara una prova molt concreta al teu Deepin:<\/p><pre><code class=\"language-javascript\">speechSynthesis.getVoices().map(v => ({<br>    name: v.name,<br>    lang: v.lang,<br>    localService: v.localService<br>}))<\/code><\/pre><p>Si retorna <code>[]<\/code>, ja tenim confirmat que <strong>el problema est\u00e0 entre Firefox i Speech Dispatcher<\/strong>, no entre Piper i Ona.<\/p><p>I aix\u00f2 \u00e9s important perqu\u00e8 <strong>no cal abandonar Piper\/Ona ni tornar a eSpeak<\/strong>. Podem intentar fer que Firefox vegi expl\u00edcitament la veu que ja tens funcionant.<\/p><p><a href=\"https:\/\/bugzilla.mozilla.org\/show_bug.cgi?id=1907786&amp;utm_source=chatgpt.com\">Incid\u00e8ncia de Mozilla sobre Piper i Web Speech API<\/a><\/p>s utilitza localment.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I una cosa important: <strong>no cal instal\u00b7lar totes les veus<\/strong>. Podem comen\u00e7ar amb, per exemple, <strong>Ona + una veu castellana + angl\u00e8s + franc\u00e8s + alemany<\/strong>, i anar afegint-ne quan les necessitis.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p class=\"wp-block-paragraph\">S\u00ed. <strong>La difer\u00e8ncia que veus entre Windows 11 i Deepin\/Linux \u00e9s real<\/strong>, i en el teu cas explica perfectament el missatge:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\u26a0\ufe0f Firefox no ha detectat cap veu catalana.<\/p>\n<\/blockquote>\n\n\n\n<h3 class=\"wp-block-heading\">Windows 11<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">A Windows, Firefox pot accedir a les veus TTS disponibles al sistema, com la que veus a la captura:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\"><code>Microsoft Zira Desktop - English (United States)<\/code><\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">Per aix\u00f2 el teu JavaScript <code>speechSynthesis.getVoices()<\/code> rep una llista de veus i el selector les pot mostrar.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Deepin\/Linux<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Aqu\u00ed Firefox funciona d&#8217;una manera diferent. <strong>Firefox per a Linux no porta un conjunt propi de veus<\/strong>. La seva implementaci\u00f3 de Web Speech synthesis utilitza <strong>Speech Dispatcher<\/strong> com a intermediari del sistema. Mozilla ho documenta expl\u00edcitament.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">El cam\u00ed \u00e9s aproximadament:<\/p>\n\n\n\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=\"\">Firefox\n   \u2193\nWeb Speech API\n   \u2193\nSpeech Dispatcher\n   \u2193\nm\u00f2dul TTS\n   \u2193\nveu<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">I aqu\u00ed apareix el problema interessant que ja est\u00e0vem treballant:<\/p>\n\n\n\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=\"\">Firefox\n   \u2193\nSpeech Dispatcher\n   \u2193\nPiper\n   \u2193\nOna<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Aquesta arquitectura \u00e9s perfectament possible<\/strong>, per\u00f2 Firefox no necess\u00e0riament veu autom\u00e0ticament totes les veus que tu tens instal\u00b7lades a Piper.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">De fet, Mozilla t\u00e9 fins i tot una incid\u00e8ncia espec\u00edfica sobre aix\u00f2: <strong>Piper est\u00e0 instal\u00b7lat com a m\u00f2dul de Speech Dispatcher per\u00f2 Firefox no incorpora les veus Piper a <code>speechSynthesis.getVoices()<\/code><\/strong>.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">I aix\u00f2 explica exactament el que hem estat fent<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Tu ja tens:<\/p>\n\n\n\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=\"\">spd-say -L<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">i hi apareixen <strong>centenars\/milers de veus<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Aix\u00f2 significa que:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Speech Dispatcher s\u00ed que t\u00e9 veus.<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Per\u00f2 el teu navegador est\u00e0 dient:<\/p>\n\n\n\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=\"\">Firefox \u2192 speechSynthesis.getVoices()\n                         \u2193\n                       []<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Per tant, el problema <strong>no \u00e9s que Deepin no tingui veus<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u00c9s que hi ha una difer\u00e8ncia entre:<\/p>\n\n\n\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=\"\">veus disponibles per al sistema<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">i<\/p>\n\n\n\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=\"\">veus que Firefox Linux exposa a la Web Speech API<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Mozilla reconeix precisament aquesta fragilitat de la implementaci\u00f3 Linux.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Aix\u00f2 tamb\u00e9 explica una cosa molt important<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">La nostra infraestructura:<\/p>\n\n\n\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=\"\">Firefox \u2192 Speech Dispatcher \u2192 Piper \u2192 Ona<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>s\u00ed que pot funcionar per fer parlar Firefox<\/strong>, per\u00f2 hem de superar la capa de detecci\u00f3 de veus de <code>speechSynthesis<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Per aix\u00f2 jo faria ara una prova molt concreta al teu Deepin:<\/p>\n\n\n\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=\"\">speechSynthesis.getVoices().map(v => ({\n    name: v.name,\n    lang: v.lang,\n    localService: v.localService\n}))<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Si retorna <code>[]<\/code>, ja tenim confirmat que <strong>el problema est\u00e0 entre Firefox i Speech Dispatcher<\/strong>, no entre Piper i Ona.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I aix\u00f2 \u00e9s important perqu\u00e8 <strong>no cal abandonar Piper\/Ona ni tornar a eSpeak<\/strong>. Podem intentar fer que Firefox vegi expl\u00edcitament la veu que ja tens funcionant.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a target=\"_blank\" rel=\"noopener\" href=\"https:\/\/bugzilla.mozilla.org\/show_bug.cgi?id=1907786&amp;utm_source=chatgpt.com\">Incid\u00e8ncia de Mozilla sobre Piper i Web Speech API<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Conversor de text a veu Conversor de text a veu Aquest script, mosta les veus que admet el navegador S\u00ed. El problema principal del teu codi \u00e9s que forces Microsoft Zira en angl\u00e8s, aix\u00ed que Firefox no t\u00e9 cap possibilitat &hellip; <a href=\"https:\/\/www.beseit.net\/?p=17173\">Continua llegint <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":3167,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-17173","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-bloc-de-notes"],"_links":{"self":[{"href":"https:\/\/www.beseit.net\/index.php?rest_route=\/wp\/v2\/posts\/17173","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=17173"}],"version-history":[{"count":23,"href":"https:\/\/www.beseit.net\/index.php?rest_route=\/wp\/v2\/posts\/17173\/revisions"}],"predecessor-version":[{"id":19002,"href":"https:\/\/www.beseit.net\/index.php?rest_route=\/wp\/v2\/posts\/17173\/revisions\/19002"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.beseit.net\/index.php?rest_route=\/wp\/v2\/media\/3167"}],"wp:attachment":[{"href":"https:\/\/www.beseit.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=17173"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.beseit.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=17173"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.beseit.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=17173"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}