使用套接字(TCP)和服务从一个Android设备直播音频到其他设备

时间:2015-03-19 05:35:35

标签: android sockets service tcp audio-streaming

我正在尝试将音频从服务器流式传输到客户端(FYI,应用程序充当服务器和客户端,因此相同的应用程序可以双向通信)使用套接字和TCP。 我的应用程序在某个端口启动应用程序时打开一个serverSocket,因此它充当服务器。当服务器向客户端发送“开始”时,客户端上的服务启动并将语音记录在clinet上并将其发送回服务器(任何其他设备都可以执行相同操作,因为它们都具有ServerSocket Open并且也可以作为客户端运行)。在这里,我需要实时音频流黑白服务器和客户端。

我能够在客户端接收启动命令,startservice。客户端正在录制,我想发送回服务器,因为在服务器上打印收到的inputStream。它打印一些垃圾值。当我尝试将接收的字节数组转换为音频时,我得到了 W / AudioTrack(8259):在服务器上禁用了winsBuffer()轨道0xf3b00,重新启动

以下是我正在使用的代码

MainActivity.java

public class MainActivity extends Activity implements OnClickListener {

private Button pinger, sendFile;
private EditText otherIP, msg;
private TextView myIP, msgLog;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    pinger = (Button) findViewById(R.id.pingButton);
    sendFile = (Button) findViewById(R.id.sendFile);
    otherIP = (EditText) findViewById(R.id.otherIP);
    msg = (EditText) findViewById(R.id.msgToServer);
    myIP = (TextView) findViewById(R.id.myIP);
    msgLog = (TextView) findViewById(R.id.msgToLog);

    pinger.setOnClickListener(this);
    sendFile.setOnClickListener(this);
    myIP.setText("My IPs \n" + Utils.getIPAddress(true));
    otherIP.setText(Utils.getIPAddress(true));

    new OpenServerThread(this).start();
}

@Override
public void onClick(View v) {
    if (v.equals(pinger)) {
        new ControlCommands(this, otherIP.getText().toString(), 8080, msg
                .getText().toString(), "") {
            @Override
            protected void onPostExecute(Void result) {
                String s = msgLog.getText().toString().trim();
                msgLog.setText(s);
                msg.setText("");
                super.onPostExecute(result);
            }
        }.execute();
    }
 }
}

OpenServerThread.java

public class OpenServerThread extends Thread {

private Socket socket;
String msg;
private ServerSocket serverSocket;
private Context context;
private TextView t;

public OpenServerThread(Context context) {
    this.context = context;
    setPriority(1);
    t = (TextView) ((Activity) context).findViewById(R.id.msgToLog);
}

@Override
public void run() {
    System.out.println("opening socket...");
    DataInputStream din = null;

    try {
        serverSocket = new ServerSocket(8080);
        ((Activity) context).runOnUiThread(new Runnable() {
            @Override
            public void run() {
                t.setText("I'm waiting here: "
                        + serverSocket.getLocalPort());
            }
        });

        while (true) {
            socket = serverSocket.accept();
            // inputStream is the base class to read bytes from a stream
            // (network or file) as primitive Data type.
            din = new DataInputStream(socket.getInputStream());

            int length = din.readInt(); // read length of incoming message
            if (length > 0) {
                byte[] message = new byte[length];
                din.readFully(message, 0, message.length);
                msg = new String(message);


               /**
                * Here after receiving messege I am trying to convert byte
                * array to audio and this is main area of concern 
                **/

                if (message.length == length && length >5 ) {
                    System.out.println("Message: " + message.length);
                    playMp3(message);

                }

            }

            ((Activity) context).runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    t.setText(msg);
                }
            });

            // din.close();

