Поиск по этому блогу

четверг, 15 июня 2017 г.

Пример записи аудио с паузой и востановлением записи

Это будет не большая заметка о том как лучше записывать аудио. Я для себя недавно открыл библиотеку PauseResumeAudioRecorder, оч крутая библиотека, позволяет выполнять все нужные функции для записи аудио, есть и запись, и пауза, и резум и стоп, чего собственно нет в стандартном AudioRecord'ере. Я на основе этой либы создал свою, немного подредактировал код под свои нужды, вывел амплитуду громкости и еще пару фич. Очень удобная библиотека в общем, можно ее кастомизировать под себя.

Если вам не нужны фичи что я создал под себя, то можете использовать библиотеку которая оригинальная, я же создал свои файлы библиотеки. Вот исходник PcmWavConverter и вот исходник рекордера PauseResumeAudioRecorder.
Вам нужно просто создать эти два файла у себя в проекте и обращаться к ним как к рекордеру.

Дальше я просто опишу как работать с этой библиотекой. И создам визуализатор записи.

Давайте создадим вьюху визуализации записи аудио, она у нас будет состоять из двух прогресбаров, в которые мы будем передавать амплитуду, и в зависимости от нее прогресс бар будет увеличиваться или уменьшаться. 

view_audio_visualization.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@android:color/darker_gray"
        android:paddingLeft="40dp"
        android:paddingRight="40dp"
        android:paddingTop="10dp"
        android:paddingBottom="10dp">

        <TextView
            android:text="Recording Level"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/textView25"
            android:textSize="18sp"
            android:gravity="center_horizontal" />

        <ProgressBar
            style="?android:attr/progressBarStyleHorizontal"
            android:layout_width="match_parent"
            android:id="@+id/progressBar1"
            android:layout_marginTop="10dp"
            android:max="5000"
            android:layout_height="6dp" />

        <ProgressBar
            style="?android:attr/progressBarStyleHorizontal"
            android:layout_width="match_parent"
            android:id="@+id/progressBar2"
            android:layout_weight="0.1"
            android:max="5000"
            android:layout_marginTop="10dp"
            android:layout_height="6dp" />
    </LinearLayout>

</LinearLayout>

А в нашей вьюхе мы просто опишем тот сценарий что я описал выше. 

AudioVisualizationView.java
import android.content.Context;
import android.util.AttributeSet;
import android.widget.LinearLayout;
import android.widget.ProgressBar;

import com.project.recordaudioexample.R;

import butterknife.BindView;
import butterknife.ButterKnife;

/**
 * Created by gleb on 6/15/17.
 */

public class AudioVisualizationView extends LinearLayout {

    @BindView(R.id.progressBar1)
    ProgressBar progressBar1;
    @BindView(R.id.progressBar2)
    ProgressBar progressBar2;

    public AudioVisualizationView(Context context) {
        super(context);
        init(context);
    }

    public AudioVisualizationView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public AudioVisualizationView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    private void init(Context context) {
        inflate(context, R.layout.view_audio_visualization, this);
        setOrientation(VERTICAL);
        ButterKnife.bind(this);
    }

    public void updateProgress(int amplitude) {
        progressBar1.setProgress(amplitude);
        progressBar2.setProgress(amplitude);
    }
}

Главный метод ради которого мы пишем эту вьюху в самом низу экрана, updateProgress просто сетит амплитуда в прогресбары. И все, это весь код вьюхи.

Дальше соберем все в MainActivity. Для начала создадим файл разметки главного экрана, на нем у нас будет 4 кнопки, запись, пауза, резум и стоп и AudioVisualizationView. Соотвественно по нажатию онных будут совершаться соответствующие действия. И AudioVisualizationView будет просто дергаться если вы будете производить какие-то звуки в микрофон :)

activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:orientation="horizontal">

        <com.project.recordaudioexample.audio.view.AudioVisualizationView
            android:id="@+id/audioVisualizationView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:gravity="center_horizontal"
        android:orientation="horizontal">

        <Button
            android:id="@+id/recordButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="onRecordClick"
            android:text="Record" />

        <Button
            android:id="@+id/pauseButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="onPauseClick"
            android:text="Pause" />

        <Button
            android:id="@+id/resumeButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="onResumeClick"
            android:text="Resume" />

        <Button
            android:id="@+id/stopButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="onStopClick"
            android:text="Stop" />

    </LinearLayout>

</RelativeLayout>

Ну а в активити мы просто опишем что мы хотим что бы было по клику на определенные кнопки. И в колбеке амплитуды сетим данные в визуализатор.

MainActivity.java
import android.os.Bundle;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;

import com.project.recordaudioexample.audio.PauseResumeAudioRecorder;
import com.project.recordaudioexample.audio.view.AudioVisualizationView;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;

public class MainActivity extends AppCompatActivity implements PauseResumeAudioRecorder.OnAmplitudeRunning {

    @BindView(R.id.audioVisualizationView)
    AudioVisualizationView audioVisualizationView;

    private PauseResumeAudioRecorder mediaRecorder;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);

        mediaRecorder = new PauseResumeAudioRecorder();
        mediaRecorder.setOnAmplitudeRunning(this);
        mediaRecorder.setAudioFile(Environment.getExternalStorageDirectory() + "/Record");
    }

    @Override
    public void onDestroy(){
        super.onDestroy();
        if (mediaRecorder.getCurrentState() == PauseResumeAudioRecorder.RECORDING_STATE || mediaRecorder.getCurrentState()==PauseResumeAudioRecorder.PAUSED_STATE) {
            mediaRecorder.stopRecording();
        }
    }

    @OnClick(R.id.recordButton)
    public void onRecordClick() {
        mediaRecorder.startRecording();
    }

    @OnClick(R.id.pauseButton)
    public void onPauseClick() {
        mediaRecorder.pauseRecording();
    }

    @OnClick(R.id.stopButton)
    public void onStopClick() {
        mediaRecorder.stopRecording();
    }

    @OnClick(R.id.resumeButton)
    public void onResumeClick() {
        mediaRecorder.resumeRecording();
    }

    @Override
    public void getAmplitude(double amplitude, int currentState) {
        audioVisualizationView.updateProgress((int) amplitude);
    }
}

А дальше нам еще надо в манифест добавить 3 пермишена которые позволят нам записывать аудио и писать файлы на флешку и читать с нее.

AndroidManifest.xml
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />


Вот собственно и все что нужно для создания програмки для записи аудио. Может кому-то пригодится мой опыт в этом.

Исходники:
GitHub