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