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> |