Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/video/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Video 在MP4文件中解压缩采样时间表(STTS)_Video_Ffmpeg_Hex_Mp4_Compression - Fatal编程技术网

Video 在MP4文件中解压缩采样时间表(STTS)

Video 在MP4文件中解压缩采样时间表(STTS),video,ffmpeg,hex,mp4,compression,Video,Ffmpeg,Hex,Mp4,Compression,我有一个mp4视频字节数组,我需要使用它的中间帧为它生成一个缩略图(例如,如果视频长度为10秒,那么我需要从第5秒开始获取图片) 我设法解析了文件并提取了它的框(atom)。我还设法从mvhd盒中获取视频长度。我还设法提取了 1.从stts框采样表的时间, 2.stcs框中的样本到区块表, 3.stco框中的块偏移表, 4.stsz盒中的样本量表, 5.从stss框同步示例表 我知道所有实际的介质都在mdat框中,我需要关联上表以找到文件中的精确帧偏移量,但我的问题是如何关联?表的数据似乎被压缩

我有一个mp4视频字节数组,我需要使用它的中间帧为它生成一个缩略图(例如,如果视频长度为10秒,那么我需要从第5秒开始获取图片)

我设法解析了文件并提取了它的框(atom)。我还设法从mvhd盒中获取视频长度。我还设法提取了 1.从stts框采样表的时间, 2.stcs框中的样本到区块表, 3.stco框中的块偏移表, 4.stsz盒中的样本量表, 5.从stss框同步示例表

我知道所有实际的介质都在mdat框中,我需要关联上表以找到文件中的精确帧偏移量,但我的问题是如何关联?表的数据似乎被压缩了(特别是采样表的时间),但我不知道如何解压缩它们

感谢您的帮助

下面是代码示例

将字节转换为十六进制的代码

public static char[] bytesToHex(byte[] bytes) {
    char[] hexChars = new char[bytes.length * 2];
    for ( int j = 0; j < bytes.length; j++ ) {
        int v = bytes[j] & 0xFF;

        hexChars[j * 2] = hexArray[v >>> 4];
        hexChars[j * 2 + 1] = hexArray[v & 0x0F];            
    }
    return hexChars;
}
获取样本表时间的代码

