gpt4 book ai didi

android - 使用 AndroidRecord API 录制的音频无法播放

转载 作者:行者123 更新时间:2023-11-29 17:46:48 24 4
gpt4 key购买 nike

我正在开发一个具有录制用户语音功能的 Android 应用程序。为此,我使用了 AndroidRecord 音频 API。

目前在sd卡中成功生成了pcm文件(录制的音频文件-recordedAudio.pcm)。但我无法播放该文件。我也在 PC 上尝试过使用 windows media palyer 和其他一些播放器。但没有任何帮助。

以下是我的代码 fragment

private int minBufSize;
private AudioRecord recorder;
private int sampleRate = 44100;
private int channelConfig = AudioFormat.CHANNEL_IN_MONO;
private int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
private boolean status;

minBufSize = AudioRecord.getMinBufferSize(sampleRate, channelConfig,
audioFormat);
status = true;
startStreaming();

public void startStreaming() {
Thread streamThread = new Thread(new Runnable() {
@Override
public void run() {
try {
String filePath = Environment.getExternalStorageDirectory()
.getPath() + "/audioRecord.pcm";
FileOutputStream fileOutputStreamObj = null;
try {
fileOutputStreamObj = new FileOutputStream(filePath);
} catch (FileNotFoundException e) {
e.printStackTrace();
Log.e(TAG, "Exception" + e.getMessage());
}

// short[] sData = new short[minBufSize];
byte[] buffer = new byte[minBufSize];

// recorder = findAudioRecord();
recorder = new AudioRecord(MediaRecorder.AudioSource.MIC,
sampleRate, channelConfig, audioFormat, minBufSize);
Log.d(TAG, "Recorder initialized");

recorder.startRecording();

while (status) {
// reading data from MIC into buffer
minBufSize = recorder.read(buffer, 0, buffer.length);
try {
// writes the data to file from buffer
// stores the voice buffer
// byte bData[] = short2byte(sData);

fileOutputStreamObj.write(buffer, 0, buffer.length);
} catch (IOException e) {
e.printStackTrace();
Log.e(TAG, "Exception" + e.getMessage());
}
// mConnection.sendBinaryMessage(buffer);
System.out.println("MinBufferSize: " + minBufSize);
}

} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, "Exception" + e.getMessage());
}
}

});
streamThread.start();
}

请帮我解决这个问题。提前致谢。

最佳答案

您不必将其转换为 WAV 并播放。
AudioTrack可以直接播放录制的Audio。

以下是使用 AudioRecord 将音频录制到文件中并使用 AudioTrack API 播放的代码 fragment 。

操作由用户使用按钮控制。


代码

private int BufferSize;
byte[] buffer = new byte[BufferSize];

/* AudioRecord and AudioTrack Object */
private AudioRecord record = null;
private AudioTrack track = null;

/* Audio Configuration */
private int sampleRate = 44100;
private int channelConfig = AudioFormat.CHANNEL_IN_MONO;
private int audioFormat = AudioFormat.ENCODING_PCM_16BIT;

private boolean isRecording = true;
private Thread recordingThread = null;

音频配置可以根据设备更改。
引用this问题。


GUI 有三个按钮,RecordStopPlay

protected void onCreate(Bundle savedInstanceState) 
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

setButtonHandlers();

/* Set Button Visibility */
enableButton(R.id.btnStartRec,true);
enableButton(R.id.btnStopRec,false);
enableButton(R.id.btnStartPlay,false);

BufferSize = AudioRecord.getMinBufferSize(sampleRate,
channelConfig, audioFormat);
}

/* Function to Enable/Disable Buttons */
private void enableButton(int id,boolean isEnable){
((Button)findViewById(id)).setEnabled(isEnable);
}

/* Assign OnClickListener to Buttons */
private void setButtonHandlers() {
((Button)findViewById(R.id.btnStartRec)).setOnClickListener(btnClick);
((Button)findViewById(R.id.btnStopRec)).setOnClickListener(btnClick);
((Button)findViewById(R.id.btnStartPlay)).setOnClickListener(btnClick);
}

