网上代码时长不准
从网上搜这个标题,基本上搜出来的就是这段代码(如果你们用这段代码没问题就不用往后看了):
public static int getAmrDuration(File file) throws IOException {
long duration = -1;
int[] packedSize = { 12, 13, 15, 17, 19, 20, 26, 31, 5, 0, 0, 0, 0, 0,
0, 0 };
RandomAccessFile randomAccessFile = null;
try {
randomAccessFile = new RandomAccessFile(file, "rw");
long length = file.length();// 文件的长度
int pos = 6;// 设置初始位置
int frameCount = 0;// 初始帧数
int packedPos = -1;
byte[] datas = new byte[1];// 初始数据值
while (pos <= length) {
randomAccessFile.seek(pos);
if (randomAccessFile.read(datas, 0, 1) != 1) {
duration = length > 0 ? ((length - 6) / 650) : 0;
break;
}
packedPos = (datas[0] >> 3) & 0x0F;
pos += packedSize[packedPos] + 1;
frameCount++;
}
duration += frameCount * 20;// 帧数*20
} finally {
if (randomAccessFile != null) {
randomAccessFile.close();
}
}
return (int)((duration/1000)+1);
}
但我发现我读取到的时长并不正确,但也不是完全不正确
比如,我检测4个音频,发现代码结果和时长分别为:
实际时长 | 代码结果 |
---|---|
6秒 | 24 |
9秒 | 35 |
99 | 365 |
48 | 178 |
上述代码调整
因为没搞懂这段代码的意思,所以只能通过这种方式解决
根据上面我采集到的样本,绘制成散点图,如下:
很明显,他们是成线性关系的,这样就可以很容易的推算出该直线的方程:
代
码
结
果
=
11
3
×
实
际
时
长
+
2
代码结果 = \frac{11}{3} \times 实际时长 + 2
代码结果=311×实际时长+2
所以,实际时长为:
实
际
时
长
=
3
×
(
代
码
结
果
−
2
)
11
实际时长 = \frac{3\times(代码结果-2) }{11}
实际时长=113×(代码结果−2)
最终调整最后几行代码:
public static int getAmrDuration(File file) throws IOException {
long duration = -1;
int[] packedSize = { 12, 13, 15, 17, 19, 20, 26, 31, 5, 0, 0, 0, 0, 0,
0, 0 };
RandomAccessFile randomAccessFile = null;
try {
randomAccessFile = new RandomAccessFile(file, "rw");
long length = file.length();// 文件的长度
int pos = 6;// 设置初始位置
int frameCount = 0;// 初始帧数
int packedPos = -1;
byte[] datas = new byte[1];// 初始数据值
while (pos <= length) {
randomAccessFile.seek(pos);
if (randomAccessFile.read(datas, 0, 1) != 1) {
duration = length > 0 ? ((length - 6) / 650) : 0;
break;
}
packedPos = (datas[0] >> 3) & 0x0F;
pos += packedSize[packedPos] + 1;
frameCount++;
}
duration += frameCount * 20;// 帧数*20
} finally {
if (randomAccessFile != null) {
randomAccessFile.close();
}
}
int x = (int)((duration/1000)+1);
return 3 * (x - 2) / 11; // 单位为秒
}