Data structures 有熟悉mp4数据结构的人吗?

Data structures 有熟悉mp4数据结构的人吗?,data-structures,video,mp4,Data Structures,Video,Mp4,其中的持续时间是多少?是一种“容器”格式,这基本上意味着它可以包含许多不同的音频或视频流。每个流都有自己的持续时间值 要挖掘出您需要的内容,您需要更多的参考文件。我可以建议你去看看。。。但是,您可能还需要搜索其他类型的A/V流,以获得您想要支持的不同类型的A/V流。这可能不是您问题的答案,但却是我的问题: (它有一个库,并且是开源的,所以你可以只检查你需要的部分)据我所知,“mp4”容器是从QuickTime atom结构派生的。您可以阅读QuickTime文件格式的说明 解析quicktime

其中的持续时间是多少?

是一种“容器”格式,这基本上意味着它可以包含许多不同的音频或视频流。每个流都有自己的持续时间值


要挖掘出您需要的内容,您需要更多的参考文件。我可以建议你去看看。。。但是,您可能还需要搜索其他类型的A/V流,以获得您想要支持的不同类型的A/V流。

这可能不是您问题的答案,但却是我的问题:

(它有一个库,并且是开源的,所以你可以只检查你需要的部分)

据我所知,“mp4”容器是从QuickTime atom结构派生的。您可以阅读QuickTime文件格式的说明

解析quicktime原子不是什么大问题(请看)。我不确定MP4,但对于MOV文件,在“mvhd”(电影头)atom和“tkhd”(曲目头)atom中都有一个“duration”(持续时间)字段。此持续时间通常是帧数乘以“时间刻度”属性。
时间刻度可以在相同的原子中找到。

对于Red5 MP4阅读器,我使用了“mvhd”原子,因为它同时包含时间刻度和持续时间字段。根据所使用的版本,从atom获取持续时间会有所不同,下面您可以看到一个示例:

公共长创建完整原子(MP4DataStream比特流)引发IOException{
长值=比特流。读取字节(4);
版本=(int)值>>24;
标志=(int)值&0xffffff;
读数+=4;
回读;
}

公共长创建\电影\头\原子(MP4DataStream位流)引发IOException{ 创建完整的原子(比特流); 如果(版本==1){ creationTime=createDate(bitstream.readBytes(8)); modificationTime=createDate(bitstream.readBytes(8)); timeScale=(int)位流。readBytes(4); 持续时间=比特流。读取字节(8); 读数+=28; }否则{ creationTime=createDate(bitstream.readBytes(4)); modificationTime=createDate(bitstream.readBytes(4)); timeScale=(int)位流。readBytes(4); 持续时间=比特流。读取字节(4); 读数+=16; } int qt_preferredRate=(int)位流.readBytes(4); int qt_preferredVolume=(int)位流.readBytes(2); 字节(10); 长qt_matrixA=比特流.readBytes(4); long qt_matrixB=比特流.readBytes(4); long qt_matrixU=比特流.readBytes(4); long qt_matrixC=比特流.readBytes(4); long qt_matrixD=比特流.readBytes(4); long qt_matrixV=比特流.readBytes(4); 长qt_matrixX=比特流。读取字节(4); 长qt_matrixY=比特流。读取字节(4); 长qt_matrixW=比特流。读取字节(4); long qt_previewTime=bitstream.readBytes(4); 长qt_previewDuration=比特流。读取字节(4); long qt_posterTime=位流.readBytes(4); long qt_selectionTime=比特流。读取字节(4); long qt_selectionDuration=比特流。读取字节数(4); 长qt_currentTime=比特流。读取字节(4); long nextTrackID=比特流.readBytes(4); 读数+=80;
返回已读;
}

在旁注中,我使用这些值来计算播放时间和fps,如下所示:

双fps=(videoSampleCount*时间刻度)/(双)持续时间;
双视频时间=((双)持续时间/(双)时间刻度);

videoSampleCount变量来自“stsz”atom。可以使用媒体盒查看器。它是MP4和Quicktime解析器。打开Quicktime文件时,可以看到atom结构。寻找视频描述。其属性之一是持续时间。媒体盒查看器可从下载。

请参阅项目。它是一个Java库,显示mp4文件的结构。

如前一张海报所述,使用MP4Parser-它们甚至有一个提供持续时间的示例:


基本上,MP4结构是一棵树。 宏观领域包括:

  • ftyp-文件类型
  • moov-包含元数据(歌曲标题、自动收录、url和其他信息)
  • 空闲-空白区域,用于分隔标题和数据
  • mdat-包含音频帧
你可以试试这个免费的MP4分析器工具


电影的持续时间在电影标题mvhd中。 以秒为单位的持续时间来自mvhd中的两个字段

  • 4字节时标
  • 4字节持续时间
这些是@Tom Brito发布的规范中的第380行和第382行

因此,给定时间刻度“ts”和持续时间“dur”

持续时间(秒)=dur/ts

在文档中搜索持续时间。头文件的长度不是8字节(版本1)就是4字节。@MichaelTodd是我做的,文件中有很多持续时间。如果没有人知道答案,我会阅读整个文档以更好地理解。相关(这是Java):也许你可以看看VLC/mplayer/insert-open-source-mp4-player-name源代码,看看它是如何计算持续时间的?@lepple mp4和avi是相同的结构?我不再寻找这个,但这可能是这里最好的答案。比mediainfo提供更多有关原子的详细信息 public long create_full_atom(MP4DataStream bitstream) throws IOException { long value = bitstream.readBytes(4); version = (int)value >> 24; flags = (int)value & 0xffffff; readed += 4; return readed; }

public long create_movie_header_atom(MP4DataStream bitstream) throws IOException { create_full_atom(bitstream); if (version == 1) { creationTime = createDate(bitstream.readBytes(8)); modificationTime = createDate(bitstream.readBytes(8)); timeScale = (int)bitstream.readBytes(4); duration = bitstream.readBytes(8); readed += 28; } else { creationTime = createDate(bitstream.readBytes(4)); modificationTime = createDate(bitstream.readBytes(4)); timeScale = (int)bitstream.readBytes(4); duration = bitstream.readBytes(4); readed += 16; } int qt_preferredRate = (int)bitstream.readBytes(4); int qt_preferredVolume = (int)bitstream.readBytes(2); bitstream.skipBytes(10); long qt_matrixA = bitstream.readBytes(4); long qt_matrixB = bitstream.readBytes(4); long qt_matrixU = bitstream.readBytes(4); long qt_matrixC = bitstream.readBytes(4); long qt_matrixD = bitstream.readBytes(4); long qt_matrixV = bitstream.readBytes(4); long qt_matrixX = bitstream.readBytes(4); long qt_matrixY = bitstream.readBytes(4); long qt_matrixW = bitstream.readBytes(4); long qt_previewTime = bitstream.readBytes(4); long qt_previewDuration = bitstream.readBytes(4); long qt_posterTime = bitstream.readBytes(4); long qt_selectionTime = bitstream.readBytes(4); long qt_selectionDuration = bitstream.readBytes(4); long qt_currentTime = bitstream.readBytes(4); long nextTrackID = bitstream.readBytes(4); readed += 80;
return readed;
} double fps = (videoSampleCount * timeScale) / (double) duration; double videoTime = ((double) duration / (double) timeScale);