多媒体——音频——利用MediaRecorder录制音频

news/2024/10/24 0:28:55/

布局:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="40dp"android:paddingLeft="5dp"><TextViewandroid:layout_width="wrap_content"android:layout_height="match_parent"android:gravity="center"android:text="音频编码:"android:textColor="@color/black"android:textSize="17sp" /><Spinnerandroid:id="@+id/sp_encoder"android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"android:gravity="left|center"android:spinnerMode="dialog" /></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="40dp"android:paddingLeft="5dp"><TextViewandroid:layout_width="wrap_content"android:layout_height="match_parent"android:gravity="center"android:text="输出格式:"android:textColor="@color/black"android:textSize="17sp" /><Spinnerandroid:id="@+id/sp_format"android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"android:gravity="left|center"android:spinnerMode="dialog" /></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="40dp"android:paddingLeft="5dp"><TextViewandroid:layout_width="wrap_content"android:layout_height="match_parent"android:gravity="center"android:text="录制时长:"android:textColor="@color/black"android:textSize="17sp" /><Spinnerandroid:id="@+id/sp_duration"android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"android:gravity="left|center"android:spinnerMode="dialog" /></LinearLayout><Buttonandroid:id="@+id/btn_record"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="开始录音"android:textColor="@color/black"android:textSize="17sp" /><LinearLayoutandroid:id="@+id/ll_progress"android:layout_width="match_parent"android:layout_height="30dp"android:paddingLeft="5dp"android:paddingRight="5dp"android:orientation="horizontal"android:visibility="gone"><ProgressBarandroid:id="@+id/pb_record"style="?android:attr/progressBarStyleHorizontal"android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="4" /><TextViewandroid:id="@+id/tv_progress"android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"android:gravity="right|center"android:textColor="@color/black"android:textSize="15sp" /></LinearLayout><ImageViewandroid:id="@+id/iv_audio"android:layout_width="match_parent"android:layout_height="50dp"android:scaleType="fitCenter"android:src="@drawable/play_audio"android:visibility="gone" /></LinearLayout>

 MediaUtil
package com.example.myapplication.util;import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.media.MediaMetadataRetriever;
import android.net.Uri;
import android.os.Environment;
import android.util.Log;import java.io.File;@SuppressLint("DefaultLocale")
public class MediaUtil {private final static String TAG = "MediaUtil";// 格式化播放时长(mm:ss)public static String formatDuration(int milliseconds) {int seconds = milliseconds / 1000;int hour = seconds / 3600;int minute = seconds / 60;int second = seconds % 60;String str;if (hour > 0) {str = String.format("%02d:%02d:%02d", hour, minute, second);} else {str = String.format("%02d:%02d", minute, second);}return str;}// 获得音视频文件的缓存路径public static String getRecordFilePath(Context context, String dir_name, String extend_name) {String path = "";File recordDir = new File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).toString() + "/" + dir_name + "/");if (!recordDir.exists()) {recordDir.mkdirs();}try {File recordFile = File.createTempFile(DateUtil.getNowDateTime(), extend_name, recordDir);path = recordFile.getAbsolutePath();Log.d(TAG, "dir_name=" + dir_name + ", extend_name=" + extend_name + ", path=" + path);} catch (Exception e) {e.printStackTrace();}return path;}// 获取视频文件中的某帧图片public static Bitmap getOneFrame(Context ctx, Uri uri) {MediaMetadataRetriever retriever = new MediaMetadataRetriever();retriever.setDataSource(ctx, uri);// 获得视频的播放时长,大于1秒的取第1秒处的帧图,不足1秒的取第0秒处的帧图String duration = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);Log.d(TAG, "duration="+duration);int pos = (Integer.parseInt(duration)/1000)>1 ? 1 : 0;// 获取指定时间的帧图,注意getFrameAtTime方法的时间单位是微秒return retriever.getFrameAtTime(pos * 1000 * 1000);}
}
item_select.xml
<TextView xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="50dp"android:singleLine="true"android:gravity="center"android:textSize="17sp"android:textColor="#0000ff" />

主代码:

