Android-语音录制和播放

新一
2022-08-18 / 0 评论 / 57 阅读 / 正在检测是否收录...

效果图

l6yrl8f6.png
l6yrluac.png
l6yrlgyn.png

语音工厂封装

package com.element.wisdomclassbrand.util;

import android.media.MediaRecorder;

import java.io.File;
import java.io.IOException;

/**
 * 语音工厂
 */
public class AudioRecorderHelper {

    public static MediaRecorder getAudioRecorder(File cacheFile) {
        MediaRecorder recorder = new MediaRecorder();
        recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
        recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
        recorder.setOutputFile(cacheFile.getAbsolutePath());

        try {
            recorder.prepare();
            return recorder;
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }

    public static File getCacheFile(String cachePath) {
        File dir = new File(cachePath);
        if(!dir.exists()) {
            dir.mkdirs();
        }
        return new File(cachePath + System.currentTimeMillis() + ".aac");
    }
}

调用

package com.element.wisdomclassbrand.ui.fragment;

import android.annotation.SuppressLint;
import android.content.Context;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.view.View;

import androidx.annotation.NonNull;

import com.element.wisdomclassbrand.R;
import com.element.wisdomclassbrand.databinding.FragmentSpeechInputBinding;
import com.element.wisdomclassbrand.ui.base.BaseViewBindingFragment;
import com.element.wisdomclassbrand.util.AudioRecorderHelper;
import com.element.wisdomclassbrand.util.MyCountDownTimer;
import com.eric.jinglecat.util.AudioPlayer;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.io.File;

import kotlin.Unit;
import kotlin.jvm.functions.Function0;
import kotlin.jvm.functions.Function1;

public class SpeechInputFragment extends BaseViewBindingFragment<FragmentSpeechInputBinding> {

    private MediaRecorder recorder; //录音机
    private File recorderFile; //录音暂存文件
    private MyCountDownTimer myCountDownTimer; // 倒计时
    private Long startRecordTime = 0L;
    private Long mAudioSourceRecordTime = 0L; // 当前录音时长


    public static SpeechInputFragment newInstance() {
        Bundle args = new Bundle();
        SpeechInputFragment fragment = new SpeechInputFragment();
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onAttach(@NonNull @NotNull Context context) {
        super.onAttach(context);
        if (context instanceof IStateListener) {
            iStateListener = (IStateListener) context;
        }
    }

    @Override
    protected int initLayoutId() {
        return R.layout.fragment_speech_input;
    }

    @SuppressLint("SetTextI18n")
    @Override
    protected void initParams(@Nullable Bundle savedInstanceState) {
        super.initParams(savedInstanceState);
    }

    @Override
    protected void initViews() {
        super.initViews();
        getBinding().suspendVoice.setOnClickListener(this);
        getBinding().recordVoice.setOnClickListener(this);
        getBinding().trashCanVoice.setOnClickListener(this);
        getBinding().playVoice.setOnClickListener(this);
        getBinding().playSuspendVoice.setOnClickListener(this);
    }

    @SuppressLint("NonConstantResourceId")
    @Override
    public void onClick(@Nullable View v) {
        super.onClick(v);
        if (v == null) {
            return;
        }
        switch (v.getId()) {
            case R.id.suspend_voice:
                suspendVoice();
                break;
            case R.id.record_voice:
                recordVoice(v);
                break;
            case R.id.play_voice:
                playVoice(v);
                break;
            case R.id.play_suspend_voice:
                playSuspendVoice(v);
                break;
            case R.id.trash_can_voice:
                trashCanVoice(v);
                break;
        }
    }

    @Override
    @SuppressLint("SetTextI18n")
    protected void initListeners() {
        super.initListeners();
        myCountDownTimer = new MyCountDownTimer(60000L, 1000, new Function0<Unit>() {
            @Override
            public Unit invoke() {
                suspendVoice(); // 暂停录制
                return null;
            }
        }, new Function1<Long, Unit>() {
            @Override
            public Unit invoke(Long aLong) {
                getBinding().hourMinuteSecond.setText(getResources().getString(R.string.voice_entering_count_down, aLong / 1000L));
                return null;
            }
        });
    }

    /**
     * 开始录音
     */
    private void recordVoice(View v) {
        initAudioRecorder(); // 初始化录音机
        onStartRecord(); // 开始录制

        v.setVisibility(View.GONE);
        getBinding().suspendVoice.setVisibility(View.VISIBLE);
        getBinding().tvLeaveReasonsRecordHint.setVisibility(View.GONE);

        myCountDownTimer.start(); // 开启倒计时
        setStartRecordTime(System.currentTimeMillis());
    }

    private void setStartRecordTime(Long time) {
        startRecordTime = time;
    }

    /**
     * 暂停录音
     */
    private void suspendVoice() {
        getBinding().suspendVoice.setVisibility(View.GONE);
        getBinding().playVoice.setVisibility(View.VISIBLE);
        getBinding().trashCanVoice.setVisibility(View.VISIBLE);

        myCountDownTimer.cancel(); // 暂停倒计时
        onStopRecord();

        mAudioSourceRecordTime = getAudioSourceMaxRecordTime();
        getBinding().hourMinuteSecond.setText(getResources().getString(R.string.leave_reasons_record_text, mAudioSourceRecordTime));
    }

    private Long getAudioSourceMaxRecordTime() {
        Long tempEndRecordTime = System.currentTimeMillis() / 1000;
        Long tempStartRecordTime = startRecordTime / 1000;
        return tempEndRecordTime - tempStartRecordTime;
    }

    /**
     * 播放录音
     */
    private void playVoice(View v) {
        v.setVisibility(View.GONE);
        getBinding().playSuspendVoice.setVisibility(View.VISIBLE);
        AudioPlayer.getInstance().playAudio(recorderFile.getAbsolutePath());
        // 当前所播放的媒体文件是否播放完成
        AudioPlayer.getInstance().setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            @Override
            public void onCompletion(MediaPlayer mp) {
                v.setVisibility(View.VISIBLE);
                getBinding().playSuspendVoice.setVisibility(View.GONE);
                iStateListener.openTimedTask(); // 开启跳转顶层窗口定时任务阈值
            }
        });
    }

