Diferencia entre revisiones de «PDM Avanzado Captura de Audio»
| Línea 1: | Línea 1: | ||
==Introducion== | ==Introducion== | ||
| − | Nesta | + | Con esta clase podemos capturar '''audio''' ou '''vídeo'''. |
| + | |||
| + | |||
| + | Nesta sección imos aprender como capturar audio dende Android. | ||
A clase que imos utilizar é a '''[http://developer.android.com/reference/android/media/MediaRecorder.html Clase MediaRecorder]'''. | A clase que imos utilizar é a '''[http://developer.android.com/reference/android/media/MediaRecorder.html Clase MediaRecorder]'''. | ||
Revisión del 15:03 12 nov 2019
Introducion
Con esta clase podemos capturar audio ou vídeo.
Nesta sección imos aprender como capturar audio dende Android.
A clase que imos utilizar é a Clase MediaRecorder.
Podedes ver os formatos de audio soportados en: http://developer.android.com/guide/appendix/media-formats.html
Nota: Poderíamos usar a clase AudioRecord pero como non imos procesar e analizar o audio capturado e polo tanto non a usaremos.
Para facelo necesitaremos engadir unha serie de permisos ao arquivo AndroidManifiest.xml.
- Permiso para capturar audio.
1 <uses-permission android:name="android.permission.RECORD_AUDIO"/>
- Permiso para gardar o audio capturado na tarxeta SD.
1 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
IMPORTANTE: A partires da API 23 (Android 6), Android incorpora outro nivel de seguridade, de tal forma que agora, a maiores, teremos que solicitar dito permiso a nivel de programación. Máis información de como facelo neste enlace.
Clase MediaRecorder
Os pasos que temos que dar para capturar audio son os seguintes:
- Crear un obxecto da clase MediaRecorder.
1 private MediaRecorder mediaRecorder;
2 ...........
3 mediaRecorder = new MediaRecorder();
- Establecer de onde vén a fonte de audio. O normal é que sexa do MIC da cámara web. Isto se fai chamando ó método setAudioSource(fonte) onde fonte é unha constante que atopades en MediaRecorder.AudioSource.XXXXX.
1 mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
- Establecer o formato de saída, chamando ó método setOutputFormat(formato) onde formato é unha constante que se atopa en MediaRecorder.OutputFormat.XXX
1 mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
A columna de Supported File Type indica o formato de saída. No noso caso usaremos MediaRecorder.OutputFormat.TREE_GPP.
- Optativo: Establecer o tempo máximo de gravación chamando o método setMaxDuration(int mseg) do obxecto MediaRecorder.
Nos imos poñer 10000 (10 segundos).
1 mediaRecorder.setMaxDuration(10000);
- Optativo: Indicar a tasa de bit´s, chamando ó método setAudioEncodingBitRate(int valor).
Os permitidos o tedes no na imaxe anterior.
Nota: A cantidade de bit´s vai establecer a calidade do audio capturado.
Algúns valores típicos:
- Tasas de bits de compresión a MP3:
- 4 kbit/s Mínimo para recoñecer a fala.
- 8 kbit/s Calidade telefónica convencional
- 32 kbit/s Radio AM
- 96 kbit/s Radio FM
- 128 kbit/s Son calidade semi CD, muy común en MP3
- 192 kbit/s Son calidade CD en formato MP3
- 320 kbit/s Máxima calidade para formato MP3
Nos imos probar con 32 * 1024 = 32768
1 mediaRecorder.setAudioEncodingBitRate(32768);
- Optativo: Indicar a frecuencia de muestreo, chamando ó método setAudioSamplingRate(int valor).
ATENCION: No emulador este valor non pode ser superior a 8000.
Máis información: http://es.wikipedia.org/wiki/Frecuencia_de_muestreo
Un exemplo, no caso de calidade CD o simplerate é de 44,1Khz. No noso caso o valor estará limitado pola táboa de formatos de audio. Por exemplo AAC está limitado entre 8Khz e 96Khz, AMR_NB só a 8Khz e AMR_WB a 16Khz.
Nos imos probar con 8000 (8Khz) pola limitación do emulador.
1 mediaRecorder.setAudioSamplingRate(8000); // No emulador só 8000
- Indicar a codificación de audio utilizada chamando ó método setAudioEncoder(método) onde método é unha constante que se atopa en MediaRecorder.AudioEncoder.XXX.
No noso caso imos utilizar MediaRecorder.AudioEncoder.AAC.
1 mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
- Indicar o arquivo a gravar, indicando a ruta nome e extensión do arquivo, chamando ó método setOutputFile(arquivogravar).
Aquí temos varias posibilidades. Unha delas é darlle coma valor un String no que vai a ruta e o nome de arquivo e extensión. A ruta será algún cartafol da SDCARD. Para obter esa ruta faremos uso da clase Environment.
Para saber onde gardar o arquivo tedes que facer uso da clase Environment: http://developer.android.com/reference/android/os/Environment.html
Exemplos:
1 Environment.getExternalStorageDirectory().getAbsolutePath()
- Con isto obtemos a ruta a SDCARD (raíz).
1 String state = Environment.getExternalStorageState(); 2 if(!state.equals(Environment.MEDIA_MOUNTED)){ 3 // A TARXETA NON ESTA MONTADA 4 }
- Con isto sabemos se a tarxeta SD está montada.
Nota: Tamén podemos crear a ruta na SDCARD, facendo uso de obxectos da clase File, ou comprobando se existe o cartafol. O veremos máis adiante.
1 private String arquivoGravar;
2 ................
3 String timeStamp = DateFormat.getDateTimeInstance().format(new Date()).replaceAll(":", "").replaceAll("/", "_") .replaceAll(" ", "_");
4
5 arquivoGravar = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC) + timeStamp + ".3gp";
6
7 mediaRecorder.setOutputFile(arquivoGravar);
Neste exemplo creamos un nome para o arquivo gravado baseado na data-hora e o vai gardar no cartafol da SD Externa que o S.O. reserva para gardar música.
- Chamar ó método prepare(). Pode producir excepcións (debe ir con try...catch).
1 mediaRecorder.prepare();
- Chamar ó método start().
1 mediaRecorder.start();
Neste intre se procede a gravar no cartafol indicado. A gravación non parará ata que chamemos ó método stop do MediaRecorder ou se acade o tempo máximo de gravación.
É importante seguir a orden, xa que por exemplo, a chamada a setAudioEncoder non pode ir antes de setOutputFormat (mirade o diagrama de estados seguinte).
Ó igual que o MediaPlayer, o MediaRecorder ten un diagrama de estados que xa non debería ter dificultade en entenderse:
Cando rematemos de gravar (por tempo) ou se paramos nos premendo o botón correspondente se recomenda liberar os recursos do MediaRecorder.
O faremos así:
- Chamando o método stop.
- Chamando o método release.
- Igualando a null o obxecto da clase MediaRecorder.
Tamén deberemos liberar os recursos se cambiamos de aplicación ou se a pechamos.
Caso práctico
O obxectivo desta práctica é gravar un arquivo de audio no cartafol da SD Externa reservado á música. Ó premer o botón Gravar amosaremos unha caixa de diálogo indicando que se está a gravar e o saír de dita caixa pararemos de gravar. Ó premer o botón Reproducir reproduciremos o arquivo gardado.
Creamos a Activity
- Nome do proxecto: UD6_03_MultimediaGravador
- Nome da activity: UD6_03_MultimediaGravador.java
Código do layout xml
Nota: Por motivos de tempo para o alumnado o deseño non fai uso de constantes externas definidas no cartafol values. Queda claro que esta debería ser a opción escollida para o deseño das Interfaces de Usuario.
1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
2 xmlns:tools="http://schemas.android.com/tools"
3 android:layout_width="match_parent"
4 android:layout_height="match_parent"
5 tools:context="${relativePackage}.${activityClass}" >
6
7 <Button
8 android:id="@+id/UD6_03_btnGravar"
9 android:layout_width="wrap_content"
10 android:layout_height="wrap_content"
11 android:layout_alignParentTop="true"
12 android:layout_centerHorizontal="true"
13 android:text="GRAVAR AUDIO" />
14
15 <Button
16 android:id="@+id/UD6_03_btnReproducir"
17 android:layout_width="wrap_content"
18 android:layout_height="wrap_content"
19 android:layout_below="@+id/UD6_03_btnGravar"
20 android:layout_centerHorizontal="true"
21 android:layout_marginTop="26dp"
22 android:text="REPRODUCIR AUDIO" />
23 </RelativeLayout>
Código da clase UD6_03_MultimediaGravador
Obxectivo: Amosar como gravar un arquivo de audio.
1 import java.io.File;
2 import java.text.DateFormat;
3 import java.util.Date;
4
5 import android.app.Activity;
6 import android.app.AlertDialog;
7 import android.content.DialogInterface;
8 import android.media.AudioManager;
9 import android.media.MediaPlayer;
10 import android.media.MediaRecorder;
11 import android.os.Bundle;
12 import android.os.Environment;
13 import android.view.View;
14 import android.view.View.OnClickListener;
15 import android.widget.Button;
16 import android.widget.Toast;
17
18 public class UD6_03_MultimediaGravador extends Activity {
19
20 private MediaRecorder mediaRecorder;
21 private String arquivoGravar;
22
23
24 private void abrirDialogo(String tipo){
25 if (tipo == "GRAVAR") {
26 AlertDialog.Builder dialog = new AlertDialog.Builder(this)
27 .setMessage("GRAVANDO").setPositiveButton(
28 "PREME PARA PARAR",
29 new DialogInterface.OnClickListener() {
30
31 @Override
32 public void onClick(DialogInterface dialog,
33 int which) {
34 // TODO Auto-generated method stub
35 mediaRecorder.stop();
36 mediaRecorder.release();
37 mediaRecorder = null;
38 }
39 });
40 dialog.show();
41 }
42
43 if (tipo == "REPRODUCIR") {
44
45 if ((arquivoGravar==null) | arquivoGravar=="") return;
46 File arquivo = new File(arquivoGravar);
47 if (!arquivo.exists()) return;
48
49 final MediaPlayer mediaPlayer = new MediaPlayer();
50 try {
51 mediaPlayer.setDataSource(arquivoGravar);
52 mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
53 mediaPlayer.prepare();
54 mediaPlayer.start();
55 } catch (Exception e) {
56 Toast.makeText(getApplicationContext(),
57 "ERRO:" + e.getMessage(), Toast.LENGTH_LONG).show();
58 }
59
60 AlertDialog.Builder dialog = new AlertDialog.Builder(this)
61 .setMessage("REPRODUCINDO").setPositiveButton(
62 "PREME PARA PARAR",
63 new DialogInterface.OnClickListener() {
64
65 @Override
66 public void onClick(DialogInterface dialog,
67 int which) {
68 // TODO Auto-generated method stub
69 mediaPlayer.stop();
70 mediaPlayer.release();
71 }
72 });
73 dialog.show();
74
75 }
76
77 }
78
79 private void xestionarEventos(){
80
81 Button btnGravar = (Button)findViewById(R.id.UD6_03_btnGravar);
82 btnGravar.setOnClickListener(new OnClickListener() {
83
84 @Override
85 public void onClick(View v) {
86 // TODO Auto-generated method stub
87 String timeStamp = DateFormat.getDateTimeInstance().format(
88 new Date()).replaceAll(":", "").replaceAll("/", "_")
89 .replaceAll(" ", "_");
90
91 mediaRecorder = new MediaRecorder();
92 arquivoGravar = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC) + timeStamp + ".3gp";
93 mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
94 mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
95 mediaRecorder.setMaxDuration(10000);
96 mediaRecorder.setAudioEncodingBitRate(32768);
97 mediaRecorder.setAudioSamplingRate(8000); // No emulador só 8000 coma
98 mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
99 mediaRecorder.setOutputFile(arquivoGravar);
100 try {
101 mediaRecorder.prepare();
102 } catch (Exception e) {
103 // TODO Auto-generated catch block
104 mediaRecorder.reset();
105 }
106 mediaRecorder.start();
107 abrirDialogo("GRAVAR");
108
109
110 }
111 });
112
113 Button btnReproducir = (Button)findViewById(R.id.UD6_03_btnReproducir);
114 btnReproducir.setOnClickListener(new OnClickListener() {
115
116 @Override
117 public void onClick(View v) {
118 // TODO Auto-generated method stub
119 abrirDialogo("REPRODUCIR");
120 }
121 });
122
123
124 }
125
126 @Override
127 protected void onCreate(Bundle savedInstanceState) {
128 super.onCreate(savedInstanceState);
129 setContentView(R.layout.activity_ud6_03__multimedia_gravador);
130
131 xestionarEventos();
132
133 }
134 }
- Liña 20: Definimos o MediaRecorder.
- Liña 21: Propiedade que garda o nome e ruta do arquivo gravado. Necesario para cando prememos o botón de reproducir.
- Liñas 25-41: Diálogo que aparece cando prememos sobre o botón de Gravar. Se prememos o botón de Aceptar dentro do diálogo paramos de gravar e liberamos o MediaRecorder.
- Liñas 43-75: Diálogo que aparece cando prememos sobre o botón de Reproducir. Xa visto no punto anterior desta Unidade Didáctica.
- Liñas 91-107: Xestión do evento click sobre o botón de gravar. Preparamos o MediaRecorder e chamamos a abrir o diálogo de gravación.
- Liñas 117-120: Xestión do evento click sobre o botón de reproducir. Abrimos o diálogo de Reproducir.
-- Ángel D. Fernández González e Carlos Carrión Álvarez -- (2014).