处理按钮点击:

private View.OnClickListener btnClick = new View.OnClickListener() {
@Override
public void onClick(View v) {
switch(v.getId()){
case R.id.btnStartRec:{
Log.d(TAG, "Start Recording");
enableButton(R.id.btnStartRec,false);
enableButton(R.id.btnStopRec,true);
startRecording();
break;
}
case R.id.btnStopRec:{
Log.d(TAG, "Stop Recording");
enableButton(R.id.btnStartRec,true);
enableButton(R.id.btnStopRec,false);
stopRecording();
enableButton(R.id.btnStartPlay,true);
break;
}
case R.id.btnStartPlay:{
Log.d(TAG, "Play Recording");
enableButton(R.id.btnStartRec,false);
enableButton(R.id.btnStopRec,false);
StartPlaying();
break;
}
}
}
};

开始录制代码

private void startRecording()
{
record = new AudioRecord(AudioSource.DEFAULT, sampleRate,
channelConfig, audioFormat, BufferSize);
if (AudioRecord.STATE_INITIALIZED == record.getState())
record.startRecording();

isRecording = true;

/* Run a thread for Recording */
recordingThread = new Thread(new Runnable() {
@Override
public void run() {
writeAudioDataToFile();
}
},"AudioRecorder Thread");
recordingThread.start();
}


private void writeAudioDataToFile()
{
byte data[] = new byte[BufferSize];

/* Record audio to following file */
String filename = "/sdcard/audiofile.pcm";
FileOutputStream os = null;

try {
os = new FileOutputStream(filename);
} catch (FileNotFoundException e) {
e.printStackTrace();
}

int read_bytes = 0;

if(null != os){
while(isRecording)
{
read_bytes = record.read(data, 0, BufferSize);

if(AudioRecord.ERROR_INVALID_OPERATION != read_bytes){
try {
os.write(data);
} catch (IOException e) {
e.printStackTrace();
}
}
}

try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

停止录制代码

private void stopRecording()
{
if(null != record)
{
isRecording = false;

if (AudioRecord.STATE_INITIALIZED == record.getState())
{
record.stop();
record.release();
Log.d(TAG, "===== Recording Audio Completed ===== ");
}

record = null;
recordingThread = null;
}
}

播放音频文件的代码:

public void startPlaying()
{
enableButton(R.id.btnStartPlay,false);

int minBufferSize = AudioTrack.getMinBufferSize(sampleRate,
AudioFormat.CHANNEL_OUT_MONO,
AudioFormat.ENCODING_PCM_16BIT);

track = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate,
AudioFormat.CHANNEL_OUT_MONO,
AudioFormat.ENCODING_PCM_16BIT, minBufferSize,
AudioTrack.MODE_STREAM);

int i = 0;
byte[] temp = new byte[minBufferSize];

try {
FileInputStream fin = new FileInputStream("/sdcard/audiofile.pcm");
Log.d(TAG, "===== Opening File for Playing : /sdcard/audiofile.pcm ===== ");

DataInputStream dis = new DataInputStream(fin);

track.play();
while((i = dis.read(temp, 0, minBufferSize)) > -1)
{
track.write(temp, 0, i);
}

Log.d(TAG, "===== Playing Audio Completed ===== ");
track.stop();
track.release();
dis.close();
fin.close();

} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
enableButton(R.id.btnStartRec,true);
}

请在 AndroidManifest.xml 中包含以下内容

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

activity_main.xml 看起来像 this .
string.xml 看起来像 this .

上面的代码正在运行并经过测试。

您也可以执行相同的操作,没有文件并使用中间缓冲区
请参阅:Audio Recording and Streaming in Android

关于android - 使用 AndroidRecord API 录制的音频无法播放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25970430/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com