package com.example.myapplication;import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import com.example.myapplication.util.MediaUtil;
import androidx.appcompat.app.AppCompatActivity;
import java.util.Timer;
import java.util.TimerTask;public class MainActivity extends AppCompatActivity implements View.OnClickListener, MediaRecorder.OnInfoListener {private static final String TAG = "MediaRecorderActivity";private Button btn_record;private LinearLayout ll_progress;private ProgressBar pb_record; // 声明一个进度条对象private TextView tv_progress;private ImageView iv_audio; // 该图标充当播放按钮private MediaRecorder mMediaRecorder = new MediaRecorder(); // 媒体录制器private boolean isRecording = false; // 是否正在录制private int mAudioEncoder; // 音频编码private int mOutputFormat; // 输出格式private int mDuration; // 录制时长private String mRecordFilePath; // 录制文件的保存路径private Timer mTimer = new Timer(); // 计时器private int mTimeCount; // 时间计数private MediaPlayer mMediaPlayer = new MediaPlayer(); // 媒体播放器@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);btn_record = findViewById(R.id.btn_record);ll_progress = findViewById(R.id.ll_progress);pb_record = findViewById(R.id.pb_record);tv_progress = findViewById(R.id.tv_progress);iv_audio = findViewById(R.id.iv_audio);btn_record.setOnClickListener(this);iv_audio.setOnClickListener(this);initEncoderSpinner(); // 初始化音频编码的下拉框initFormatSpinner(); // 初始化输出格式的下拉框initDurationSpinner(); // 初始化录制时长的下拉框}// 初始化音频编码的下拉框private void initEncoderSpinner() {ArrayAdapter<String> encoderAdapter = new ArrayAdapter<String>(this,R.layout.item_select, encoderDescArray);Spinner sp_encoder = findViewById(R.id.sp_encoder);sp_encoder.setPrompt("请选择音频编码"); // 设置下拉框的标题sp_encoder.setAdapter(encoderAdapter); // 设置下拉框的数组适配器// 给下拉框设置选择监听器,一旦用户选中某一项,就触发监听器的onItemSelected方法sp_encoder.setOnItemSelectedListener(new EncoderSelectedListener());sp_encoder.setSelection(0); // 设置下拉框默认显示第一项}private String[] encoderDescArray = {"默认编码","窄带编码","宽带编码","低复杂度的高级编码","高效率的高级编码","增强型低延时的高级编码"};private int[] encoderArray = {MediaRecorder.AudioEncoder.DEFAULT,MediaRecorder.AudioEncoder.AMR_NB,MediaRecorder.AudioEncoder.AMR_WB,MediaRecorder.AudioEncoder.AAC,MediaRecorder.AudioEncoder.HE_AAC,MediaRecorder.AudioEncoder.AAC_ELD};class EncoderSelectedListener implements AdapterView.OnItemSelectedListener {public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) {mAudioEncoder = encoderArray[arg2];}public void onNothingSelected(AdapterView<?> arg0) {}}// 初始化输出格式的下拉框private void initFormatSpinner() {ArrayAdapter<String> formatAdapter = new ArrayAdapter<String>(this,R.layout.item_select, formatDescArray);Spinner sp_format = findViewById(R.id.sp_format);sp_format.setPrompt("请选择输出格式"); // 设置下拉框的标题sp_format.setAdapter(formatAdapter); // 设置下拉框的数组适配器sp_format.setSelection(0); // 设置下拉框默认显示第一项// 给下拉框设置选择监听器,一旦用户选中某一项,就触发监听器的onItemSelected方法sp_format.setOnItemSelectedListener(new FormatSelectedListener());}private String[] formatDescArray = {"默认格式","窄带格式","宽带格式","高级的音频传输流格式"};private int[] formatArray = {MediaRecorder.OutputFormat.DEFAULT,MediaRecorder.OutputFormat.AMR_NB,MediaRecorder.OutputFormat.AMR_WB,MediaRecorder.OutputFormat.AAC_ADTS};class FormatSelectedListener implements AdapterView.OnItemSelectedListener {public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) {mOutputFormat = formatArray[arg2];}public void onNothingSelected(AdapterView<?> arg0) {}}// 初始化录制时长的下拉框private void initDurationSpinner() {ArrayAdapter<String> durationAdapter = new ArrayAdapter<String>(this,R.layout.item_select, durationDescArray);Spinner sp_duration = findViewById(R.id.sp_duration);sp_duration.setPrompt("请选择录制时长"); // 设置下拉框的标题sp_duration.setAdapter(durationAdapter); // 设置下拉框的数组适配器sp_duration.setSelection(0); // 设置下拉框默认显示第一项// 给下拉框设置选择监听器,一旦用户选中某一项,就触发监听器的onItemSelected方法sp_duration.setOnItemSelectedListener(new DurationSelectedListener());}private String[] durationDescArray = {"5秒", "10秒", "20秒", "30秒", "60秒"};private int[] durationArray = {5, 10, 20, 30, 60};class DurationSelectedListener implements AdapterView.OnItemSelectedListener {public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) {mDuration = durationArray[arg2];}public void onNothingSelected(AdapterView<?> arg0) {}}@Overridepublic void onClick(View v) {if (v.getId() == R.id.btn_record) {if (!isRecording) { // 未在录音startRecord(); // 开始录音} else { // 正在录音stopRecord(); // 停止录音}} else if (v.getId() == R.id.iv_audio) {mMediaPlayer.reset(); // 重置媒体播放器mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); // 设置音频流的类型为音乐try {mMediaPlayer.setDataSource(mRecordFilePath); // 设置媒体数据的文件路径mMediaPlayer.prepare(); // 媒体播放器准备就绪mMediaPlayer.start(); // 媒体播放器开始播放} catch (Exception e) {e.printStackTrace();}}}// 开始录音private void startRecord() {Log.d(TAG, "startRecord mAudioEncoder="+mAudioEncoder+", mOutputFormat="+mOutputFormat+", mDuration="+mDuration);ll_progress.setVisibility(View.VISIBLE);isRecording = !isRecording;btn_record.setText("停止录制");pb_record.setMax(mDuration); // 设置进度条的最大值mTimeCount = 0; // 时间计数清零mTimer = new Timer(); // 创建一个计时器mTimer.schedule(new TimerTask() {@Overridepublic void run() {pb_record.setProgress(mTimeCount); // 设置进度条的当前进度tv_progress.setText(MediaUtil.formatDuration(mTimeCount*1000));mTimeCount++;}}, 0, 1000); // 计时器每隔一秒就更新进度条上的录制进度// 获取本次录制的媒体文件路径mRecordFilePath = MediaUtil.getRecordFilePath(this, "RecordAudio", ".amr");// 下面是媒体录制器的处理代码mMediaRecorder.reset(); // 重置媒体录制器mMediaRecorder.setOnInfoListener(this); // 设置媒体录制器的信息监听器mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); // 设置音频源为麦克风mMediaRecorder.setOutputFormat(mOutputFormat); // 设置媒体的输出格式。该方法要先于setAudioEncoder调用mMediaRecorder.setAudioEncoder(mAudioEncoder); // 设置媒体的音频编码器// mMediaRecorder.setAudioSamplingRate(8); // 设置媒体的音频采样率。可选// mMediaRecorder.setAudioChannels(2); // 设置媒体的音频声道数。可选// mMediaRecorder.setAudioEncodingBitRate(1024); // 设置音频每秒录制的字节数。可选mMediaRecorder.setMaxDuration(mDuration * 1000); // 设置媒体的最大录制时长// mMediaRecorder.setMaxFileSize(1024*1024*10); // 设置媒体的最大文件大小// setMaxFileSize与setMaxDuration设置其一即可mMediaRecorder.setOutputFile(mRecordFilePath); // 设置媒体文件的保存路径try {mMediaRecorder.prepare(); // 媒体录制器准备就绪mMediaRecorder.start(); // 媒体录制器开始录制} catch (Exception e) {e.printStackTrace();}}// 停止录音private void stopRecord() {isRecording = !isRecording;btn_record.setText("开始录制");mTimer.cancel(); // 取消定时器mMediaRecorder.stop(); // 媒体录制器停止录制}@Overridepublic void onInfo(MediaRecorder mr, int what, int extra) {// 录制达到最大时长,或者达到文件大小限制,都停止录制if (what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED|| what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED) {stopRecord(); // 停止录音iv_audio.setVisibility(View.VISIBLE);Toast.makeText(this, "已结束录制,音频文件路径为"+mRecordFilePath, Toast.LENGTH_LONG).show();}}@Overrideprotected void onStop() {super.onStop();if (!TextUtils.isEmpty(mRecordFilePath) && isRecording) {stopRecord(); // 停止录音}if (mMediaPlayer.isPlaying()) { // 如果正在播放mMediaPlayer.stop(); // 停止播放}}@Overrideprotected void onDestroy() {super.onDestroy();mMediaRecorder.release(); // 释放媒体录制器mMediaPlayer.release(); // 释放媒体播放器}
}

 

 

 


