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代码。
虽然这位朋友可能不需要了吧,不过还是更新了下文章,希望能帮助到有需要的朋友。