我正在研究java中的一个音频项目,它要求我根据数据确定音频文件类型(而不是文件扩展名),而且我已经用MP3播放了一个墙。据我了解,MP3文件被分成几帧,每帧有一个4字节的标题,包含11个用于帧同步和各种其他数据。现在我的代码可以准确识别WAVE文件,但是当我开始阅读我的测试MP3文件的字节时,我无法在任何地方找到11111111字节(11个帧同步位中的前8个)。
try {
FileInputStream fis = new FileInputStream(f);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buff = new byte[11];
byte[] byteData;
int bytes = 0;
while ((bytes = fis.read(buff)) != -1) {
baos.write(buff, 0, buff.length);
}
byteData = baos.toByteArray();
fis.close();
baos.close();
if ((int)byteData[0] == 255) {
type = "MP3";
} else if (("" + (char)byteData[8] + (char)byteData[9] +
(char)byteData[10] + (char)byteData[11]) == "WAVE") {
type = "WAVE";
}
}
答案 0 :(得分:2)
您可能会发现MP3文件的前三个字节是:
49 44 33
这是带有ID3v2标签的MP3的“神奇数字”.... at least according to wikipedia
修改
好的,所以我查看了我的系统,我的MP3中包含了幻数:
73 68 51
在ascii中是'ID3'。
请注意,您的字节操作存在一些问题....当您针对int值测试字节值时,您需要确保转换正确....测试:
byte x = ....;
if (x == 255) {...}
对于任何'x'值,永远不会成立,因为(byte)x
的范围是-128到+127。
要使此测试工作,您需要执行以下操作:
if ((x & 0xff) == 255) { .... }
我已经修改了你的方法来测试我的系统上的东西,并尝试了一个WAV文件和几个MP3。这是我的代码:
public static final String getValid(File f) throws IOException {
FileInputStream fis = new FileInputStream(f);
byte[] buff = new byte[12];
int bytes = 0, pos = 0;
while (pos < buff.length && (bytes = fis.read(buff, pos, buff.length - pos)) > 0) {
pos += bytes;
}
fis.close();
// this is your test.... which should bitmask the value too:
if ((buff[0] & 0x000000ff) == 255) {
return "MP3 " + f;
}
// My testing indicates this is the MP3 magic number
if ( 'I' == (char)buff[0]
&& 'D' == (char)buff[1]
&& '3' == (char)buff[2]) {
return "MP3 ID3 Magic" + f;
}
// This is the magic number from wikipedia (spells '1,!')
if (49 == buff[0] && 44 == buff[1] && 33 == buff[2]) {
return "MP3 ID3v2" + f;
}
if ( 'W' == (char)buff[8]
&& 'A' == (char)buff[9]
&& 'V' == (char)buff[10]
&& 'E' == (char)buff[11]) {
return "WAVE " + f;
}
return "unknown " + f;
}