I am trying to send audio stream/wav file as a byte array from android to C# server, but not able to receive it properly, though I am able to receive a simple String.
C# server disconnects after few seconds, with protocol error as reason
protocol error: Code = 1002, I think when the file is large the frame size exceeds and web socket connection is lost. Is there a way out?
I also tried sending a wav file as byte array from android as following, removing the recording stream:
byte[] buffer = new byte[1024];
try {
FileInputStream fis = new FileInputStream(file);
while(true) {
int in = fis.read(buffer, 0, buffer.length);
if(in != -1) {
mWebSocket.send(buffer);
}else{
break;
}
}
}catch (Exception e) {
Log.d("Exception", e.toString());
}
Android Code:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
Button stopPlaying, send, record, stop;
private AudioRecord audiorecord;
private static int SAMPLER = 44100; //Sample Audio Rate
private int channelConfig = AudioFormat.CHANNEL_IN_MONO;
private int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
int minBufSize = AudioRecord.getMinBufferSize(SAMPLER, channelConfig, audioFormat);
private boolean status = true;
URI uri = URI.create("ws://ab1d04d2.ngrok.io");
private String outputFile = null;
private Thread senderThread = null;
private WebSocketClient mWebSocket;
private File file = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
file = new File(Environment.getExternalStorageDirectory(), "recording.wav");
setContentView(honeywell.rana.sumit.voicecontrol.R.layout.activity_main);
audiorecord = new AudioRecord(MediaRecorder.AudioSource.MIC, SAMPLER, channelConfig, audioFormat, minBufSize);
send = (Button) findViewById(R.id.send);
send.setOnClickListener(this);
stop = (Button) findViewById(R.id.stop);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.send:
AudioTask task = new AudioTask();
task.execute();
break;
case R.id.stop:
audiorecord.stop();
mWebSocket.close();
Log.d("Socket Closed", "");
default:
break;
}
}
public class AudioTask extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... params) {
try {
mWebSocket = new WebSocketClient(uri) {
@Override
public void onOpen(ServerHandshake handshakedata) {
Log.d("Connected: ", mWebSocket.getConnection().toString());
mWebSocket.send("hello!");
byte[] buffer = new byte[minBufSize];
audiorecord.startRecording();
while (true) {
int number = audiorecord.read(buffer, 0, minBufSize);
for (int i = 0; i < number; i++) {
mWebSocket.send(buffer);
}
}
}
@Override
public void onMessage(String message) {
Log.d("Received: ", message);
}
@Override
public void onClose(int code, String reason, boolean remote) {
Log.d("Closed", "Code = " + code + ", Reason: " + reason);
}
@Override
public void onError(Exception ex) {
Log.d("Error: ", ex.toString());
}
};
mWebSocket.connect();
} catch (Exception e) {
Log.d("Exception: ", e.toString());
}
return null;
}
}
}
C# Code:
namespace ChatServer
{
class Program
{
static WaveOut waveOut;
static BufferedWaveProvider bufferedWaveProvider = null;
private static WebSocketServer appServer = new WebSocketServer();
static void Main(string[] args)
{
Console.WriteLine("Press any key to start the WebSocketServer!");
Console.ReadKey();
Console.WriteLine();
waveOut = new WaveOut();
bufferedWaveProvider = new BufferedWaveProvider(new WaveFormat(44100, 16, 2));
waveOut.Init(bufferedWaveProvider);
waveOut.Play();
appServer.NewMessageReceived += new SessionHandler<WebSocketSession, string>(appServer_NewMessageReceived);
appServer.NewDataReceived += new SessionHandler<WebSocketSession, byte[]>(appServer_NewDataReceived);
appServer.NewSessionConnected += AppServer_NewSessionConnected;
appServer.SessionClosed += new SessionHandler<WebSocketSession, CloseReason>(appServer_SessionClosed);
//Setup the appServer
if (!appServer.Setup(80)) //Setup with listening port
{
Console.WriteLine("Failed to setup!");
Console.ReadKey();
return;
}
//Try to start the appServer
if (!appServer.Start())
{
Console.WriteLine("Failed to start!");
Console.ReadKey();
return;
}
Console.WriteLine("The server started successfully, press key 'q' to stop it!");
while (Console.ReadKey().KeyChar != 'q')
{
Console.WriteLine();
continue;
}
//Stop the appServer
appServer.Stop();
Console.WriteLine();
Console.WriteLine("The server was stopped!");
Console.ReadKey();
}
private static void AppServer_NewSessionConnected(WebSocketSession session)
{
Console.WriteLine("New Client connected: " + session.SessionID);
}
static void appServer_SessionClosed(WebSocketSession session, CloseReason reason)
{
Console.WriteLine(reason);
}
static void appServer_NewDataReceived(WebSocketSession session, byte[] value)
{
bufferedWaveProvider.AddSamples(value, 0, value.Length);
}
static void appServer_NewMessageReceived(WebSocketSession session, string message)
{
//Send the received message back
session.Send("Server: " + message);
Console.WriteLine(message);
}
I got it working finally, it was just a minute problem. I just reduced the buffer size in android to 64/128/512 and now it's working perfectly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With