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-包含音频帧
电影的持续时间在电影标题mvhd中。 以秒为单位的持续时间来自mvhd中的两个字段
- 4字节时标
- 4字节持续时间
持续时间(秒)=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);