怎么使用arecord录制mono
时间: 2024-01-09 08:05:16 浏览: 232
要使用arecord录制单声道音频,您可以通过在命令行中指定参数来设置录制参数。以下是一个示例命令:
```
arecord -f S16_LE -r 44100 -c 1 -D hw:0,0 -d 10 recording.wav
```
解释一下这个命令的各个参数:
- `-f S16_LE`:设置音频格式为16位的小端存储。
- `-r 44100`:设置采样率为44100 Hz。
- `-c 1`:设置通道数为1(单声道)。
- `-D hw:0,0`:指定音频设备,这里是使用硬件设备hw:0,0。
- `-d 10`:设置录制时长为10秒。
- `recording.wav`:指定保存录制音频的文件名。
请注意,这只是一个示例命令,您可能需要根据您的实际情况进行调整。
相关问题
用audiorecord录制一个wav音频文件
好的,以下是用 Android 的 AudioRecord 类录制 wav 音频文件的代码示例:
```java
private void startRecording() {
// 设置音频录制参数
int audioSource = MediaRecorder.AudioSource.MIC;
int sampleRate = 44100;
int channelConfig = AudioFormat.CHANNEL_IN_MONO;
int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
int bufferSizeInBytes = AudioRecord.getMinBufferSize(sampleRate, channelConfig, audioFormat);
AudioRecord audioRecord = new AudioRecord(audioSource, sampleRate, channelConfig, audioFormat, bufferSizeInBytes);
// 开始录制音频
audioRecord.startRecording();
byte[] audioData = new byte[bufferSizeInBytes];
// 创建 wav 文件
String filePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/test.wav";
try {
FileOutputStream fos = new FileOutputStream(filePath);
// 写入 wav 文件头
writeWaveFileHeader(fos, audioData.length);
while (isRecording) {
// 读取录制的音频数据
int readSize = audioRecord.read(audioData, 0, bufferSizeInBytes);
if (AudioRecord.ERROR_INVALID_OPERATION != readSize) {
// 写入 wav 文件
fos.write(audioData, 0, readSize);
}
}
// 关闭文件流
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
// 停止录制音频
audioRecord.stop();
audioRecord.release();
}
private void writeWaveFileHeader(FileOutputStream fos, int audioDataLength) throws IOException {
// 音频数据大小
long dataSize = audioDataLength;
// 文件大小
long fileSize = 36 + dataSize;
// 采样率
int sampleRate = 44100;
// 声道数
int numChannels = 1;
// 位深度
int bitsPerSample = 16;
byte[] header = new byte[44];
// ChunkID
header[0] = 'R';
header[1] = 'I';
header[2] = 'F';
header[3] = 'F';
// ChunkSize
header[4] = (byte) (fileSize & 0xff);
header[5] = (byte) ((fileSize >> 8) & 0xff);
header[6] = (byte) ((fileSize >> 16) & 0xff);
header[7] = (byte) ((fileSize >> 24) & 0xff);
// Format
header[8] = 'W';
header[9] = 'A';
header[10] = 'V';
header[11] = 'E';
// Subchunk1ID
header[12] = 'f';
header[13] = 'm';
header[14] = 't';
header[15] = ' ';
// Subchunk1Size
header[16] = 16;
header[17] = 0;
header[18] = 0;
header[19] = 0;
// AudioFormat
header[20] = 1;
header[21] = 0;
// NumChannels
header[22] = (byte) numChannels;
header[23] = 0;
// SampleRate
header[24] = (byte) (sampleRate & 0xff);
header[25] = (byte) ((sampleRate >> 8) & 0xff);
header[26] = (byte) ((sampleRate >> 16) & 0xff);
header[27] = (byte) ((sampleRate >> 24) & 0xff);
// ByteRate
int byteRate = sampleRate * numChannels * bitsPerSample / 8;
header[28] = (byte) (byteRate & 0xff);
header[29] = (byte) ((byteRate >> 8) & 0xff);
header[30] = (byte) ((byteRate >> 16) & 0xff);
header[31] = (byte) ((byteRate >> 24) & 0xff);
// BlockAlign
int blockAlign = numChannels * bitsPerSample / 8;
header[32] = (byte) (blockAlign & 0xff);
header[33] = (byte) ((blockAlign >> 8) & 0xff);
// BitsPerSample
header[34] = (byte) bitsPerSample;
header[35] = 0;
// Subchunk2ID
header[36] = 'd';
header[37] = 'a';
header[38] = 't';
header[39] = 'a';
// Subchunk2Size
header[40] = (byte) (dataSize & 0xff);
header[41] = (byte) ((dataSize >> 8) & 0xff);
header[42] = (byte) ((dataSize >> 16) & 0xff);
header[43] = (byte) ((dataSize >> 24) & 0xff);
fos.write(header, 0, 44);
}
```
以上代码中,我们首先设置了音频录制的参数:音频源为麦克风,采样率为 44100 Hz,声道数为单声道,位深度为 16 位。然后通过 AudioRecord.getMinBufferSize() 方法获取音频数据缓冲区的大小,并创建 AudioRecord 实例。
接着,我们开始录制音频,并创建一个 FileOutputStream 实例来写入 wav 文件。在录制过程中,我们不断读取录制的音频数据,并将其写入 wav 文件。最后,我们在停止录制音频之前,关闭文件流,并释放 AudioRecord 实例。
在写入 wav 文件之前,我们需要先写入 wav 文件头。wav 文件头的格式如下:
| 字段 | 长度 | 说明 |
| --- | --- | --- |
| ChunkID | 4 | 固定值 "RIFF" |
| ChunkSize | 4 | 文件大小(不包括 ChunkID 和 ChunkSize)|
| Format | 4 | 固定值 "WAVE" |
| Subchunk1ID | 4 | 固定值 "fmt " |
| Subchunk1Size | 4 | 16(表示 Subchunk1 的大小)|
| AudioFormat | 2 | 音频格式(1 表示 PCM)|
| NumChannels | 2 | 声道数 |
| SampleRate | 4 | 采样率 |
| ByteRate | 4 | 每秒传输的字节数 |
| BlockAlign | 2 | 每个采样点占用的字节数 |
| BitsPerSample | 2 | 位深度 |
| Subchunk2ID | 4 | 固定值 "data" |
| Subchunk2Size | 4 | 音频数据大小 |
我们可以通过 writeWaveFileHeader() 方法来写入 wav 文件头。在该方法中,我们需要传入 wav 文件的 FileOutputStream 对象和音频数据的长度,然后按照上述格式写入 wav 文件头。最后,我们在 wav 文件头的末尾写入音频数据大小即可。
希望以上代码能够帮助到你!
Android MediaCodec 录制音频功能完整代码
以下是一个简单的 Android MediaCodec 录制音频的完整代码示例:
```java
import android.media.MediaCodec;
import android.media.MediaCodecInfo;
import android.media.MediaFormat;
import android.media.MediaMuxer;
import android.os.Build;
import android.os.Environment;
import android.util.Log;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
public class AudioRecorder {
private static final String TAG = "AudioRecorder";
private static final String AUDIO_MIME_TYPE = "audio/mp4a-latm";
private static final int AUDIO_SAMPLE_RATE = 44100; // 44.1kHz
private static final int AUDIO_CHANNEL_COUNT = 1; // mono
private static final int AUDIO_BIT_RATE = 64000;
private static final int BUFFER_SIZE = 2 * AudioRecord.getMinBufferSize(AUDIO_SAMPLE_RATE,
AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT);
private MediaCodec mEncoder;
private MediaMuxer mMuxer;
private int mTrackIndex = -1;
private boolean mMuxerStarted = false;
private long mStartTime = 0;
public void startRecording() throws IOException {
File outputFile = new File(Environment.getExternalStorageDirectory(),
"audio_record.mp4");
mEncoder = MediaCodec.createEncoderByType(AUDIO_MIME_TYPE);
MediaFormat format = new MediaFormat();
format.setString(MediaFormat.KEY_MIME, AUDIO_MIME_TYPE);
format.setInteger(MediaFormat.KEY_SAMPLE_RATE, AUDIO_SAMPLE_RATE);
format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, AUDIO_CHANNEL_COUNT);
format.setInteger(MediaFormat.KEY_BIT_RATE, AUDIO_BIT_RATE);
format.setInteger(MediaFormat.KEY_AAC_PROFILE, MediaCodecInfo.CodecProfileLevel.AACObjectLC);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
format.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, BUFFER_SIZE);
}
mEncoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
mEncoder.start();
mMuxer = new MediaMuxer(outputFile.getAbsolutePath(), MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
ByteBuffer[] encoderOutputBuffers = mEncoder.getOutputBuffers();
MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
mTrackIndex = -1;
mMuxerStarted = false;
int sampleRate = AUDIO_SAMPLE_RATE;
int channelCount = AUDIO_CHANNEL_COUNT;
long presentationTimeUs = 0;
while (true) {
int inputBufferIndex = mEncoder.dequeueInputBuffer(-1);
if (inputBufferIndex >= 0) {
ByteBuffer inputBuffer = mEncoder.getInputBuffer(inputBufferIndex);
inputBuffer.clear();
int bytesRead = // read audio data into the inputBuffer
if (bytesRead == -1) { // eof
mEncoder.queueInputBuffer(inputBufferIndex, 0, 0, presentationTimeUs,
MediaCodec.BUFFER_FLAG_END_OF_STREAM);
break;
} else {
int inputBufferCapacity = inputBuffer.capacity();
int size = inputBufferCapacity < bytesRead ? inputBufferCapacity : bytesRead;
inputBuffer.put(audioData, 0, size);
presentationTimeUs = (long) (1_000_000L * bytesRead / (2 * channelCount * sampleRate));
mEncoder.queueInputBuffer(inputBufferIndex, 0, size, presentationTimeUs, 0);
}
}
int outputBufferIndex = mEncoder.dequeueOutputBuffer(bufferInfo, 0);
if (outputBufferIndex >= 0) {
ByteBuffer outputBuffer = encoderOutputBuffers[outputBufferIndex];
if (!mMuxerStarted) {
MediaFormat newFormat = mEncoder.getOutputFormat();
mTrackIndex = mMuxer.addTrack(newFormat);
mMuxer.start();
mStartTime = System.nanoTime();
mMuxerStarted = true;
}
if ((bufferInfo.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0) {
bufferInfo.size = 0;
}
if (bufferInfo.size != 0) {
outputBuffer.position(bufferInfo.offset);
outputBuffer.limit(bufferInfo.offset + bufferInfo.size);
mMuxer.writeSampleData(mTrackIndex, outputBuffer, bufferInfo);
}
mEncoder.releaseOutputBuffer(outputBufferIndex, false);
} else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
MediaFormat newFormat = mEncoder.getOutputFormat();
mTrackIndex = mMuxer.addTrack(newFormat);
mMuxer.start();
mStartTime = System.nanoTime();
mMuxerStarted = true;
}
}
release();
}
private void release() {
if (mEncoder != null) {
mEncoder.stop();
mEncoder.release();
mEncoder = null;
}
if (mMuxer != null) {
if (mMuxerStarted) {
mMuxer.stop();
}
mMuxer.release();
mMuxer = null;
}
}
}
```
注意,这只是一个简单的示例,实际应用中还需要考虑错误处理、音频数据来源和如何停止录制等问题。
阅读全文