File size: 10,240 Bytes
da8e0c5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="icon" type="image/svg+xml" href="./voice.png" />
    <script src="//cdn.tailwindcss.com?plugins=forms"></script>
    <link href="https://cdn.jsdelivr.net/npm/tailwindcss@latest/dist/tailwind.min.css" rel="stylesheet">
    <script src="//cdn.jsdelivr.net/npm/[email protected]/dist/cdn.min.js" defer></script>
    <script src="./app.js"></script>
    <title>voiceapi demo </title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
    </style>

    <style type="text/tailwindcss">
        .label { @apply text-gray-900 w-[50px] lg:w-20 }
        .title{
            @apply text-[16px] text-zinc-500 mx-2;
        }

        .select { @apply w-full rounded-md h-10 }

        .round { @apply rounded border px-3 p-2 border-slate-300 placeholder-gray-400 placeholder:text-sm
                        focus:bg-white focus:text-gray-900 focus:placeholder-gray-500 focus:outline-none
                         focus:border-zinc-950 focus:border ring-0 focus:ring-0 text-gray-900 }

        .checkbox { @apply ml-2 lg:ml-4 border focus:outline-none ring-0 focus:ring-gray-800 text-gray-900 }
        .dash{ @apply border border-dashed border-zinc-200 flex flex-grow }

        .button { @apply hover:bg-opacity-90 text-white font-bold py-1.5 px-6 rounded-full cursor-pointer }
        .card { @apply bg-white shadow-sm rounded-xl border p-4 }


    .animate-ping { 
        animation: ping 2s cubic-bezier(0.5, 0.4, 0.2, 1) infinite;
    }

    @keyframes ping {
        0% {
            transform: scale(1);
            opacity: 1;
        }
        50% {
            transform: scale(1.2);
            opacity: 0.7;
        }
        100% {
            transform: scale(1);
            opacity: 1;
        }
    }
    </style>
</head>

