update frontend
Browse files- src/demo.png +0 -0
- src/live_transcription.html +72 -5
src/demo.png
CHANGED
![]() |
![]() |
src/live_transcription.html
CHANGED
@@ -41,24 +41,86 @@
|
|
41 |
display: inline;
|
42 |
color: rgb(197, 197, 197);
|
43 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
44 |
</style>
|
45 |
</head>
|
46 |
<body>
|
47 |
-
<
|
48 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
49 |
<div id="transcriptions"></div>
|
50 |
|
51 |
<script>
|
52 |
-
let isRecording = false, websocket, recorder;
|
53 |
|
54 |
const statusText = document.getElementById("status");
|
55 |
const recordButton = document.getElementById("recordButton");
|
|
|
|
|
56 |
const transcriptionsDiv = document.getElementById("transcriptions");
|
57 |
|
58 |
let fullTranscription = ""; // Store confirmed transcription
|
59 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
60 |
function setupWebSocket() {
|
61 |
-
websocket = new WebSocket(
|
62 |
websocket.onmessage = (event) => {
|
63 |
const data = JSON.parse(event.data);
|
64 |
const { transcription, buffer } = data;
|
@@ -72,13 +134,18 @@
|
|
72 |
<span class="buffer">${buffer}</span>
|
73 |
`;
|
74 |
};
|
|
|
|
|
|
|
|
|
|
|
75 |
}
|
76 |
|
77 |
async function startRecording() {
|
78 |
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
|
79 |
recorder = new MediaRecorder(stream, { mimeType: "audio/webm" });
|
80 |
recorder.ondataavailable = (e) => websocket?.send(e.data);
|
81 |
-
recorder.start(
|
82 |
isRecording = true;
|
83 |
updateUI();
|
84 |
}
|
|
|
41 |
display: inline;
|
42 |
color: rgb(197, 197, 197);
|
43 |
}
|
44 |
+
.settings-container {
|
45 |
+
display: flex;
|
46 |
+
justify-content: center;
|
47 |
+
align-items: center;
|
48 |
+
gap: 15px;
|
49 |
+
margin-top: 20px;
|
50 |
+
}
|
51 |
+
.settings {
|
52 |
+
display: flex;
|
53 |
+
flex-direction: column;
|
54 |
+
align-items: flex-start;
|
55 |
+
gap: 5px;
|
56 |
+
}
|
57 |
+
#chunkSelector, #websocketInput {
|
58 |
+
font-size: 16px;
|
59 |
+
padding: 5px;
|
60 |
+
border-radius: 5px;
|
61 |
+
border: 1px solid #ddd;
|
62 |
+
background-color: #f9f9f9;
|
63 |
+
}
|
64 |
+
#websocketInput {
|
65 |
+
width: 200px;
|
66 |
+
}
|
67 |
+
#chunkSelector:focus, #websocketInput:focus {
|
68 |
+
outline: none;
|
69 |
+
border-color: #007bff;
|
70 |
+
}
|
71 |
+
label {
|
72 |
+
font-size: 14px;
|
73 |
+
}
|
74 |
</style>
|
75 |
</head>
|
76 |
<body>
|
77 |
+
<div class="settings-container">
|
78 |
+
<button id="recordButton">🎙️</button>
|
79 |
+
<div class="settings">
|
80 |
+
<div>
|
81 |
+
<label for="chunkSelector">Chunk size (ms):</label>
|
82 |
+
<select id="chunkSelector">
|
83 |
+
<option value="500">500 ms</option>
|
84 |
+
<option value="1000" selected>1000 ms</option>
|
85 |
+
<option value="2000">2000 ms</option>
|
86 |
+
<option value="3000">3000 ms</option>
|
87 |
+
<option value="4000">4000 ms</option>
|
88 |
+
<option value="5000">5000 ms</option>
|
89 |
+
</select>
|
90 |
+
</div>
|
91 |
+
<div>
|
92 |
+
<label for="websocketInput">WebSocket URL:</label>
|
93 |
+
<input id="websocketInput" type="text" value="ws://localhost:8000/ws" />
|
94 |
+
</div>
|
95 |
+
</div>
|
96 |
+
</div>
|
97 |
+
<p id="status"></p>
|
98 |
+
|
99 |
<div id="transcriptions"></div>
|
100 |
|
101 |
<script>
|
102 |
+
let isRecording = false, websocket, recorder, chunkDuration = 1000, websocketUrl = "ws://localhost:8000/ws";
|
103 |
|
104 |
const statusText = document.getElementById("status");
|
105 |
const recordButton = document.getElementById("recordButton");
|
106 |
+
const chunkSelector = document.getElementById("chunkSelector");
|
107 |
+
const websocketInput = document.getElementById("websocketInput");
|
108 |
const transcriptionsDiv = document.getElementById("transcriptions");
|
109 |
|
110 |
let fullTranscription = ""; // Store confirmed transcription
|
111 |
|
112 |
+
// Update chunk duration based on the selector
|
113 |
+
chunkSelector.addEventListener("change", () => {
|
114 |
+
chunkDuration = parseInt(chunkSelector.value);
|
115 |
+
});
|
116 |
+
|
117 |
+
// Update WebSocket URL dynamically
|
118 |
+
websocketInput.addEventListener("change", () => {
|
119 |
+
websocketUrl = websocketInput.value;
|
120 |
+
});
|
121 |
+
|
122 |
function setupWebSocket() {
|
123 |
+
websocket = new WebSocket(websocketUrl);
|
124 |
websocket.onmessage = (event) => {
|
125 |
const data = JSON.parse(event.data);
|
126 |
const { transcription, buffer } = data;
|
|
|
134 |
<span class="buffer">${buffer}</span>
|
135 |
`;
|
136 |
};
|
137 |
+
|
138 |
+
websocket.onerror = () => {
|
139 |
+
statusText.textContent = "Error connecting to WebSocket";
|
140 |
+
stopRecording(); // Stop recording if WebSocket fails
|
141 |
+
};
|
142 |
}
|
143 |
|
144 |
async function startRecording() {
|
145 |
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
|
146 |
recorder = new MediaRecorder(stream, { mimeType: "audio/webm" });
|
147 |
recorder.ondataavailable = (e) => websocket?.send(e.data);
|
148 |
+
recorder.start(chunkDuration); // Use dynamic chunk duration
|
149 |
isRecording = true;
|
150 |
updateUI();
|
151 |
}
|