http://www.ppmy.cn/news/474528.html

相关文章

有没有录制声音的方法?教你三个录制的方法

现如今&#xff0c;很多的地方都需要使用录音功能&#xff0c;无论是我们平时的商场推销、视频配音还是会议录制、通过录制等等。那么大家平时是怎么样进行声音的录制的呢&#xff1f; 如果你还不知道录制声音的方法有哪些的话&#xff0c;让我来教教你吧。下面大家分享三个好…

电脑录制音频用什么软件效果好?看完你就知道了

音频录制软件作为音频处理领域的重要工具&#xff0c;已经成为了众多音频制作爱好者、专业制作人员和工程师的必备应用之一。随着音频录制软件的数量和种类不断增多&#xff0c;很多人面临着如何选择合适的录音软件的难题。那么&#xff0c;对于众多音频录制软件中的精品佳作&a…

python---录制音频

import numpy as np from matplotlib import pyplot as plt import pyaudio import waveCHUNK1024 #每个缓冲区的帧数 FORMAT pyaudio.paInt16 #采样位数 fs 16000 duration2 channels 1 n duration * fs t np.arange(1,n) / fs wave_output_file record.wav print(这…

内录音频工具哪个好 怎么录制电脑音频

我想现在很多人都会使用到音频软件吧&#xff01;最简单的大家应该都使用过&#xff0c;就是我们手机或者电脑自带的录音软件&#xff0c;这些用起来很简单&#xff0c;但是一般功能都比较单一&#xff0c;无法满足我们的需求&#xff0c;如果我们想录制电脑系统发出的声音该怎…

