import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import io.kvh.media.amr.AmrDecoder;
import io.kvh.media.amr.AmrEncoder;
public class AmrUtil {
private static final int[] amrEncodeMode = {4750, 5150, 5900, 6700, 7400, 7950, 10200, 12200}; // amr 编码方式
private static final int AMR_FRAME_COUNT_PER_SECOND = 50;
private static int mMode = 0;
public static void change(String inPath, String outPath) {
File inFile = new File(inPath);
File outFile = new File(outPath);
if (!inFile.exists()) {
return;
}
try {
outFile.deleteOnExit();
outFile.createNewFile();
FileInputStream in = new FileInputStream(inFile);
FileOutputStream out = new FileOutputStream(outFile);
byte[] amrhead = new byte[6];// amr head 6 bytes
in.read(amrhead);
out.write(amrhead);
byte[] amrframehead = new byte[1];// amr frame head 1 bytes
in.read(amrframehead);
out.write(amrframehead);
int frameSize = caclAMRFrameSize(amrframehead[0]);
byte[] amrframecontent = new byte[frameSize - 1];// amr frame content frameSize - 1 bytes
in.read(amrframecontent);
out.write(amrframecontent);
byte[] amrframe = new byte[frameSize];// amr frame frameSize bytes
short[] pcmframe = new short[160];// pcm frame 160 shorts
long state = AmrDecoder.init();
AmrEncoder.init(0);
while (in.read(amrframe) != -1) {
AmrDecoder.decode(state, amrframe, pcmframe);
int pcmval;
for (int i = 0; i < pcmframe.length; i++) {
// 音量调节
pcmval = pcmframe[i] * 3;
if (pcmval < 32767 && pcmval > -32768) {
pcmframe[i] = (short) pcmval;
} else if (pcmval > 32767) {
pcmframe[i] = 32767;
} else if (pcmval < -32768) {
pcmframe[i] = -32768;
}
}
AmrEncoder.encode(mMode, pcmframe, amrframe);
out.write(amrframe);
}
in.close();
out.flush();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
// 根据帧头计算当前帧大小
private static int caclAMRFrameSize(byte frameHeader) {
int mode;
int temp1 = 0;
int temp2 = 0;
int frameSize;
temp1 = frameHeader; // 编码方式编号 = 帧头的3-6位 temp1 &= 0x78; // 0111-1000 temp1 >>= 3;
mMode = temp1;
mode = amrEncodeMode[temp1];
// 计算amr音频数据帧大小
// 原理: amr 一帧对应20ms,那么一秒有50帧的音频数据
temp2 = myround((double) (((double) mode / (double) AMR_FRAME_COUNT_PER_SECOND) / (double) 8));
frameSize = myround((double) temp2 + 0.5);
return frameSize;
}
private static int myround(double x) {
return ((int) (x + 0.5));
}
}
参考链接:
注:
更新了import,需要依赖opencore-amr-android才行哦!
implementation 'io.kvh:amr:1.1.1'
今天才看到某个朋友两周前发来的邮件,询问我是否有import代码。
虽然这位朋友可能不需要了吧,不过还是更新了下文章,希望能帮助到有需要的朋友。