            ((Activity) context).runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    if (msg.equals("start")) {
                        context.startService(new Intent(context,
                                MyService.class));
                        System.out.println("rec starting");
                    } else if (msg.equals("stop")) {
                        System.out.println("rec Stoping");
                        context.stopService(new Intent(context,
                                MyService.class));
                    } else {
                        System.out.println("some other msg");
                    }
                }
            });
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

 //This function is producing error I have mentioned above 
 private void playMp3(final byte[] mp3SoundByteArray) {
     int sampleRate = 44100;
     int bufferSize = AudioTrack.getMinBufferSize(sampleRate,
            AudioFormat.CHANNEL_CONFIGURATION_MONO,
            AudioFormat.ENCODING_PCM_16BIT);

     AudioTrack mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
            sampleRate, AudioFormat.CHANNEL_CONFIGURATION_MONO,
            AudioFormat.ENCODING_PCM_16BIT, bufferSize,
            AudioTrack.MODE_STREAM);
     mAudioTrack.write(mp3SoundByteArray, 0, mp3SoundByteArray.length);
     mAudioTrack.play();
 } 
}

ControlCommands.java

public class ControlCommands extends AsyncTask<Void, Void, Void> {
String dstAddress;
int dstPort;
String msgToServer;
String selectedFilePath;
Context context;

ControlCommands(Context context, String addr, int port, String msgTo,
        String selectedFilePath) {
    dstAddress = addr;
    dstPort = port;
    msgToServer = msgTo;
    this.selectedFilePath = selectedFilePath;
    this.context = context;
}

@Override
protected Void doInBackground(Void... arg0) {

    System.out.println("dst add: " + dstAddress + " : " + dstPort
            + " msgttoser: " + msgToServer);
    Socket socket = null;
    DataOutputStream dataOutputStream = null;
    DataInputStream dataInputStream = null;
    try {
        socket = new Socket(dstAddress, dstPort);

        if (selectedFilePath.equals("")) {
            dataOutputStream = new DataOutputStream(
                    socket.getOutputStream());
            dataInputStream = new DataInputStream(socket.getInputStream());

            dataOutputStream.writeInt(msgToServer.getBytes().length);
            dataOutputStream.write(msgToServer.getBytes());
        }
    } catch (UnknownHostException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return null;
 }
} 

MyService.java

public class MyService extends Service {
public byte[] buffer;
public static DatagramSocket socket;
AudioRecord recorder;

private int sampleRate = 44100;
private int channelConfig = AudioFormat.CHANNEL_CONFIGURATION_MONO;
private int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
int minBufSize = AudioRecord.getMinBufferSize(sampleRate, channelConfig,
        audioFormat);
private boolean status = true;
private static final String TAG = "MyService";

@Override
public IBinder onBind(Intent intent) {
    return null;
}

@Override
public void onCreate() {
    Toast.makeText(this, "My Service Created", Toast.LENGTH_LONG).show();
    Log.d(TAG, "onCreate");
    Toast.makeText(this, "recard Started Created", Toast.LENGTH_LONG)
            .show();
}

public void startStreaming(String Ip) {
    Thread streamThread = new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                //IP is correct this is where I have to send the data
                Socket socket = new Socket("192.168.1.105", 8080); 

                DataOutputStream dataOutputStream = new DataOutputStream(
                            socket.getOutputStream());

                recorder = new AudioRecord(MediaRecorder.AudioSource.MIC,
                        sampleRate, channelConfig, audioFormat,
                        minBufSize);
                Log.d("VS", "Recorder initialized");

                recorder.startRecording();

                while (status == true) {
                     buffer = new byte[minBufSize];
                    // reading data from MIC into buffer
                    minBufSize = recorder.read(buffer, 0, buffer.length);

                    dataOutputStream.writeInt(buffer.length); // write length of the message
                    dataOutputStream.write(buffer);

                    //System.out.println(new String(buffer).substring(0,4));
                    dataOutputStream.flush();

                    status = false;
                }
            } catch (UnknownHostException e) {
                Log.e("VS", "UnknownHostException");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    });
    streamThread.start();
}

 @Override
 public void onDestroy() {
     recorder.stop();
     recorder.release();
     Toast.makeText(this, "My Service Stopped", Toast.LENGTH_LONG).show();
     Log.d(TAG, "onDestroy");
 }

 @Override
 public void onStart(Intent intent, int startid) {
     startStreaming("");
     Toast.makeText(this, "My Service Started", Toast.LENGTH_LONG).show();
     Log.d(TAG, "onStart");
 }
}

0 个答案:

没有答案