static int[][] getTimeToSampleTable(char[] s, int trakOffset) {
    int offset = getBox(s, trakOffset, MOOV_TRAK_MDIA_MINF_STBL_STTS);
    int sizeStart = offset*2;
    int sizeEnd   = offset*2 + (4)*2;

    int typeStart = offset*2 + (4)*2;
    int typeEnd   = offset*2 + (4 + 4)*2;

    int noOfEntriesStart = offset*2 + (4 + 4 + 1 + 3)*2;
    int noOfEntriesEnd   = offset*2 + (4 + 4 + 1 + 3 + 4)*2;

    String sizeHex = new String(Arrays.copyOfRange(s, sizeStart, sizeEnd));
    String typeHex = new String(Arrays.copyOfRange(s, typeStart, typeEnd));
    String noOfEntriesHex = new String(Arrays.copyOfRange(s, noOfEntriesStart, noOfEntriesEnd));

    int size = Integer.parseInt(sizeHex, 16);
    int noOfEntries = Integer.parseInt(noOfEntriesHex, 16);

    int[][] timeToSampleTable = new int[noOfEntries][2];

    for (int i = 0; i<noOfEntries; i++) {
        int sampleCountStart = noOfEntriesEnd + ((i)*((4 + 4)*2));
        int sampleCountEnd   = noOfEntriesEnd + ((i)*((4 + 4)*2)) + (4)*2;

        int sampleDurationStart = noOfEntriesEnd + ((i)*((4 + 4)*2)) + (4)*2;
        int sampleDurationEnd   = noOfEntriesEnd + ((i)*((4 + 4)*2)) + (4 + 4)*2;

        String sampleCountHex = new String(Arrays.copyOfRange(s, sampleCountStart, sampleCountEnd));
        String sampleDurationHex = new String(Arrays.copyOfRange(s, sampleDurationStart, sampleDurationEnd));

        timeToSampleTable[i][0] = Integer.parseInt(sampleCountHex, 16);
        timeToSampleTable[i][1] = Integer.parseInt(sampleDurationHex, 16);
    }

    return timeToSampleTable;
} 
static int[][]getTimeToSampleTable(char[]s,int-trakOffset){
int offset=getBox(s,trakOffset,MOOV_TRAK_MDIA_MINF_STBL_STTS);
int sizeStart=偏移量*2;
int SIZEND=偏移量*2+(4)*2;
int typeStart=偏移量*2+(4)*2;
int typeEnd=偏移量*2+(4+4)*2;
int noofentriessstart=偏移量*2+(4+4+1+3)*2;
int noOfEntriesEnd=偏移量*2+(4+4+1+3+4)*2;
String sizeHex=新字符串(Arrays.copyOfRange(s、sizeStart、sizend));
String typeHex=新字符串(Arrays.copyOfRange(s,typeStart,typeEnd));
String noOfEntriesHex=新字符串(Arrays.copyOfRange(s,noOfEntriesStart,noOfEntriesEnd));
int size=Integer.parseInt(sizeHex,16);
int noOfEntries=Integer.parseInt(noOfEntriesHex,16);
int[][]timeToSampleTable=新int[noOfEntries][2];

对于(int i=0;iISO/IEC 14496-12标准描述了您需要的所有步骤。 附录7提供了解码步骤。第8节描述了这些表


希望这能有所帮助。

嗨,你找到解决办法了吗?还不是很不幸
static int[] getDuration(char[] s) {
    int mvhdOffset = getBox(s, 0, MOOV_MVHD);
    int timeScaleStart = (mvhdOffset*2) + (4 + 4 + 1 + 3 + 4 + 4)*2;
    int timeScaleEnd   = (mvhdOffset*2) + (4 + 4 + 1 + 3 + 4 + 4 + 4)*2;

    int durationStart  = (mvhdOffset*2) + (4 + 4 + 1 + 3 + 4 + 4 + 4)*2;
    int durationEnd    = (mvhdOffset*2) + (4 + 4 + 1 + 3 + 4 + 4 + 4 + 4)*2;

    String timeScaleHex = new String(Arrays.copyOfRange(s, timeScaleStart, timeScaleEnd));
    String durationHex = new String(Arrays.copyOfRange(s, durationStart, durationEnd));

    int timeScale = Integer.parseInt(timeScaleHex, 16);
    int duration = Integer.parseInt(durationHex, 16);

    int[] result = {duration, timeScale};
    return result;
}
static int[][] getTimeToSampleTable(char[] s, int trakOffset) {
    int offset = getBox(s, trakOffset, MOOV_TRAK_MDIA_MINF_STBL_STTS);
    int sizeStart = offset*2;
    int sizeEnd   = offset*2 + (4)*2;

    int typeStart = offset*2 + (4)*2;
    int typeEnd   = offset*2 + (4 + 4)*2;

    int noOfEntriesStart = offset*2 + (4 + 4 + 1 + 3)*2;
    int noOfEntriesEnd   = offset*2 + (4 + 4 + 1 + 3 + 4)*2;

    String sizeHex = new String(Arrays.copyOfRange(s, sizeStart, sizeEnd));
    String typeHex = new String(Arrays.copyOfRange(s, typeStart, typeEnd));
    String noOfEntriesHex = new String(Arrays.copyOfRange(s, noOfEntriesStart, noOfEntriesEnd));

    int size = Integer.parseInt(sizeHex, 16);
    int noOfEntries = Integer.parseInt(noOfEntriesHex, 16);

    int[][] timeToSampleTable = new int[noOfEntries][2];

    for (int i = 0; i<noOfEntries; i++) {
        int sampleCountStart = noOfEntriesEnd + ((i)*((4 + 4)*2));
        int sampleCountEnd   = noOfEntriesEnd + ((i)*((4 + 4)*2)) + (4)*2;

        int sampleDurationStart = noOfEntriesEnd + ((i)*((4 + 4)*2)) + (4)*2;
        int sampleDurationEnd   = noOfEntriesEnd + ((i)*((4 + 4)*2)) + (4 + 4)*2;

        String sampleCountHex = new String(Arrays.copyOfRange(s, sampleCountStart, sampleCountEnd));
        String sampleDurationHex = new String(Arrays.copyOfRange(s, sampleDurationStart, sampleDurationEnd));

        timeToSampleTable[i][0] = Integer.parseInt(sampleCountHex, 16);
        timeToSampleTable[i][1] = Integer.parseInt(sampleDurationHex, 16);
    }

    return timeToSampleTable;
}