Android: Grabación de audio con visualización de nivel de voz

Necesito crear una aplicación android que es para la grabación de voz mientras muestra la voz (sonido) de visualización de nivel.

Ya he creado una aplicación de grabación de audio, pero no puedo añadir a ella la visualización de nivel de sonido. ¿Cómo puedo hacerlo?

Por favor, alguien me ayude a dar una sugerencia o una muestra tutoriales enlace o código.

Cree un xml activity_recording.xml como este.

<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="180dp" android:layout_alignParentBottom="true" android:background="#231f20" > <ali.visualiser.VisualizerView android:id="@+id/visualizer" android:layout_width="220dp" android:layout_height="75dp" android:layout_centerHorizontal="true" android:layout_margin="5dp" /> <TextView android:id="@+id/txtRecord" android:layout_width="wrap_content" android:layout_height="40dp" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:layout_marginBottom="25dp" android:gravity="center" android:text="Start Recording" android:textColor="@android:color/white" android:textSize="30sp" /> </RelativeLayout> 

Cree un visualizador personalizado como se muestra a continuación.

 package ali.visualiser; import java.util.ArrayList; import java.util.List; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.util.AttributeSet; import android.view.View; public class VisualizerView extends View { private static final int LINE_WIDTH = 1; // width of visualizer lines private static final int LINE_SCALE = 75; // scales visualizer lines private List<Float> amplitudes; // amplitudes for line lengths private int width; // width of this View private int height; // height of this View private Paint linePaint; // specifies line drawing characteristics // constructor public VisualizerView(Context context, AttributeSet attrs) { super(context, attrs); // call superclass constructor linePaint = new Paint(); // create Paint for lines linePaint.setColor(Color.GREEN); // set color to green linePaint.setStrokeWidth(LINE_WIDTH); // set stroke width } // called when the dimensions of the View change @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { width = w; // new width of this View height = h; // new height of this View amplitudes = new ArrayList<Float>(width / LINE_WIDTH); } // clear all amplitudes to prepare for a new visualization public void clear() { amplitudes.clear(); } // add the given amplitude to the amplitudes ArrayList public void addAmplitude(float amplitude) { amplitudes.add(amplitude); // add newest to the amplitudes ArrayList // if the power lines completely fill the VisualizerView if (amplitudes.size() * LINE_WIDTH >= width) { amplitudes.remove(0); // remove oldest power value } } // draw the visualizer with scaled lines representing the amplitudes @Override public void onDraw(Canvas canvas) { int middle = height / 2; // get the middle of the View float curX = 0; // start curX at zero // for each item in the amplitudes ArrayList for (float power : amplitudes) { float scaledHeight = power / LINE_SCALE; // scale the power curX += LINE_WIDTH; // increase X by LINE_WIDTH // draw a line representing this item in the amplitudes ArrayList canvas.drawLine(curX, middle + scaledHeight / 2, curX, middle - scaledHeight / 2, linePaint); } } } 

Cree la clase RecordingActivity como se indica a continuación.

Paquete ali.visualiser;

 import java.io.File; import java.io.IOException; import android.app.Activity; import android.media.MediaRecorder; import android.media.MediaRecorder.OnErrorListener; import android.media.MediaRecorder.OnInfoListener; import android.os.Bundle; import android.os.Environment; import android.os.Handler; import android.view.View; import android.view.View.OnClickListener; import android.widget.TextView; public class RecordingActivity extends Activity { public static final String DIRECTORY_NAME_TEMP = "AudioTemp"; public static final int REPEAT_INTERVAL = 40; private TextView txtRecord; VisualizerView visualizerView; private MediaRecorder recorder = null; File audioDirTemp; private boolean isRecording = false; private Handler handler; // Handler for updating the visualizer // private boolean recording; // are we currently recording? @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_recording); visualizerView = (VisualizerView) findViewById(R.id.visualizer); txtRecord = (TextView) findViewById(R.id.txtRecord); txtRecord.setOnClickListener(recordClick); audioDirTemp = new File(Environment.getExternalStorageDirectory(), DIRECTORY_NAME_TEMP); if (audioDirTemp.exists()) { deleteFilesInDir(audioDirTemp); } else { audioDirTemp.mkdirs(); } // create the Handler for visualizer update handler = new Handler(); } OnClickListener recordClick = new OnClickListener() { @Override public void onClick(View v) { if (!isRecording) { // isRecording = true; txtRecord.setText("Stop Recording"); recorder = new MediaRecorder(); recorder.setAudioSource(MediaRecorder.AudioSource.MIC); recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); recorder.setOutputFile(audioDirTemp + "/audio_file" + ".mp3"); OnErrorListener errorListener = null; recorder.setOnErrorListener(errorListener); OnInfoListener infoListener = null; recorder.setOnInfoListener(infoListener); try { recorder.prepare(); recorder.start(); isRecording = true; // we are currently recording } catch (IllegalStateException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } handler.post(updateVisualizer); } else { txtRecord.setText("Start Recording"); releaseRecorder(); } } }; private void releaseRecorder() { if (recorder != null) { isRecording = false; // stop recording handler.removeCallbacks(updateVisualizer); visualizerView.clear(); recorder.stop(); recorder.reset(); recorder.release(); recorder = null; } } public static boolean deleteFilesInDir(File path) { if( path.exists() ) { File[] files = path.listFiles(); if (files == null) { return true; } for(int i=0; i<files.length; i++) { if(files[i].isDirectory()) { } else { files[i].delete(); } } } return true; } @Override protected void onDestroy() { super.onDestroy(); releaseRecorder(); } // updates the visualizer every 50 milliseconds Runnable updateVisualizer = new Runnable() { @Override public void run() { if (isRecording) // if we are already recording { // get the current amplitude int x = recorder.getMaxAmplitude(); visualizerView.addAmplitude(x); // update the VisualizeView visualizerView.invalidate(); // refresh the VisualizerView // update in 40 milliseconds handler.postDelayed(this, REPEAT_INTERVAL); } } }; } 

Resultado

Así es como se ve: https://www.youtube.com/watch?v=BoFG6S02GH0

Cuando llega al final, la animación continúa como se esperaba: borrando el principio del gráfico.

Si está utilizando la clase MediaRecorder y la visualización basada en la amplitud de pico está bien, puede utilizar el método getMaxAmplitude () para realizar una sondeo continua de la "amplitud absoluta máxima que se muestreó desde la última llamada".
Escala que la amplitud hacia abajo en un índice que determina cuántas barras de volumen gráficas de su aplicación para iluminar y que está establecido.

Consulta este enlace: http://code.google.com/p/android-labs/source/browse/trunk/NoiseAlert/src/com/google/android/noisealert/SoundMeter.java

Graba el audio en / dev / null y comprueba el volumen. Pero puede cambiar el nombre de archivo para mantener el sonido grabado.

Me gusta la respuesta de Ali, pero aquí hay una versión más sencilla que funciona mucho mejor.

Lanzé mi RecordingActivity y lo establecí en pantalla completa, pero puede crear un recurso de diseño o agregar la vista en cualquier lugar.

GrabaciónActividad con pantalla completa

 public class RecordingActivity extends Activity { private VisualizerView visualizerView; private MediaRecorder recorder = new MediaRecorder(); private Handler handler = new Handler(); final Runnable updater = new Runnable() { public void run() { handler.postDelayed(this, 1); int maxAmplitude = recorder.getMaxAmplitude(); if (maxAmplitude != 0) { visualizerView.addAmplitude(maxAmplitude); } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_recording); visualizerView = (VisualizerView) findViewById(R.id.visualizer); try { recorder.setAudioSource(MediaRecorder.AudioSource.MIC); recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); recorder.setOutputFile("/dev/null"); recorder.prepare(); recorder.start(); } catch (IllegalStateException | IOException ignored) { } } @Override protected void onDestroy() { super.onDestroy(); handler.removeCallbacks(updater); recorder.stop(); recorder.reset(); recorder.release(); } @Override public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); handler.post(updater); } } 

