Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix issue in upload and offlind-record pages of python streaming server #284

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions python-api-examples/http_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,18 @@
("/js/bootstrap.min.js", "application/javascript"),
("/js/bootstrap.min.js.map", "application/javascript"),
("/js/jquery-3.6.0.min.js", "application/javascript"),
("/js/offline_record.js", "application/javascript"),
("/js/offline_record.js", "application/javascript"),
("/js/non_streaming_record.js", "application/javascript"),
("/js/popper.min.js", "application/javascript"),
("/js/popper.min.js.map", "application/javascript"),
("/js/streaming_record.js", "application/javascript"),
("/js/upload.js", "application/javascript"),
("/js/streaming_upload.js", "application/javascript"),
("/js/non_streaming_upload.js", "application/javascript"),
("/k2-logo.png", "image/png"),
("/nav-partial.html", "text/html"),
("/offline_record.html", "text/html"),
("/non_streaming_record.html", "text/html"),
("/streaming_record.html", "text/html"),
("/upload.html", "text/html"),
("/streaming_upload.html", "text/html"),
("/non_streaming_upload.html", "text/html"),
)

_404_page = r"""
Expand Down
4 changes: 4 additions & 0 deletions python-api-examples/non_streaming_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -536,6 +536,10 @@ async def process_request(
# This is a normal HTTP request
if path == "/":
path = "/index.html"
if path == "/upload.html":
path = "/non_streaming_upload.html"
if path == "/offline_record.html":
path = "/non_streaming_record.html"
if path[-1] == "?":
path = path[:-1]

Expand Down
14 changes: 10 additions & 4 deletions python-api-examples/streaming_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -527,15 +527,21 @@ async def process_request(
# This is a normal HTTP request
if path == "/":
path = "/index.html"

if path in ("/upload.html", "/offline_record.html"):
if path == "/upload.html":
path = "/streaming_upload.html"
if path == "/offline_record.html":
response = r"""
<!doctype html><html><head>
<title>Speech recognition with next-gen Kaldi</title><body>
<h2>Only /streaming_record.html is available for the streaming server.<h2>
<h2>Only
<a href="/upload.html">/upload.html</a>
and
<a href="/streaming_record.html">/streaming_record.html</a>
is available for the streaming server.<h2>
<br/>
<br/>
Go back to <a href="/streaming_record.html">/streaming_record.html</a>
Go back to <a href="/upload.html">/upload.html</a>
or <a href="/streaming_record.html">/streaming_record.html</a>
</body></head></html>
"""
found = True
Expand Down
167 changes: 167 additions & 0 deletions python-api-examples/web/js/streaming_upload.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
/**
References
https://developer.mozilla.org/en-US/docs/Web/API/FileList
https://developer.mozilla.org/en-US/docs/Web/API/FileReader
https://javascript.info/arraybuffer-binary-arrays
https://developer.mozilla.org/zh-CN/docs/Web/API/WebSocket
https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/send
*/

var socket;
var recognition_text = [];

function getDisplayResult() {
let i = 0;
let ans = '';
for (let s in recognition_text) {
if (recognition_text[s] == '') continue;

ans += '' + i + ': ' + recognition_text[s] + '\n';
i += 1;
}
return ans;
}

const serverIpInput = document.getElementById('server-ip');
const serverPortInput = document.getElementById('server-port');

const connectBtn = document.getElementById('connect');
const uploadBtn = document.getElementById('file');

function initWebSocket() {
let protocol = 'ws://';
if (window.location.protocol == 'https:') {
protocol = 'wss://'
}
let server_ip = serverIpInput.value;
let server_port = serverPortInput.value;
console.log('protocol: ', protocol);
console.log('server_ip: ', server_ip);
console.log('server_port: ', server_port);


let uri = protocol + server_ip + ':' + server_port;
console.log('uri', uri);
socket = new WebSocket(uri);

// Connection opened
socket.addEventListener('open', function(event) {
console.log('connected');
uploadBtn.disabled = false;
connectBtn.disabled = true;
connectBtn.innerHTML = 'Connected!';
});

// Connection closed
socket.addEventListener('close', function(event) {
console.log('disconnected');
uploadBtn.disabled = true;
connectBtn.disabled = false;
connectBtn.innerHTML = 'Click me to connect!';
});

// Listen for messages
socket.addEventListener('message', function(event) {
/* for streaming*/
let message = JSON.parse(event.data);
if (message.segment in recognition_text) {
recognition_text[message.segment] = message.text;
} else {
recognition_text.push(message.text);
}
let text_area = document.getElementById('results');
text_area.value = getDisplayResult();
text_area.scrollTop = text_area.scrollHeight; // auto scroll

console.log('Received message: ', event.data);

/* for non-streaming
document.getElementById('results').value = event.data;
socket.send('Done');
console.log('Sent Done');
socket.close();
*/
});
}

window.onload = (event) => {
console.log('page is fully loaded');
console.log('protocol', window.location.protocol);
console.log('port', window.location.port);
if (window.location.protocol == 'https:') {
document.getElementById('ws-protocol').textContent = 'wss://';
}
serverIpInput.value = window.location.hostname;
serverPortInput.value = window.location.port;
};

connectBtn.onclick = function() {
initWebSocket();
};

function send_header(n) {
const header = new ArrayBuffer(8);
// assume the uploaded wave is 16000 Hz
new DataView(header).setInt32(0, 16000, true /* littleEndian */);
new DataView(header).setInt32(4, n, true /* littleEndian */);
socket.send(new Int32Array(header, 0, 2));
}

function onFileChange() {
var files = document.getElementById('file').files;

if (files.length == 0) {
console.log('No file selected');
return;
}

console.log('files: ' + files);

const file = files[0];
console.log(file);
console.log('file.name ' + file.name);
console.log('file.type ' + file.type);
console.log('file.size ' + file.size);

let audioCtx = new AudioContext({sampleRate: 16000});

let reader = new FileReader();
reader.onload = function() {
console.log('reading file!');
audioCtx.decodeAudioData(reader.result, decodedDone);
};

function decodedDone(decoded) {
let typedArray = new Float32Array(decoded.length);
let float32_samples = decoded.getChannelData(0);
let buf = float32_samples.buffer

// Send 1024 audio samples per request.
//
// It has two purposes:
// (1) Simulate streaming
// (2) There is a limit on the number of bytes in the payload that can be
// sent by websocket, which is 1MB, I think. We can send a large
// audio file for decoding in this approach.
let n = 1024 * 4; // send this number of bytes per request.
console.log('buf length, ' + buf.byteLength);
send_header(buf.byteLength);
for (let start = 0; start < buf.byteLength; start += n) {
socket.send(buf.slice(start, start + n));
}
socket.send('Done');
console.log('Sent Done');
/*
socket.close();
*/
}

reader.readAsArrayBuffer(file);
}

const clearBtn = document.getElementById('clear');
clearBtn.onclick = function() {
console.log('clicked');
document.getElementById('results').value = '';
recognition_text = []
};
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,6 @@ <h3>Recognition from offline recordings</h3>
crossorigin="anonymous">
</script>

<script src="./js/offline_record.js"> </script>
<script src="./js/non_streaming_record.js"> </script>
</body>
</html>
68 changes: 68 additions & 0 deletions python-api-examples/web/non_streaming_upload.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8"></meta>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"></meta>

<!-- Bootstrap CSS -->
<link rel="stylesheet"
href="./css/bootstrap.min.css"
integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T"
crossorigin="anonymous">
</link>

<script src="./js/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>

<title>Next-gen Kaldi demo (Upload file for recognition)</title>
</head>


<body>
<div id="nav"></div>
<script>
$(function(){
$("#nav").load("nav-partial.html");
});
</script>

<h3>Recognition from a selected file</h3>
<div class="input-group mb-1">
<div class="input-group-prepend">
<button class="btn btn-block btn-primary" type="button" id="connect">Click me to connect</button>
</div>
<span class="input-group-text" id="ws-protocol">ws://</span>
<input type="text" id="server-ip" class="form-control" placeholder="Sherpa-onnx server IP, e.g., localhost" aria-label="sherpa-onnx server IP">
<span class="input-group-text">:</span>
<input type="text" id="server-port" class="form-control" placeholder="Sherpa-onnx server port, e.g., 6006" aria-label="sherpa-onnx server port">
</div>

<form>
<div class="mb-3">
<label for="file" class="form-label">Select file</label>
<input class="form-control" type="file" id="file" accept=".wav" onchange="onFileChange()" disabled="true"></input>
</div>

<div class="mb-3">
<label for="results" class="form-label">Recognition results</label>
<textarea class="form-control" id="results" rows="8"></textarea>
</div>

<button type="button" class="btn btn-primary btn-block" id="clear">Clear results</button>
</form>

<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="./js/popper.min.js"
integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1"
crossorigin="anonymous">
</script>

<script src="./js/bootstrap.min.js"
integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM"
crossorigin="anonymous">
</script>

<script src="./js/non_streaming_upload.js"> </script>
</body>
</html>
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ <h3>Recognition from a selected file</h3>
<textarea class="form-control" id="results" rows="8"></textarea>
</div>

<button class="btn btn-primary btn-block" id="clear">Clear results</button>
<button type="button" class="btn btn-primary btn-block" id="clear">Clear results</button>
</form>

<!-- Optional JavaScript -->
Expand All @@ -63,6 +63,6 @@ <h3>Recognition from a selected file</h3>
crossorigin="anonymous">
</script>

<script src="./js/upload.js"> </script>
<script src="./js/streaming_upload.js"> </script>
</body>
</html>
Loading