studio programacion herramientas fundamentos con avanzado aplicaciones android audio stream voice

programacion - manual de android en pdf



Transmisión de voz entre teléfonos Android a través de WiFi (3)

Debe considerar cuidadosamente su uso de UDP (clase DatagramSocket) como su protocolo de red.

UDP es un protocolo liviano que no garantiza mantener el orden de los paquetes recibidos. Esto puede ser parte de la razón por la cual el audio está distorsionado. Un paquete recibido fuera de servicio dará como resultado que el paquete de audio se reproduzca fuera de servicio. En el límite de estos paquetes fuera de secuencia, escuchará clics / pops donde la muestra de audio está efectivamente dañada. Además de esto, no se garantiza que los paquetes UDP se entreguen con éxito. Cualquier paquete descartado obviamente se agregará a cualquier garbling o distorsión que se escuche.

TCP (clase Socket) sería una mejor opción para una calidad de audio óptima. TCP es un protocolo más robusto que mantendrá el orden en que se reciben los paquetes. También tiene una comprobación de errores incorporada y volverá a enviar los paquetes descartados. Sin embargo, debido a esta funcionalidad atencional, TCP tiene una sobrecarga de red más alta.

Comencé esta respuesta diciendo que debes considerar cuidadosamente qué protocolo usas. Esto se debe a que hay un caso para usar dependiendo de lo que es importante para usted.

Si desea una reproducción de latencia ultra baja pero está feliz de sacrificar la calidad de audio, UDP funcionará. Sin embargo, llevará algo de experimentación encontrar el mejor tampón y tamaño de muestra.

Si desea la mejor reproducción de audio posible con cero distorsión, pero está dispuesto a introducir un poco más de latencia, entonces TCP es el camino a seguir.

No puedo decir cuánto más latencia TCP agregaría. Pero es posible que se pueda implementar sin afectar la experiencia del usuario. La única manera de descubrirlo es probarlo y ver.

Estoy tratando de transmitir audio desde el micrófono de 1 Android a otro a través de WiFi. Después de ver algunos ejemplos hice 2 aplicaciones con una sola actividad en cada una, 1 para capturar y enviar audio y la otra para recibir.

He usado las clases Audiorecord y Audiotrack para capturar y jugar. Sin embargo, acabo de escuchar un sonido crujiente (que ahora se detuvo después de que hice algunos cambios, aunque volví)

La actividad para enviar voz.

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(); } }

La actividad para recibir voz

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(); } }

Usé wireshark para verificar si los paquetes se están enviando y puedo ver los paquetes. Sin embargo, la fuente es la dirección MAC del dispositivo de envío y el destino también es algo así como una dirección física. Sin embargo, no estoy seguro de si esto es relevante.

Entonces, ¿cuál es el problema?


Hola, hay una biblioteca de código abierto llamada "Libstreaming" que se utiliza para transmitir voz / video a través de la red mediante WIFI. Solo échale un vistazo:

https://github.com/fyhertz/libstreaming

También hay algunos ejemplos proporcionados, amablemente eche un vistazo a él:

https://github.com/fyhertz/libstreaming-examples

He utilizado la biblioteca para transmitir audio RTSP a través de la red, espero que pueda ser útil.


Trataría de dividir el problema en Tres partes.

Parte 1

Asegúrese de que la conexión de socket funciona bien al comentar todo lo relacionado con el audio

Parte 2

Envíe simplemente un mensaje de texto arbitrario [ Hello WiFi ] del remitente, y luego recíbalo e imprímalo en la aplicación del lado del receptor.

Parte 3

Si la grabadora realmente está funcionando? intenta probar tu grabación en un proyecto separado para ver si funciona correctamente o no.

Use this código para capturar el micrófono y reproducirlo.

Mi experiencia

Una vez trabajé en un proyecto similar y para probarlo, lo que hice fue después de grabar. Escribí los datos de audio grabados como un archivo en la tarjeta SD.

(Sería audio en bruto, por lo que la mayoría de los reproductores de música no podrán reproducirlo ... mPlayer debería jugarlo, supongo)