我正在尝试将音频从服务器流式传输到客户端(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");
}
}