El método onDraw de la clase view debe ser lo más rápido posible.

 public class VisualizerView extends View { private static final int MAX_AMPLITUDE = 32767; private float[] amplitudes; private float[] vectors; private int insertIdx = 0; private Paint pointPaint; private Paint linePaint; private int width; private int height; public VisualizerView(Context context, AttributeSet attrs) { super(context, attrs); linePaint = new Paint(); linePaint.setColor(Color.GREEN); linePaint.setStrokeWidth(1); pointPaint = new Paint(); pointPaint.setColor(Color.BLUE); pointPaint.setStrokeWidth(1); } @Override protected void onSizeChanged(int width, int h, int oldw, int oldh) { this.width = width; height = h; amplitudes = new float[this.width * 2]; // xy for each point across the width vectors = new float[this.width * 4]; // xxyy for each line across the width } /** * modifies draw arrays. cycles back to zero when amplitude samples reach max screen size */ public void addAmplitude(int amplitude) { invalidate(); float scaledHeight = ((float) amplitude / MAX_AMPLITUDE) * (height - 1); int ampIdx = insertIdx * 2; amplitudes[ampIdx++] = insertIdx; // x amplitudes[ampIdx] = scaledHeight; // y int vectorIdx = insertIdx * 4; vectors[vectorIdx++] = insertIdx; // x0 vectors[vectorIdx++] = 0; // y0 vectors[vectorIdx++] = insertIdx; // x1 vectors[vectorIdx] = scaledHeight; // y1 // insert index must be shorter than screen width insertIdx = ++insertIdx >= width ? 0 : insertIdx; } @Override public void onDraw(Canvas canvas) { canvas.drawLines(vectors, linePaint); canvas.drawPoints(amplitudes, pointPaint); } } 
  • ¿Qué es un método de conveniencia en Java?
  • Android error en tutorial no puede encontrar la variable de símbolo activity_display_message
  • No se pudo iniciar sesión. Compruebe la conexión de red e inténtelo de nuevo.
  • Problema de zona horaria en Android
  • Programaticamente silenciar un Android
  • Prueba de objetos JSON nulos en Java / Android
  • ¿Cómo puedo cambiar el comportamiento del modo de avión de Android para que no apague la radio celular?
  • La clase de prueba de Android falla al compilar en eclipse con error de "falta de coincidencia vinculada"
  • Androide. OnEditorAction nunca llamado
  • Twitter aplicación sólo la autenticación java android con twitter4j
  • ¿Cómo ejecutar y mostrar el resultado de un comando shell ssh con JSch?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.