{"id":8929,"date":"2026-01-24T11:42:47","date_gmt":"2026-01-24T08:42:47","guid":{"rendered":"https:\/\/1.cbm.ua\/?p=8929"},"modified":"2026-01-30T19:49:31","modified_gmt":"2026-01-30T16:49:31","slug":"test-tts-%d0%bf%d1%80%d0%be%d1%81%d1%82%d0%b0%d1%8f-%d1%81%d1%82%d1%80%d0%b0%d0%bd%d0%b8%d1%86%d1%8b-%d1%81-%d1%87%d1%82%d0%b5%d0%bd%d0%b8%d0%b5%d0%bc","status":"publish","type":"post","link":"https:\/\/1.cbm.ua\/?p=8929","title":{"rendered":"Test TTS \u043f\u0440\u043e\u0441\u0442\u0430\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0441 \u0447\u0442\u0435\u043d\u0438\u0435\u043c."},"content":{"rendered":"\n<span class=\"lang-label\">RU<\/span>\n            <span class=\"phrase-text ru\">\u0414\u043e\u0431\u0440\u043e\u0435 \u0443\u0442\u0440\u043e! \u041a\u0430\u043a \u0443 \u0432\u0430\u0441 \u0434\u0435\u043b\u0430?<\/span>\n            <button class=\"play-btn\" onclick=\"speak('\u0414\u043e\u0431\u0440\u043e\u0435 \u0443\u0442\u0440\u043e! \u041a\u0430\u043a \u0443 \u0432\u0430\u0441 \u0434\u0435\u043b\u0430?', 'ru')\"> \u25ba\n                <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><polygon points=\"5,3 19,12 5,21\"\/><\/svg>\n            <\/button>\n\n\n\n<!DOCTYPE html>\n<html lang=\"de\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>\u041d\u0435\u043c\u0435\u0446\u043a\u043e-\u0440\u0443\u0441\u0441\u043a\u0438\u0435 \u0444\u0440\u0430\u0437\u044b<\/title>\n    <style>\n        * {\n            box-sizing: border-box;\n        }\n        \n        body {\n            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n            max-width: 600px;\n            margin: 0 auto;\n            padding: 20px;\n            background: #f5f5f5;\n        }\n        \n        .phrase-card {\n            background: white;\n            border-radius: 12px;\n            padding: 20px;\n            margin-bottom: 16px;\n            box-shadow: 0 2px 8px rgba(0,0,0,0.1);\n        }\n        \n        .phrase-row {\n            display: flex;\n            align-items: center;\n            gap: 12px;\n            padding: 10px 0;\n        }\n        \n        .phrase-row:first-child {\n            border-bottom: 1px solid #eee;\n        }\n        \n        .lang-label {\n            font-size: 12px;\n            font-weight: 600;\n            color: #666;\n            width: 30px;\n            flex-shrink: 0;\n        }\n        \n        .phrase-text {\n            flex: 1;\n            font-size: 18px;\n            line-height: 1.4;\n        }\n        \n        .de { color: #1a1a1a; }\n        .ru { color: #555; }\n        \n        .play-btn {\n            width: 44px;\n            height: 44px;\n            border: none;\n            border-radius: 50%;\n            background: #4a90d9;\n            color: white;\n            cursor: pointer;\n            display: flex;\n            align-items: center;\n            justify-content: center;\n            flex-shrink: 0;\n            transition: background 0.2s, transform 0.1s;\n        }\n        \n        .play-btn:hover {\n            background: #3a7bc8;\n        }\n        \n        .play-btn:active {\n            transform: scale(0.95);\n        }\n        \n        .play-btn:disabled {\n            background: #ccc;\n            cursor: not-allowed;\n        }\n        \n        .play-btn svg {\n            width: 20px;\n            height: 20px;\n        }\n    <\/style>\n<\/head>\n<body>\n    <div class=\"phrase-card\">\n        <div class=\"phrase-row\">\n            <span class=\"lang-label\">DE<\/span>\n            <span class=\"phrase-text de\">Guten Morgen! Wie geht es Ihnen?<\/span>\n            <button class=\"play-btn\" onclick=\"speak('Guten Morgen! Wie geht es Ihnen?', 'de')\">\n                <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><polygon points=\"5,3 19,12 5,21\"\/><\/svg>\n            <\/button>\n        <\/div>\n        <div class=\"phrase-row\">\n            <span class=\"lang-label\">RU<\/span>\n            <span class=\"phrase-text ru\">\u0414\u043e\u0431\u0440\u043e\u0435 \u0443\u0442\u0440\u043e! \u041a\u0430\u043a \u0443 \u0432\u0430\u0441 \u0434\u0435\u043b\u0430?<\/span>\n            <button class=\"play-btn\" onclick=\"speak('\u0414\u043e\u0431\u0440\u043e\u0435 \u0443\u0442\u0440\u043e! \u041a\u0430\u043a \u0443 \u0432\u0430\u0441 \u0434\u0435\u043b\u0430?', 'ru')\">\n                <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><polygon points=\"5,3 19,12 5,21\"\/><\/svg>\n            <\/button>\n        <\/div>\n    <\/div>\n\n    <div class=\"phrase-card\">\n        <div class=\"phrase-row\">\n            <span class=\"lang-label\">DE<\/span>\n            <span class=\"phrase-text de\">Ich lerne Deutsch seit einem Jahr.<\/span>\n            <button class=\"play-btn\" onclick=\"speak('Ich lerne Deutsch seit einem Jahr.', 'de')\">\n                <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><polygon points=\"5,3 19,12 5,21\"\/><\/svg>\n            <\/button>\n        <\/div>\n        <div class=\"phrase-row\">\n            <span class=\"lang-label\">RU<\/span>\n            <span class=\"phrase-text ru\">\u042f \u0443\u0447\u0443 \u043d\u0435\u043c\u0435\u0446\u043a\u0438\u0439 \u0443\u0436\u0435 \u0433\u043e\u0434.<\/span>\n            <button class=\"play-btn\" onclick=\"speak('\u042f \u0443\u0447\u0443 \u043d\u0435\u043c\u0435\u0446\u043a\u0438\u0439 \u0443\u0436\u0435 \u0433\u043e\u0434.', 'ru')\">\n                <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><polygon points=\"5,3 19,12 5,21\"\/><\/svg>\n            <\/button>\n        <\/div>\n    <\/div>\n\n    <div class=\"phrase-card\">\n        <div class=\"phrase-row\">\n            <span class=\"lang-label\">DE<\/span>\n            <span class=\"phrase-text de\">K\u00f6nnten Sie das bitte wiederholen?<\/span>\n            <button class=\"play-btn\" onclick=\"speak('K\u00f6nnten Sie das bitte wiederholen?', 'de')\">\n                <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><polygon points=\"5,3 19,12 5,21\"\/><\/svg>\n            <\/button>\n        <\/div>\n        <div class=\"phrase-row\">\n            <span class=\"lang-label\">RU<\/span>\n            <span class=\"phrase-text ru\">\u041d\u0435 \u043c\u043e\u0433\u043b\u0438 \u0431\u044b \u0432\u044b \u043f\u043e\u0432\u0442\u043e\u0440\u0438\u0442\u044c?<\/span>\n            <button class=\"play-btn\" onclick=\"speak('\u041d\u0435 \u043c\u043e\u0433\u043b\u0438 \u0431\u044b \u0432\u044b \u043f\u043e\u0432\u0442\u043e\u0440\u0438\u0442\u044c?', 'ru')\">\n                <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><polygon points=\"5,3 19,12 5,21\"\/><\/svg>\n            <\/button>\n        <\/div>\n    <\/div>\n\n    <script>\n        var preferredVoices = {\n            'en': ['Google US English 1 (Natural)', 'Google US English', 'Google UK English Female', 'Microsoft David'],\n            'de': ['Google Deutsch', 'GoogleTranslate German', 'Microsoft Stefan', 'Microsoft Katja'],\n            'ru': ['Google \u0440\u0443\u0441\u0441\u043a\u0438\u0439', 'GoogleTranslate Russian', 'Microsoft Pavel', 'Microsoft Irina'],\n            'fr': ['Google fran\u00e7ais', 'GoogleTranslate French'],\n            'es': ['Google espa\u00f1ol', 'GoogleTranslate Spanish', 'Microsoft Helena', 'Microsoft Pablo'],\n            'it': ['Google italiano', 'GoogleTranslate Italian']\n        };\n\n        var voiceCache = {};\n\n        function getVoice(lang) {\n            if (voiceCache[lang]) {\n                return voiceCache[lang];\n            }\n\n            var voices = speechSynthesis.getVoices();\n            var preferred = preferredVoices[lang] || [];\n\n            for (var i = 0; i < preferred.length; i++) {\n                for (var j = 0; j < voices.length; j++) {\n                    if (voices[j].name === preferred[i]) {\n                        voiceCache[lang] = voices[j];\n                        return voices[j];\n                    }\n                }\n            }\n\n            \/\/ Fallback: \u043f\u0435\u0440\u0432\u044b\u0439 \u0433\u043e\u043b\u043e\u0441 \u0441 \u043d\u0443\u0436\u043d\u044b\u043c \u044f\u0437\u044b\u043a\u043e\u043c\n            for (var k = 0; k < voices.length; k++) {\n                if (voices[k].lang.startsWith(lang)) {\n                    voiceCache[lang] = voices[k];\n                    return voices[k];\n                }\n            }\n\n            return null;\n        }\n\n        function speak(text, lang) {\n            speechSynthesis.cancel();\n\n            var utterance = new SpeechSynthesisUtterance(text);\n            var voice = getVoice(lang);\n            \n            if (voice) {\n                utterance.voice = voice;\n            }\n            utterance.lang = lang;\n            utterance.rate = 0.9;\n\n            speechSynthesis.speak(utterance);\n        }\n\n        \/\/ \u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0433\u043e\u043b\u043e\u0441\u043e\u0432 (\u0432 Chrome \u043e\u043d\u0438 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u044e\u0442\u0441\u044f \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e)\n        speechSynthesis.onvoiceschanged = function() {\n            voiceCache = {};\n        };\n    <\/script>\n<\/body>\n<\/html>\n\n\n\n<p><\/p>\n\n\n\n<details class=\"wp-block-details is-layout-flow wp-block-details-is-layout-flow\"><summary>\u0418\u0418 \u041f\u041e<\/summary>\n<p><a href=\"https:\/\/claude.ai\/chat\/92c6711f-126b-4b91-9e6f-580004e221ab\">https:\/\/claude.ai\/chat\/92c6711f-126b-4b91-9e6f-580004e221ab<\/a><\/p>\n<\/details>\n","protected":false},"excerpt":{"rendered":"<p>RU \u0414\u043e\u0431\u0440\u043e\u0435 \u0443\u0442\u0440\u043e! \u041a\u0430\u043a \u0443 \u0432\u0430\u0441 \u0434\u0435\u043b\u0430? \u25ba \u041d\u0435\u043c\u0435\u0446\u043a\u043e-\u0440\u0443\u0441\u0441\u043a\u0438\u0435 \u0444\u0440\u0430\u0437\u044b DE Guten Morgen! Wie geht es Ihnen? RU \u0414\u043e\u0431\u0440\u043e\u0435 \u0443\u0442\u0440\u043e! \u041a\u0430\u043a \u0443 \u0432\u0430\u0441 \u0434\u0435\u043b\u0430? DE Ich lerne Deutsch seit einem Jahr. RU \u042f \u0443\u0447\u0443 \u043d\u0435\u043c\u0435\u0446\u043a\u0438\u0439 \u0443\u0436\u0435 \u0433\u043e\u0434. DE K\u00f6nnten Sie das bitte wiederholen? RU \u041d\u0435 \u043c\u043e\u0433\u043b\u0438 \u0431\u044b \u0432\u044b \u043f\u043e\u0432\u0442\u043e\u0440\u0438\u0442\u044c?<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"neve_meta_sidebar":"","neve_meta_container":"","neve_meta_enable_content_width":"","neve_meta_content_width":0,"neve_meta_title_alignment":"","neve_meta_author_avatar":"","neve_post_elements_order":"","neve_meta_disable_header":"","neve_meta_disable_footer":"","neve_meta_disable_title":"","footnotes":""},"categories":[205,152,184,148,6],"tags":[],"class_list":["post-8929","post","type-post","status-publish","format-standard","hentry","category--tts","category-152","category--script","category-deutsch","category-js"],"_links":{"self":[{"href":"https:\/\/1.cbm.ua\/index.php?rest_route=\/wp\/v2\/posts\/8929","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/1.cbm.ua\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/1.cbm.ua\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/1.cbm.ua\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/1.cbm.ua\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=8929"}],"version-history":[{"count":8,"href":"https:\/\/1.cbm.ua\/index.php?rest_route=\/wp\/v2\/posts\/8929\/revisions"}],"predecessor-version":[{"id":9058,"href":"https:\/\/1.cbm.ua\/index.php?rest_route=\/wp\/v2\/posts\/8929\/revisions\/9058"}],"wp:attachment":[{"href":"https:\/\/1.cbm.ua\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=8929"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/1.cbm.ua\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=8929"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/1.cbm.ua\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=8929"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}