-1

我需要找到存储宽度和高度的地址,但是标准的IUT版本没有给出文件格式的明确定义。

到目前为止我发现了什么......:

  • 这两个值都存储在“一个 QuickTime 浮点数”中。我找不到格式,但它似乎使用两个 16 位整数:一个有符号整数,后跟一个无符号整数。
  • 与许多文件格式不同,它没有固定的位置,因此是文件特定的。它取决于 TrackHeaderBox 地址。

我迫切需要的:

一个明确的规范答案,描述了只能找到这些信息的地方。我不希望只引用第三方库的答案 (除非它们是用正确的 JavaScript 编写的)。一些类似 C 的伪结构可以提供帮助。

4

1 回答 1

1

没有固定的位置。您需要解析到文件中。请检查这个 Java 示例。

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;


public class GetHeight {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream(new File(args[0]));

        GetHeight ps = new GetHeight();
        ps.find(fis);
    }

    byte[] lastTkhd;

    private void find(InputStream fis) throws IOException {

        while (fis.available() > 0) {
            byte[] header = new byte[8];
            fis.read(header);

            long size = readUint32(header, 0);
            String type = new String(header, 4, 4, "ISO-8859-1");
            if (containers.contains(type)) {
                find(fis);
            } else {
                if (type.equals("tkhd")) {
                    lastTkhd = new byte[(int) (size - 8)];
                    fis.read(lastTkhd);
                } else {
                    if (type.equals("hdlr")) {
                        byte[] hdlr = new byte[(int) (size - 8)];
                        fis.read(hdlr);
                        if (hdlr[8] == 0x76 && hdlr[9] == 0x69 && hdlr[10] == 0x64 && hdlr[11] == 0x65) {
                            System.out.println("Video Track Header identified");
                            System.out.println("width: " + readFixedPoint1616(lastTkhd, lastTkhd.length - 8));
                            System.out.println("height: " + readFixedPoint1616(lastTkhd, lastTkhd.length - 4));
                            System.exit(1);
                        }
                    } else {
                        fis.skip(size - 8);
                    }
                }
            }
        }
    }

    public static long readUint32(byte[] b, int s) {
        long result = 0;
        result |= ((b[s + 0] << 24) & 0xFF000000);
        result |= ((b[s + 1] << 16) & 0xFF0000);
        result |= ((b[s + 2] << 8) & 0xFF00);
        result |= ((b[s + 3]) & 0xFF);
        return result;
    }

    public static double readFixedPoint1616(byte[] b, int s) {
        return ((double) readUint32(b, s)) / 65536;
    }

    List<String> containers = Arrays.asList(
            "moov",
            "mdia",
            "trak"
    );
}
于 2014-09-28T23:12:18.417 回答