    /**
     * 暂停录音
     */
    private void playSuspendVoice(View v) {
        v.setVisibility(View.GONE);
        getBinding().playVoice.setVisibility(View.VISIBLE);
        AudioPlayer.getInstance().stop();
    }

    /**
     * 删除录音
     */
    private void trashCanVoice(View v) {
        v.setVisibility(View.GONE);
        getBinding().playVoice.setVisibility(View.GONE);
        getBinding().playSuspendVoice.setVisibility(View.GONE);
        getBinding().recordVoice.setVisibility(View.VISIBLE);
        getBinding().tvLeaveReasonsRecordHint.setVisibility(View.VISIBLE);
        getBinding().hourMinuteSecond.setText("");
        deleteRecordFile();
    }

    /**
     * 初始化AudioRecorder
     */
    private void initAudioRecorder() {
        recorderFile = 自己定义一个语音路径
        recorder = AudioRecorderHelper.getAudioRecorder(recorderFile);
    }

    /**
     * 开始录音
     */
    private void onStartRecord() {
        recorder.start();
    }

    /**
     * 结束录音
     */
    private void onStopRecord() {
        if (recorder == null) {
            return;
        }
        recorder.stop();
        recorder.release();
    }

    /**
     * 删除文件
     */
    private void deleteRecordFile() {
        if (recorderFile == null) {
            return;
        }
        recorderFile.delete();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        deleteRecordFile();
    }
}

倒计时工具类封装

package com.element.wisdomclassbrand.util

import android.content.Intent
import android.os.CountDownTimer
import com.element.wisdomclassbrand.app.SessionContext
import com.element.wisdomclassbrand.ui.act.AppSplashActivity
import com.element.wisdomclassbrand.ui.act.MainActivity
import com.element.wisdomclassbrand.ui.widget.CustomToastView
import com.eric.jinglecat.app.AppContext
import com.eric.jinglecat.util.ActivityUtil
import com.eric.jinglecat.util.LogUtil

/**
 * 倒计时工具类继承至CountDownTimer类
 */
class MyCountDownTimer(
    millisInFuture: Long,
    countDownInterval: Long,
    private val onFinished: () -> Unit,
    private val onTicked: (Long) -> Unit
) : CountDownTimer(millisInFuture, countDownInterval) {

    override fun onFinish() {
        onFinished()
    }

    override fun onTick(millisUntilFinished: Long) {
        onTicked(millisUntilFinished)
    }
}

l6yru7r0.png

布局代码就没啥好看的

本文共 167 个字数,平均阅读时长 ≈ 1分钟
1

打赏

:D 获取中...

更多精彩文章,按Ctrl+D收藏本站!

评论 (0)

取消