{"id":19199,"date":"2026-09-21T18:57:03","date_gmt":"2026-09-21T16:57:03","guid":{"rendered":"https:\/\/www.beseit.net\/?p=19199"},"modified":"2026-09-21T18:57:52","modified_gmt":"2026-09-21T16:57:52","slug":"entrada-des-del-formulari-html-per-al-servidor-tts-ona-upc-a-deepin-del-docker","status":"publish","type":"post","link":"https:\/\/www.beseit.net\/?p=19199","title":{"rendered":"Entrada des del formulari html per al servidor TTS (Ona, UPC) a Deepin del Docker"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Perfecte, Miquel \u2014 ara entenc exactament qu\u00e8 vols:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\ud83d\udc49 <strong>Que l\u2019entrada del blog expliqui que NO cal obrir cap terminal, ni arrencar Python, ni entrar al servidor Flask.<\/strong> \ud83d\udc49 <strong>Nom\u00e9s cal obrir el fitxer local<\/strong> <code>TTS Piper (Ona).html<\/code>, i aquest formulari ja envia el text al servidor Flask que est\u00e0 funcionant en segon pla gr\u00e0cies a <code>systemd<\/code>. \ud83d\udc49 <strong>I que la URL<\/strong> <code>http:\/\/127.0.0.1:5000<\/code> <strong>nom\u00e9s \u00e9s visible en mode debug<\/strong>, per\u00f2 en l\u2019\u00fas normal no cal ni visitar-la.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Aix\u00f2 \u00e9s molt m\u00e9s elegant i molt m\u00e9s \u201cuser\u2011friendly\u201d.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A continuaci\u00f3 et deixo el <strong>text revisat<\/strong> perqu\u00e8 l\u2019entrada del blog reflecteixi exactament aquest comportament.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\"><strong>Entrada des de formulari HTML per al servidor TTS (Ona, UPC) a Deepin del Docker<\/strong><\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Aquesta entrada complementa la guia principal <strong>\u201cMuntatge d\u2019un servidor TTS local amb veu catalana (Ona, UPC) a Deepin\u201d<\/strong> i explica com afegir-hi un <strong>formulari HTML extern<\/strong> que permet enviar text directament al servidor TTS sense obrir cap terminal.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">L\u2019objectiu \u00e9s disposar d\u2019un sistema molt simple d\u2019usar: <strong>nom\u00e9s cal obrir el fitxer<\/strong> <code>TTS Piper (Ona).html<\/code> i escriure el text. El servidor Flask ja est\u00e0 funcionant en segon pla gr\u00e0cies a <code>systemd<\/code>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\ud83c\udfaf Objectiu<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Crear un servidor Flask que escolta a <code>127.0.0.1:5000\/processa<\/code>.<\/li>\n\n\n\n<li>Fer que Flask s\u2019inici\u00ef autom\u00e0ticament en cada arrencada del sistema.<\/li>\n\n\n\n<li>Crear un fitxer HTML local que envia text al servidor TTS.<\/li>\n\n\n\n<li>Permetre que tot el sistema funcioni <strong>sense obrir Python<\/strong>, <strong>sense activar entorns virtuals<\/strong>, <strong>sense obrir cap terminal<\/strong>.<\/li>\n\n\n\n<li>Fer que el sistema sigui <strong>reprodu\u00efble en qualsevol Deepin\/Debian<\/strong>.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">\ud83d\uddc2\ufe0f Estructura final del projecte<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Codi<\/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=\"\">~\/tts-flask\/\n \u251c\u2500\u2500 server.py\n \u2514\u2500\u2500 venv\/\n~\/Desktop\/\n \u2514\u2500\u2500 TTS Piper (Ona).html\n\/etc\/systemd\/system\/\n \u2514\u2500\u2500 flask.service\n<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">1\ufe0f\u20e3 Instal\u00b7laci\u00f3 de Flask<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">bash<\/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=\"\">mkdir -p ~\/tts-flask\ncd ~\/tts-flask\n\npython3 -m venv venv\nsource venv\/bin\/activate\n\npip install flask\n<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">2\ufe0f\u20e3 Fitxer <code>server.py<\/code><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Ubicaci\u00f3:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Codi<\/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=\"\">~\/tts-flask\/server.py\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Funciona com a pont entre el formulari HTML i el contenidor Docker <code>piper<\/code>. Rep text, el passa al contenidor i reprodueix l\u2019\u00e0udio amb <code>aplay<\/code>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">3\ufe0f\u20e3 Fitxer <code>flask.service<\/code> (systemd)<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Ubicaci\u00f3:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Codi<\/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=\"\">\/etc\/systemd\/system\/flask.service\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Aquest servei garanteix que Flask s\u2019inicia autom\u00e0ticament en cada arrencada:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>No cal executar Python manualment.<\/strong><\/li>\n\n\n\n<li><strong>No cal activar cap entorn virtual.<\/strong><\/li>\n\n\n\n<li><strong>No cal obrir cap terminal.<\/strong><\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Nom\u00e9s cal tenir el fitxer HTML.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">4\ufe0f\u20e3 Activaci\u00f3 del servei<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">bash<\/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=\"\">sudo systemctl daemon-reload\nsudo systemctl enable flask.service\nsudo systemctl start flask.service\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Despr\u00e9s d\u2019aix\u00f2, el servidor Flask queda sempre actiu.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">5\ufe0f\u20e3 Fitxer HTML: <code>TTS Piper (Ona).html<\/code><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Aquest \u00e9s el fitxer que l\u2019usuari obre per enviar text al TTS.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Es pot guardar a:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Codi<\/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=\"\">~\/Desktop\/TTS Piper (Ona).html\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Contingut:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">html<\/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=\"\">&lt;!DOCTYPE html>\n&lt;html lang=\"ca\">\n&lt;head>\n    &lt;meta charset=\"UTF-8\">\n    &lt;title>TTS Piper (Ona)&lt;\/title>\n&lt;\/head>\n&lt;body>\n    &lt;h1>TTS Piper (Ona)&lt;\/h1>\n    &lt;form action=\"http:\/\/127.0.0.1:5000\/processa\" method=\"post\">\n        &lt;label for=\"text\">Text:&lt;\/label>&lt;br>\n        &lt;textarea id=\"text\" name=\"text\" rows=\"5\" style=\"width: 80%;\">&lt;\/textarea>&lt;br>&lt;br>\n\n        &lt;button type=\"submit\" title=\"Escoltar text\" aria-label=\"Escoltar text\"\n            style=\"background: none; border: 1px solid #ccc; border-radius: 6px;\n                   cursor: pointer; padding: 8px; display: inline-flex;\n                   align-items: center; justify-content: center;\n                   transition: background-color 0.2s;\"\n            onmouseover=\"this.style.backgroundColor='#f0f0f0'\"\n            onmouseout=\"this.style.backgroundColor='none'\">\n\n            &lt;svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"24\" height=\"24\"\n                 viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#333\" stroke-width=\"2\"\n                 stroke-linecap=\"round\" stroke-linejoin=\"round\">\n                &lt;polygon points=\"11 5 6 9 2 9 2 15 6 15 11 19 11 5\">&lt;\/polygon>\n                &lt;path d=\"M19.07 4.93a10 10 0 0 1 0 14.14M15.54 8.46a5 5 0 0 1 0 7.07\">&lt;\/path>\n            &lt;\/svg>\n        &lt;\/button>\n    &lt;\/form>\n&lt;\/body>\n&lt;\/html>\n<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">6\ufe0f\u20e3 \u00das normal del sistema<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Un cop configurat:<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">\u2714\ufe0f <strong>Nom\u00e9s cal obrir<\/strong> <code>TTS Piper (Ona).html<\/code><\/h3>\n\n\n\n<h3 class=\"wp-block-heading\">\u2714\ufe0f Escriure el text<\/h3>\n\n\n\n<h3 class=\"wp-block-heading\">\u2714\ufe0f Fer clic al bot\u00f3 d\u2019altaveu<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">I el sistema:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>envia el text al servidor Flask<\/li>\n\n\n\n<li>Flask el passa al contenidor Docker <code>piper<\/code><\/li>\n\n\n\n<li>Piper genera l\u2019\u00e0udio<\/li>\n\n\n\n<li><code>aplay<\/code> el reprodueix<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Tot aix\u00f2 <strong>sense obrir cap terminal<\/strong>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">7\ufe0f\u20e3 Sobre <code>http:\/\/127.0.0.1:5000<\/code><\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>La p\u00e0gina existeix, per\u00f2 <strong>nom\u00e9s \u00e9s \u00fatil en mode debug<\/strong>.<\/li>\n\n\n\n<li>En l\u2019\u00fas normal <strong>no cal visitar-la<\/strong>.<\/li>\n\n\n\n<li>El formulari HTML \u00e9s l\u2019\u00fanica interf\u00edcie que cal.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">\ud83d\udd17 Enlla\u00e7 amb l\u2019article principal<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Aquesta entrada forma part del projecte complet documentat a:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Muntatge d\u2019un servidor TTS local amb veu catalana (Ona, UPC) a Deepin<\/strong> (tab actual: )<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\ud83c\udf93 Conclusions<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Amb aquest formulari HTML:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>El sistema TTS \u00e9s <strong>molt m\u00e9s accessible<\/strong>.<\/li>\n\n\n\n<li>No cal cap coneixement de Python ni Docker.<\/li>\n\n\n\n<li>Tot funciona autom\u00e0ticament gr\u00e0cies a <code>systemd<\/code>.<\/li>\n\n\n\n<li>\u00c9s 100% reprodu\u00efble en qualsevol equip Deepin\/Debian.<\/li>\n\n\n\n<li>L\u2019usuari nom\u00e9s interactua amb un fitxer HTML senzill i elegant.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Si vols, puc generar <strong>la versi\u00f3 exacta en Markdown<\/strong> per enganxar-la al WordPress (tab 1330389275).<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Perfecte, Miquel \u2014 ara entenc exactament qu\u00e8 vols: \ud83d\udc49 Que l\u2019entrada del blog expliqui que NO cal obrir cap terminal, ni arrencar Python, ni entrar al servidor Flask. \ud83d\udc49 Nom\u00e9s cal obrir el fitxer local TTS Piper (Ona).html, i aquest &hellip; <a href=\"https:\/\/www.beseit.net\/?p=19199\">Continua llegint <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":3169,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[207,1],"tags":[],"class_list":["post-19199","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-deepin-linux","category-bloc-de-notes"],"_links":{"self":[{"href":"https:\/\/www.beseit.net\/index.php?rest_route=\/wp\/v2\/posts\/19199","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=19199"}],"version-history":[{"count":1,"href":"https:\/\/www.beseit.net\/index.php?rest_route=\/wp\/v2\/posts\/19199\/revisions"}],"predecessor-version":[{"id":19200,"href":"https:\/\/www.beseit.net\/index.php?rest_route=\/wp\/v2\/posts\/19199\/revisions\/19200"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.beseit.net\/index.php?rest_route=\/wp\/v2\/media\/3169"}],"wp:attachment":[{"href":"https:\/\/www.beseit.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=19199"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.beseit.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=19199"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.beseit.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=19199"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}