2

我正在使用 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";
        }

    }
4

1 回答 1

2

您可能会发现 MP3 文件的前三个字节是:

49 44 33

这是带有 ID3v2 标签的 MP3 的“神奇数字”....至少根据维基百科

编辑

好的,所以我查看了我的系统,我拥有的 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;

}
于 2013-11-02T15:22:22.020 回答