Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Send Audio Stream from Android(Client) to C#(Server) using Websocket

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);
    }
like image 852
Sumit Rana Avatar asked Jun 22 '16 19:06

Sumit Rana


1 Answers

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.

like image 57
Sumit Rana Avatar answered Nov 15 '22 00:11

Sumit Rana