Sto provando a trasmettere l'audio dal microfono da 1 Android a un altro tramite WiFi. Dopo aver esaminato alcuni esempi, ho realizzato 2 applicazioni con una singola attività in ciascuna, 1 per acquisire e inviare audio e l'altra per ricevere.Streaming voce tra telefoni Android tramite WiFi
Ho utilizzato le classi Audiorecord e Audiotrack per acquisire e riprodurre. Tuttavia, sento solo alcuni suoni scoppiettanti (che ora si sono fermati dopo aver apportato alcune modifiche anche se sono tornato indietro)
L'attività per inviare la voce.
public class VoiceSenderActivity extends Activity {
private EditText target;
private TextView streamingLabel;
private Button startButton,stopButton;
public byte[] buffer;
public static DatagramSocket socket;
private int port=50005; //which port??
AudioRecord recorder;
//Audio Configuration.
private int sampleRate = 8000; //How much will be ideal?
private int channelConfig = AudioFormat.CHANNEL_CONFIGURATION_MONO;
private int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
private boolean status = true;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
target = (EditText) findViewById (R.id.target_IP);
streamingLabel = (TextView) findViewById(R.id.streaming_label);
startButton = (Button) findViewById (R.id.start_button);
stopButton = (Button) findViewById (R.id.stop_button);
streamingLabel.setText("Press Start! to begin");
startButton.setOnClickListener (startListener);
stopButton.setOnClickListener (stopListener);
}
private final OnClickListener stopListener = new OnClickListener() {
@Override
public void onClick(View arg0) {
status = false;
recorder.release();
Log.d("VS","Recorder released");
}
};
private final OnClickListener startListener = new OnClickListener() {
@Override
public void onClick(View arg0) {
status = true;
startStreaming();
}
};
public void startStreaming() {
Thread streamThread = new Thread(new Runnable() {
@Override
public void run() {
try {
int minBufSize = AudioRecord.getMinBufferSize(sampleRate, channelConfig, audioFormat);
DatagramSocket socket = new DatagramSocket();
Log.d("VS", "Socket Created");
byte[] buffer = new byte[minBufSize];
Log.d("VS","Buffer created of size " + minBufSize);
DatagramPacket packet;
final InetAddress destination = InetAddress.getByName(target.getText().toString());
Log.d("VS", "Address retrieved");
recorder = new AudioRecord(MediaRecorder.AudioSource.MIC,sampleRate,channelConfig,audioFormat,minBufSize);
Log.d("VS", "Recorder initialized");
recorder.startRecording();
while(status == true) {
//reading data from MIC into buffer
minBufSize = recorder.read(buffer, 0, buffer.length);
//putting buffer in the packet
packet = new DatagramPacket (buffer,buffer.length,destination,port);
socket.send(packet);
}
} catch(UnknownHostException e) {
Log.e("VS", "UnknownHostException");
} catch (IOException e) {
Log.e("VS", "IOException");
}
}
});
streamThread.start();
}
}
L'attività di ricevere voce
public class VoiceReceiverActivity extends Activity {
private Button receiveButton,stopButton;
public static DatagramSocket socket;
private AudioTrack speaker;
//Audio Configuration.
private int sampleRate = 8000; //How much will be ideal?
private int channelConfig = AudioFormat.CHANNEL_CONFIGURATION_MONO;
private int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
private boolean status = true;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
receiveButton = (Button) findViewById (R.id.receive_button);
stopButton = (Button) findViewById (R.id.stop_button);
findViewById(R.id.receive_label);
receiveButton.setOnClickListener(receiveListener);
stopButton.setOnClickListener(stopListener);
}
private final OnClickListener stopListener = new OnClickListener() {
@Override
public void onClick(View v) {
status = false;
speaker.release();
Log.d("VR","Speaker released");
}
};
private final OnClickListener receiveListener = new OnClickListener() {
@Override
public void onClick(View arg0) {
status = true;
startReceiving();
}
};
public void startReceiving() {
Thread receiveThread = new Thread (new Runnable() {
@Override
public void run() {
try {
DatagramSocket socket = new DatagramSocket(50005);
Log.d("VR", "Socket Created");
byte[] buffer = new byte[256];
//minimum buffer size. need to be careful. might cause problems. try setting manually if any problems faced
int minBufSize = AudioRecord.getMinBufferSize(sampleRate, channelConfig, audioFormat);
speaker = new AudioTrack(AudioManager.STREAM_MUSIC,sampleRate,channelConfig,audioFormat,minBufSize,AudioTrack.MODE_STREAM);
speaker.play();
while(status == true) {
try {
DatagramPacket packet = new DatagramPacket(buffer,buffer.length);
socket.receive(packet);
Log.d("VR", "Packet Received");
//reading content from packet
buffer=packet.getData();
Log.d("VR", "Packet data read into buffer");
//sending data to the Audiotrack obj i.e. speaker
speaker.write(buffer, 0, minBufSize);
Log.d("VR", "Writing buffer content to speaker");
} catch(IOException e) {
Log.e("VR","IOException");
}
}
} catch (SocketException e) {
Log.e("VR", "SocketException");
}
}
});
receiveThread.start();
}
}
ho usato Wireshark per verificare se i pacchetti vengono inviati e posso vedere i pacchetti. Tuttavia, la fonte è l'indirizzo MAC del dispositivo mittente e anche la destinazione è qualcosa come un indirizzo fisico. Non sono sicuro se questo è rilevante però.
Quindi qual è il problema?
Ci sono almeno tre problemi che devi affrontare: dati ritardati (o mancanti), throughput di dati complessivo e possibilità di frequenze di campionamento leggermente disadattate. La telefonia IP pratica deve avere un mezzo per gestire tutte e tre le cose. Gli orologi non corrispondenti sono sorprendentemente complessi: inizialmente è possibile introdurre un ritardo per fornire una tolleranza di bufferizzazione, ma se il mittente è più lento si utilizzerà il buffer e il ricevitore sarà affamato di dati; mentre se il mittente è più veloce il buffer finirà per traboccare con dati non riprodotti. –
Sono riuscito a farlo funzionare davvero. Non ha avuto un problema di frequenze non corrispondenti. Ritardo nei dati, sì. Aveva una specie di protocollo per abbinare gli orologi ricevitore/mittente. Alla fine ha funzionato, ma solo con un certo ritardo (che è aumentato con la distanza dal router wireless) – Alabhya
Ehi lì, ho implementato un'applicazione di test per il codice che hai sopra, facendo tutte le modifiche necessarie suggerite di seguito, ma ho ancora un problema . Non sto ottenendo comunicazioni tra i due telefoni senza problemi, ma non credo che il microfono stia registrando correttamente perché non sento alcun suono dall'altra parte. Hai forse un link ad una soluzione campione che potrei dare un'occhiata? – chuckliddell0