前言
一点背景:
当你被sox的编译搞的要摔东西的时候,我们为什么不自己绑架一个wav
我们将用代码一遍遍的,征服它
如果你使用了ffmepg,并且热爱上了,图片+音频->视频,那么,请告诉我,我可以通过调用1次api,来完成 多个图片+多个声音->1个视频 吗?(android调用ffmpeg,是非常慢的,所以,如果你找到了该方法,欢迎告诉我)
我们将说点什么:
1.wav的header,请你热爱PCM
2.wav的裁剪
3.wav的合并
4.silence wav
5.wav的音量调整
6.wav的语速调整
正文
关于第1-4点,请参照:图片+音频->视频
关于第5点,
我们为什么要谈第5点,原因,可能有很多,谈谈我的情况:我录制了人声,但是,播起来,声音却非常的小
本质上,调节音量,是对data中的sample进行放大缩小。如,你要提高音量为其3倍,那么,就使每个sample的值变成其3倍
关于第6点
我们为什么要谈第6点,原因,可能有很多(android提供了SoundPool来进行变速播放,所以,为何还要再多此一举呢),谈谈我的情况:我录制了人声,我要将该音频进行变速,然后保存,以在“图片+声音->视频”中用到
本质上,调节语速,就是删除一些sample。如,你要将语速变为其3倍,那么就每3个sample中,删除3-1个sample,保留1个sample。也许,你感觉不靠谱,但我的实验结果还算令人满意
关于第x点
如果你知道如何改变 音色啊 等声音专有的属性,那么请告诉我,或者发布一个开源的API
赠品
关于第5,6点,我提供如下代码,欢迎使用
byte[] data = new byte[1024];int len = -1;
// 变速相关
long count = 0;
long readByte = 0;
long rightPosition = 0;
InputStream fis = {你的源声音文件的is};
FileOutputStream fos = {你的目标文件的fos,之前已经写入了header了,别忘了最后再更新header};
while ((len = fis.read(data)) != -1) {
// 你不会将刚刚操纵的每个byte直接写入到fos,那会非常非常的慢
// 给你提供一个解决方法,一次写入bos.toByteArray()
ByteArrayOutputStream bos = new ByteArrayOutputStream();
for (int i = 0; i < len; i += 2) {
// 变速
long position = readByte + i;
if (position == rightPosition) {
// 提高音量
int low = data[i] & 0xff;
int high = data[i + 1] & 0xff;
int value = (high << 8) + low;
value *= VOICE_VOLUMN;
// if (value < -0x8000) {
// value = -0x8000;
// } else if (value > 0x7FFF) {
// value = 0x7FFF;
// }
data[i] = (byte) (value & 0xff);
data[i + 1] = (byte) ((value >> 8) & 0xff);
bos.write(data[i] & 0xff);
bos.write(data[i + 1] & 0xff);
count++;
rightPosition = ((long) (count * VOICE_SPEED)) * 2;
}
}
bos.flush();
fos.write(bos.toByteArray());
fos.flush();
bos.close();
readByte += len;
}
fis.close();
fos.close();