<body>
    <script>
        async function initAudioWorklet() {
            try {
                // Check for browser support
                if (!('AudioContext' in window) || !('audioWorklet' in AudioContext.prototype)) {
                    console.error('Audio Worklet API is not supported in this browser.');
                    return;
                }

                // Initialize AudioContext
                const audioContext = new AudioContext();

                // Add Audio Worklet module
                await audioContext.audioWorklet.addModule('./audio_process.js');

                console.log('Audio Worklet module added successfully.');
                // Your code to use the Audio Worklet goes here

            } catch (error) {
                console.error('Error initializing Audio Worklet:', error);
            }
        }

        // Initialize Audio Worklet when the page is loaded
        window.addEventListener('load', initAudioWorklet);
    </script>
    <div x-data="demoapp">
        <header class="bg-gray-900 py-4 px-5 lg:p-4 lg:px-10 text-white sticky top-0 z-20">
            <div class="flex w-full justify-between items-center">
                <p class="gap-x-3">
                    <span>VoiceAPI Demo</span> /
                    <a href="https://ruzhila.cn/?from=voiceapi_demo">ruzhila.cn</a>
                </p>
                <a target="_blank" href="https://github.com/ruzhila/voiceapi" class="hover:cursor-pointer">
                    <svg t="1724996252746" class="icon" viewBox="0 0 1024 1024" version="1.1"
                        xmlns="http://www.w3.org/2000/svg" p-id="" width="25" height="25">
                        <path
                            d="M512 12.64c-282.752 0-512 229.216-512 512 0 226.208 146.72 418.144 350.144 485.824 25.6 4.736 35.008-11.104 35.008-24.64 0-12.192-0.48-52.544-0.704-95.328-142.464 30.976-172.512-60.416-172.512-60.416-23.296-59.168-56.832-74.912-56.832-74.912-46.464-31.776 3.52-31.136 3.52-31.136 51.392 3.616 78.464 52.768 78.464 52.768 45.664 78.272 119.776 55.648 148.992 42.56 4.576-33.088 17.856-55.68 32.512-68.48-113.728-12.928-233.28-56.864-233.28-253.024 0-55.904 20-101.568 52.768-137.44-5.312-12.896-22.848-64.96 4.96-135.488 0 0 43.008-13.76 140.832 52.48 40.832-11.36 84.64-17.024 128.16-17.248 43.488 0.192 87.328 5.888 128.256 17.248 97.728-66.24 140.64-52.48 140.64-52.48 27.872 70.528 10.336 122.592 5.024 135.488 32.832 35.84 52.704 81.536 52.704 137.44 0 196.64-119.776 239.936-233.792 252.64 18.368 15.904 34.72 47.04 34.72 94.816 0 68.512-0.608 123.648-0.608 140.512 0 13.632 9.216 29.6 35.168 24.576 203.328-67.776 349.856-259.616 349.856-485.76 0-282.784-229.248-512-512-512z"
                            fill="#ffffff"></path>
                    </svg>
                </a>
            </div>
        </header>

        <div class="flex px-6 gap-x-10 w-full max-w-7xl mx-auto">
            <div class="relative flex flex-col items-center w-1/3 py-10">
                <div class="w-full">
                    <textarea x-model="text" class="round p-4 w-full h-[36rem] text-sm"
                        placeholder="Enter text here"></textarea>
                </div>

                <div>
                    <button @click="dotts" :disabled="disabled"
                        class="button bg-gray-900 flex items-center gap-x-2 mt-6">
                        <span>Speak</span>
                        <svg t="1726215464577" class="icon" viewBox="0 0 1024 1024" version="1.1"
                            xmlns="http://www.w3.org/2000/svg" p-id="4263" width="20" height="20">
                            <path
                                d="M830.450526 853.759999q-11.722105 8.791579-27.351579 8.791579-19.536842 0-33.701053-14.164211t-14.164211-33.701053q0-21.490526 
                   16.606316-36.143158 0.976842-0.976842 1.953684-1.465263t1.953684-1.465263l0.976842-0.976842q27.351579-18.56 50.795789-43.957895t41.027368-55.191579 27.351579-63.494737 9.768421-69.84421q0-73.263158-37.12-133.827368t-92.8-99.637895q-20.513684-14.652632-20.513684-39.073684 0-19.536842 14.164211-33.701053t33.701053-14.164211q16.606316 0 29.305263 10.745263 36.143158 25.397895 67.402105 59.098947t53.726316 73.263158 35.166316 84.496842 12.698947 92.8q0 48.842105-12.698947 93.776842t-35.654737 84.985263-54.214737 73.751579-68.378947 59.098947zM775.747368 415.157894q20.513684 28.328421 32.72421 57.145263t12.210526 69.84421q0 39.073684-12.698947 70.332632t-32.235789 56.656842q-7.814737 10.745263-16.606316 19.048421t-22.467368 8.303158q-17.583158 0-29.793684-12.698947t-12.210526-30.282105q0-7.814737 2.930526-15.629474l-0.976842 0q4.884211-10.745263 11.722105-20.513684t13.187368-20.025263 10.745263-23.444211 4.395789-31.747368q0-17.583158-4.395789-30.770526t-10.745263-23.932632-13.187368-20.513684-10.745263-20.513684q-2.930526-6.837895-2.930526-15.629474 0-17.583158 12.210526-30.282105t29.793684-12.698947q13.675789 0 22.467368 8.303158t16.606316 19.048421zM460.227368 995.402104q-49.818947-44.934737-105.498947-93.776842t-103.545263-89.869474q-55.68-46.888421-111.36-92.8-10.745263 0.976842-21.490526 0.976842-8.791579 0.976842-18.56 0.976842l-16.606316 0q-26.374737 0-42.981053-16.117895t-16.606316-38.585263l0-246.16421 0.976842 0-0.976842-0.976842q0-27.351579 17.094737-44.934737t42.492632-17.583158l55.68 0q89.869474-76.193684 163.132631-136.757895 31.258947-26.374737 61.541053-51.28421t54.703158-45.423158 41.027368-34.189474 20.513684-16.606316q29.305263-21.490526 47.376842-19.536842t28.328421 17.583158 14.164211 38.096842 3.907368 41.027368l0 788.311578 0 2.930526q0 18.56-6.837895 39.562105t-21.002105 33.212632-35.654737 10.256842-49.818947-28.328421z"
                                p-id="4264" fill="#ffffff"></path>
                        </svg>
                    </button>
                </div>
                <template x-if="elapsedTime">
                    <p x-text="`elapsedTime: ${elapsedTime}`" class="mt-4 text-sm text-gray-600 "></p>
                </template>
            </div>

            <!-- recording  -->
            <div class="w-full flex-grow h-[calc(100vh-10rem)] xl:pl-10 py-10">

                <div
                    class="rounded border border-gray-500 p-3 w-full flex flex-col items-end h-[36rem] overflow-y-auto">
                    <template x-for="item in logs">
                        <div class="mt-3 mb-2">
                            <span
                                class="text-white px-4 py-1.5 text-[13px] display-inline-block border border-gray-900 rounded-t-full rounded-l-full bg-gray-900 justify-end w-auto"
                                x-text="item?.text">
                            </span>
                        </div>
                    </template>
                </div>


                <template x-if="currentText">
                    <p x-text="`${currentText} …`" class="text-gray-800 mt-4 text-sm text-center"></p>
                </template>

                <template x-if="!recording">
                    <div class="flex flex-col gap-y-4 items-center justify-center mt-4">
                        <p @click="doasr"
                            class="mt-2 border border-gray-100 rounded-full duration-300 hover:scale-105 hover:border-gray-400">
                            <img src="./images/record.svg" alt="" class="w-14 h-14 mx-auto cursor-pointer">
                        </p>
                        <p class="text-gray-600">Click to record !</p>
                    </div>
                </template>

                <template x-if="recording">
                    <div class="flex flex-col items-center justify-center gap-y-4 mt-4">

                        <p @click="stopasr"
                            class="mt-2 border border-red-100 rounded-full duration-300 hover:scale-105  hover:border-red-400">
                            <img src="./images/speaking.svg" alt=""
                                class="w-14 h-14 mx-auto cursor-pointer animate-ping">
                        </p>
                        <div class="flex items-center text-gray-600 gap-x-4">
                            <p>Click to stop recording !</p>
                        </div>
                    </div>
                </template>
            </div>
        </div>
    </div>
    </div>
</body>

</html>