I am trying to send audio to the server. What I'm looking to accomplish is having a stream of bytes sent to the server. My current attempt is using SignalR. After a lot of issues with JSON parsing on the server (which I finally "fixed" by adding the Int8Array line).
Now I have the following errors:
[16:15:19 GMT-0500 (Eastern Standard Time)] SignalR: Invoking myhub.SendAudio
jquery.signalR-2.2.1.min.js:9 [16:15:19 GMT-0500 (Eastern Standard Time)] SignalR: Unclean disconnect from websocket: [no reason given].
jquery.signalR-2.2.1.min.js:9 [16:15:19 GMT-0500 (Eastern Standard Time)] SignalR: Invoking myhub.SendAudio
Then this over and over (about 11 times):
[15:06:54 GMT-0500 (Eastern Standard Time)] SignalR: Invoking myhub.SendAudio
WebSocket is already in CLOSING or CLOSED state.
And eventually:
[16:11:06 GMT-0500 (Eastern Standard Time)] SignalR: Closing the Websocket.
jquery.signalR-2.2.1.min.js:9 [16:11:06 GMT-0500 (Eastern Standard Time)] SignalR: Clearing hub invocation callbacks with error: Connection started reconnecting before invocation result was received..
jquery.signalR-2.2.1.min.js:9 [16:11:06 GMT-0500 (Eastern Standard Time)] SignalR: myhub.SendAudio failed to execute. Error: Connection started reconnecting before invocation result was received.
If I change the byte[] to a string, it works just fine. If I take out my "debugger;" it will repeat all of the errors after reconnecting. Only the last error triggers the debugger, the others don't
Here is the Javascript:
var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
var hub = $.connection.myHub;
$.connection.hub.logging = true;
$.connection.hub.start().done(function () {
// I know that I should leverage this method,
// but I am clicking a button to start recording for now, so it isn't an issue.
});
var recorderProcess = function (e) {
var left = e.inputBuffer.getChannelData(0);
var array = new Int8Array(left.buffer); // this is just the latest attempt
var obj = { buffer: array };
hub.server.sendAudio(obj).done(function (text) {
console.log(text);
txtResult.val(txtResult.val() + ' ' + text);
}).fail(function (error) {
debugger;
});
}
var initializeRecorder = function (stream) {
var context = audioCtx;
var audioInput = context.createMediaStreamSource(stream);
var bufferSize = 2048;
var recorder = context.createScriptProcessor(bufferSize, 1, 1);
recorder.onaudioprocess = recorderProcess;
audioInput.connect(recorder);
recorder.connect(context.destination);
}
$('#btnPlay').click(function () {
navigator.getUserMedia(session, initializeRecorder, onError);
}
Server Side Code:
public class AudioData {
[JsonProperty("buffer")]
public byte[] Buffer { get; set; }
}
public class MyHub : Hub {
public async Task<string> SendAudio(AudioData data) {
byte[] audioData = data.Buffer;
// I try and do things here, but I haven't been able to get it to work that far.
}
}
In Startup
var hubConfiguration = new HubConfiguration();
hubConfiguration.EnableDetailedErrors = true;
app.MapSignalR("/signalr", hubConfiguration);