我正在开发一款Android应用,可以使用mediarecorder录制语音并使用媒体播放器播放音乐。
我的目标是将两个音频混合成一个文件,因为Android不提供任何API,我正在寻找一个合理的解决方案。
此刻,在播放时我正在使用带有MIC源的新媒体录制器来捕获音频并保存,但这非常差!!!
无论如何混合音频?包括任何原生溶液lix SOX或FFMPEG?
或者,无论如何使用媒体播放器输出作为源来记录到文件而不是使用MIC?
任何建议都表示赞赏。
谢谢。
答案 0 :(得分:1)
当我遇到同样的问题时,我能够找到混合文件的解决方案。 由于无法混合两个mp3文件,您必须先将其转换为波形格式,然后设置标题值。之后添加数据字段。我是按照以下方式做到的。希望我的代码能帮到你。
class MixFile扩展了AsyncTask {
ProgressDialog dialog;
protected void onPreExecute() {
dialog= new ProgressDialog(MainActivity.this);
dialog.setCancelable(false);
dialog.setMessage("Mixing two wav files");
dialog.show();
}
@Override
protected Void doInBackground(Void... arg0) {
short[] audioData1 = null;
short[] audioData2 = null;
int n = 0;
try {
DataInputStream in1;
// in1 = new DataInputStream(new FileInputStream(Environment.getExternalStorageDirectory()+“/ Soundrecpluspro / one.wav”)); in1 = new DataInputStream(new FileInputStream(path1)); ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
while ((n = in1.read()) != -1) {
bos.write(n);
}
} catch (IOException e) {
e.printStackTrace();
}
ByteBuffer bb = ByteBuffer.wrap(bos.toByteArray());
bb.order(ByteOrder.LITTLE_ENDIAN);
ShortBuffer sb = bb.asShortBuffer();
audioData1 = new short[sb.capacity()];
for (int i = 0; i < sb.capacity(); i++) {
audioData1[i] = sb.get(i);
}
} catch (IOException e) {
e.printStackTrace();
}
try {
DataInputStream in1;
in1 = new DataInputStream(new FileInputStream(path2));
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
while ((n = in1.read()) != -1) {
bos.write(n);
}
} catch (IOException e) {
e.printStackTrace();
}
ByteBuffer bb = ByteBuffer.wrap(bos.toByteArray());
bb.order(ByteOrder.LITTLE_ENDIAN);
ShortBuffer sb = bb.asShortBuffer();
audioData2= new short[sb.capacity()];
sb.get(audioData2);
System.out.println();
} catch (IOException e) {
e.printStackTrace();
}
// find the max:
float max = 0;
Log.d("File audio lenght 1 ", ""+audioData1.length);
Log.d("File audio lenght 2 ", ""+audioData2.length);
System.out.println("MainActivity.MixFile.doInBackground() 1"+audioData1.length);
System.out.println("MainActivity.MixFile.doInBackground() 2"+audioData2.length);
if(audioData1.length > audioData2.length){
for (int i = 22; i < audioData2.length; i++) {
if (Math.abs(audioData1[i] + audioData2[i]) > max)
max = Math.abs(audioData1[i] + audioData2[i]);
}
System.out.println("" + (Short.MAX_VALUE - max));
int a, b, c;
// now find the result, with scaling:
for (int i = 22; i < audioData2.length; i++) {
a = audioData1[i];
b = audioData2[i];
c = Math.round(Short.MAX_VALUE * (audioData1[i] + audioData2[i])
/ max);
if (c > Short.MAX_VALUE)
c = Short.MAX_VALUE;
if (c < Short.MIN_VALUE)
c = Short.MIN_VALUE;
audioData1[i] = (short) c;
}
// to turn shorts back to bytes.
byte[] end = new byte[audioData1.length * 2];
ByteBuffer.wrap(end).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().put(audioData1);
try {
OutputStream out = new FileOutputStream(Environment.getExternalStorageDirectory() + "/assets/mixer12.wav");
for (int i = 0; i < end.length; i++) {
out.write(end[i]);
out.flush();
}
out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else{
System.out.println("MainActivity.MixFile.doInBackground() smaller one");
for (int i = 22; i < audioData1.length; i++) {
if (Math.abs(audioData2[i] + audioData1[i]) > max)
max = Math.abs(audioData2[i] + audioData1[i]);
}
System.out.println("" + (Short.MAX_VALUE - max));
int a, b, c;
// now find the result, with scaling:
for (int i = 22; i < audioData1.length; i++) {
a = audioData2[i];
b = audioData1[i];
c = Math.round(Short.MAX_VALUE * (audioData2[i] + audioData1[i])
/ max);
if (c > Short.MAX_VALUE)
c = Short.MAX_VALUE;
if (c < Short.MIN_VALUE)
c = Short.MIN_VALUE;
audioData2[i] = (short) c;
}
// to turn shorts back to bytes.
byte[] end = new byte[audioData2.length * 2];
ByteBuffer.wrap(end).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().put(audioData2);
try {
OutputStream out = new FileOutputStream(Environment.getExternalStorageDirectory() + "/Assets/mixer1.wav");
for (int i = 0; i < end.length; i++) {
out.write(end[i]);
out.flush();
}
out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return null;
}
在活动中我将其称为
public class MainActivity extends Activity implements OnClickListener {
new MixFile().execute();
}
此处path1和path2是您要混合的wav文件的路径