[2021.12.5]使用MediaRecorder录制音频和视频(Camera1)

1 概述 MediaRecorder类用于录制音频和视频。步骤如下&#xff1a; (1)实例化MediaRecorder对象 (2)设置声音来源和图像来源 (3)设置视频分辨率 (4)设置录制视频文件的保存路径 (5)设置使用哪个SurfaceView (6)准备录制视频 (7)开始录制视频 (8)停止录制&#xff0c;释放资源 …

内录音频的方法

有时需要将电脑上听到的声音录制下来&#xff0c;比如在网上听到一首好歌或者视频里的某段音乐&#xff0c;由于种种原因无法下载时&#xff0c;我们可以通过电脑内录的方法将其录制下来。提醒一句&#xff0c;内录下来的音乐也得注意版权问题哦。 设 置 要进行电脑内录之前&am…

Android录制声音文件(音频),并播放

readme&#xff1a;1、这个demo中没有对多次点击同一个声音文件做详细处理&#xff0c;偶尔会有崩溃&#xff0c;用的时候需要注意。2、按住录音按钮录音过程中&#xff0c;只对竖直方向处理了一下&#xff0c;水平方向没写&#xff1b;3、没有做删除某个声音文件的操作&#x…

windows下录制音频

参考文档&#xff1a; 1&#xff1a;github上的一个开源代码&#xff1a;点击打开链接&#xff0c;因为存储音频需要自己写文件头部&#xff0c;所以这里借鉴了它的文件存储功能。 2&#xff1a;一个很有用的帖子代码&#xff1a;点击打开链接&#xff0c;虽然有点小瑕疵&…