我是靠谱客的博主 隐形红酒,最近开发中收集的这篇文章主要介绍Android如何将采集到的音频PCM文件转为WAV并保存1.Android音频采集2.PCM文件转WAV,觉得挺不错的,现在分享给大家,希望可以做个参考。
概述
1.Android音频采集
添加权限
<uses-permission android:name="android.permission.RECORD_AUDIO" />
动态申请权限
引入权限申请库
implementation 'com.permissionx.guolindev:permissionx:1.4.0'
申请权限的部分代码
PermissionX.init(this).permissions(Manifest.permission.RECORD_AUDIO)
.request { _, _, _ ->
//TODO 申请成功之后的代码写在这里
}
初始化AudioRecorder
需要设置的参数有:音频源,采样率,声道数,数据类型,最小缓冲区
最小缓冲区的大小用AudioRecord.getMinBufferSize接口,根据采样率,声道数,数据类型返回该值;
private const val SAMPLE_RATE_IN_HZ_16K = 16000
private var minBufferSize = 1280
private var audioRecord: AudioRecord? = null
private var captureThread: Thread? = null
private var isRunning = false
private var isFloats = false
fun start(isFloats: Boolean) {
this.isFloats = isFloats
minBufferSize = AudioRecord.getMinBufferSize(
SAMPLE_RATE_IN_HZ_16K,
AudioFormat.CHANNEL_IN_MONO,
if (isFloats) AudioFormat.ENCODING_PCM_FLOAT else AudioFormat.ENCODING_PCM_16BIT
)
audioRecord = AudioRecord(
MediaRecorder.AudioSource.VOICE_COMMUNICATION,
SAMPLE_RATE_IN_HZ_16K,
AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_FLOAT,
minBufferSize
)
audioRecord!!.startRecording()
isRunning = true
}
音频采集时可以设置的格式有
public static final int ENCODING_DEFAULT = 1;
// These values must be kept in sync with core/jni/android_
// Also sync av/services/audiopolicy/managerdefault/ConfigP
/** Audio data format: PCM 16 bit per sample. Guaranteed to
public static final int ENCODING_PCM_16BIT = 2;
/** Audio data format: PCM 8 bit per sample. Not guaranteed
public static final int ENCODING_PCM_8BIT = 3;
/** Audio data format: single-precision floating-point per
public static final int ENCODING_PCM_FLOAT = 4;
/** Audio data format: AC-3 compressed, also known as Dolby
public static final int ENCODING_AC3 = 5;
/** Audio data format: E-AC-3 compressed, also known as Dol
public static final int ENCODING_E_AC3 = 6;
/** Audio data format: DTS compressed */
public static final int ENCODING_DTS = 7;
/** Audio data format: DTS HD compressed */
public static final int ENCODING_DTS_HD = 8;
/** Audio data format: MP3 compressed */
public static final int ENCODING_MP3 = 9;
/** Audio data format: AAC LC compressed */
public static final int ENCODING_AAC_LC = 10;
/** Audio data format: AAC HE V1 compressed */
public static final int ENCODING_AAC_HE_V1 = 11;
/** Audio data format: AAC HE V2 compressed */
public static final int ENCODING_AAC_HE_V2 = 12;
开始采集数据
fun capture(listener: OnReadListener) {
captureThread = Thread {
while (isRunning) {
var nReadBytes: Int
if (isFloats) {
val data = FloatArray(minBufferSize)
nReadBytes =
audioRecord!!.read(data, 0, minBufferSize, AudioRecord.READ_BLOCKING)
listener.read(nReadBytes, data)
} else {
val data = ByteArray(minBufferSize)
nReadBytes =
audioRecord!!.read(data, 0, minBufferSize)
listener.read(nReadBytes, data)
}
}
}
captureThread!!.start()
}
数据回调接口
interface OnReadListener {
fun read(readSize: Int, floatArray: FloatArray)
fun read(readSize: Int, byteArray: ByteArray)
}
结束采集,关闭AudioRecorder
fun stop() {
isRunning = false
captureThread!!.interrupt()
try {
audioRecord!!.stop()
audioRecord!!.release()
} catch (e : Exception) {
e.printStackTrace()
}
}
采集到的数据后将PCM数据保存
AudioCapture.capture(object : AudioCapture.OnReadListener {
override fun read(readSize: Int, floatArray: FloatArray) {
val savePath = getDir(
"spanner", Context.MODE_PRIVATE
).absolutePath + File.separator + "/Music/"
//保存浮点数据到本地文件
SaveBytesAsFile.writeFile(floatArray, savePath + "record.pcm")
}
override fun read(readSize: Int, byteArray: ByteArray) {
}
})
public class SaveBytesAsFile {
public SaveBytesAsFile() {
}
public void writeFile(byte[] bytes) {
long time = System.currentTimeMillis();
String path = Environment.getExternalStorageDirectory() + File.separator + "g711ToAAC.aac";
try {
FileOutputStream out = new FileOutputStream(path, true);//指定写到哪个路径中
FileChannel fileChannel = out.getChannel();
fileChannel.write(ByteBuffer.wrap(bytes)); //将字节流写入文件中
fileChannel.force(true);//强制刷新
fileChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 将流写入口自定义路径
*
* @param bytes
* @param path ps:快捷回复AAC转PCM之后写入到指定路径 请勿修改
*/
public static void writeFile(byte[] bytes, String path) {
try {
FileOutputStream out = new FileOutputStream(path, true);//指定写到哪个路径中
FileChannel fileChannel = out.getChannel();
fileChannel.write(ByteBuffer.wrap(bytes)); //将字节流写入文件中
fileChannel.force(true);//强制刷新
fileChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void writeFile(float[] floats, String path) {
try {
FileOutputStream fos = new FileOutputStream(path, true);
DataOutputStream dos = new DataOutputStream(fos);
for (float f : floats) {
dos.writeFloat(f);
}
dos.flush();
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
2.PCM文件转WAV
播放浮点型音频的指令
ffplay -f f32be -ar 16000 -ac 1 -i record.pcm
使用FFMPEG
ffmpeg -f 音频格式 -ar 采样率 -ac 频道数 -i pcm文件名 -ar 采样率 -ac 频道数 wav文件名
此处把浮点型的PCM数据转化
//浮点型音频PCM转WAV格式音频指令
ffmpeg -f f32be -ar 16000 -ac 1 -i record.pcm -ar 16000 -ac 1 record.wav
查看ffmepg可以解析的格式指令
ffmpeg -formats
DE f32be PCM 32-bit floating-point big-endian
DE f32le PCM 32-bit floating-point little-endian
DE f64be PCM 64-bit floating-point big-endian
DE f64le PCM 64-bit floating-point little-endian
DE s16be PCM signed 16-bit big-endian
DE s16le PCM signed 16-bit little-endian
DE s24be PCM signed 24-bit big-endian
DE s24le PCM signed 24-bit little-endian
DE s32be PCM signed 32-bit big-endian
DE s32le PCM signed 32-bit little-endian
DE u16be PCM unsigned 16-bit big-endian
DE u16le PCM unsigned 16-bit little-endian
DE u24be PCM unsigned 24-bit big-endian
DE u24le PCM unsigned 24-bit little-endian
DE u32be PCM unsigned 32-bit big-endian
DE u32le PCM unsigned 32-bit little-endian
最后
以上就是隐形红酒为你收集整理的Android如何将采集到的音频PCM文件转为WAV并保存1.Android音频采集2.PCM文件转WAV的全部内容,希望文章能够帮你解决Android如何将采集到的音频PCM文件转为WAV并保存1.Android音频采集2.PCM文件转WAV所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复