如何阅读从.mov影片文件头(QuickTime文件格式)比特率的信息? [英] How to read the bit rate information from a .mov video file header (QuickTime File Format)?

查看:399
本文介绍了如何阅读从.mov影片文件头(QuickTime文件格式)比特率的信息?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直想读一些价值观出.mov文件(QuickTime的文件格式)与有限的成功的元数据。我一直在使用下面的链接作为参考:




介绍到QuickTime文件格式规范




我已经成功地正确定位和读出/计算时间的媒体,但我似乎无法找到该原子比特率的信息存储英寸(原子是元数据文件中的内部模块)。



如果任何人都可以点我到正确的Atom阅读,我会没事的阅读它......我似乎无法找到它的文档中,甚至。 比特率只有在整个文档中提到了几次。






更新>>>



由@szatmary下面提供的资料非常有限随缘,我已经解析了的样本大小的Atom 的和的时间到采样的Atom 的从相关的轨道凌的,但我得到一些奇怪的值。例如,我总是收到的样本大小的值 1 (从不断的比特率多个不同的单独的视频传送文件读取时的)。相关文档(从上面的链接)说:




样本量结果
的32位整数,指定样品尺寸。如果所有的样品是相同的尺寸,则此字段包含该大小的值。如果此字段设置为0,则该样品具有不同的尺寸,并且这些尺寸被存储在样本大小表。




等等领域具有 1 的值,这意味着所有样品具有相同的大小,而项数的[在样本大小表的]字段与匹配的采样计数的字段中单个条目在时间来样表的(一些非常大的数字)。的文档状态是:




...如果一个视频媒体具有恒定帧速率,该表将具有一个入口和计数将等于样本的数目。




因此,视频具有恒定比特率。不过,从的样本大小表读取尺寸条目时的,它们都是不同的,无意义的......有些是0,而有些则是非常大的数字高达约40000为什么他们不同如果视频有一个恒定比特率,或者我应该不会在这种情况下阅读它们?



这是我发现的另一个问题是,在时间样表的的的时间到采样的Atom 的有以下值:




样品计数:一些非常大的数量的(预期)结果
样品时间:1




不幸的是,文件(从上面的链接)很轻的位置:




时间对样本表结果
一表定义在媒体的每个样本的持续时间。每个表条目包含一个计数字段和持续时间字段。




那么,什么单位做这些 1 值使用(采样持续的&放大器;的样本大小的)



任何进一步的帮助计算?正确的比特率将不胜感激。请注意,我一直在服用的大端岬的文件考虑在内,并在读之前先倒车每个字段值的字节



的。< HR>

更新2 >>>



我已成功地制定出了采样速率是这样计算的:




媒体持续时间=持续时间/时间刻度(从电影首部原子轨道头的Atom 的)
采样率=采样数(从时间对样品的Atom 的)/媒体持续时间




我只需要破解的比特率的现在进一步的帮助是必要的。


解决方案

这将让你的什么的需要,的,即在Windows资源管理器中显示的比特率的,而不是从QT元数据。如果它不适合某些原因,也许这将作为备用解决方案,直到你可以制定出了Atom基于答案或东西的QT原子比较结果。



总之,如果你想要的资源管理器显示,从资源管理器中得到它:

  //添加引用微软壳牌控制和自动化
//从COM选项卡
使用SHELL32;
类ShellInfo
{

//列我们想:
//文件名= 0;
const int的PerceivedType = 9;
// FileKind = 11;
// MediaBitrate = 28;
// MediaLength = 27;
静态INT []信息= {0,9,11,27,28};

//注:作者和书名也可以

公共静态字典<字符串,字符串> GetMediaProperties(字符串文件)
{
&字典LT;字符串,字符串> XTD =新词典<字符串,字符串>();

Shell32.Shell壳=新Shell32.Shell();
Shell32.Folder文件夹;

文件夹= shell.NameSpace(Path.GetDirectoryName(文件));

的foreach(在folder.Items变种S())
{
如果(folder.GetDetailsOf(S,0).ToLowerInvariant()==
路径。用GetFileName(文件).ToLowerInvariant())
{
//看它是否是视频
//可能检查FileKind ???
如果(folder.GetDetailsOf(S,PerceivedType).ToLowerInvariant()==
视频)
{
//添加只是我们要使用列数组的那些指数
的foreach(在信息INT N)
{
xtd.Add(folder.GetDetailsOf(folder.Items(),N),
folder.GetDetailsOf(S,N) );
}
}
中断;
}
// TODO:抓狂时,它不是一个视频或音频类型
//这取决于你正在尝试做
}
返回XTD;

}
}



用法:

 词典<字符串,字符串> MyInfo的; 
MyInfo的= ShellInfo.GetMediaProperties(文件路径);



测试文件是从苹果公司的网站样本QT MOV,所以没有什么特别的地方。在资源管理器视图:







从结果 GetMediaProperties





码率退换也符合由 MediaProps 返回的音频比特率和 MediaTab (都使用 MediaInfo.DLL 来收集的所有的媒体属性值)。






第35外壳扩展属性是相当有据可查的。我觉得作为Windows 7中,这变为291(!)。许多特定于照片文件类型,电子邮件等几个其可以是感兴趣的:




282:数据速率结果,
283:框架高度结果
284:帧率结果
285:框架宽度结果
286:总码率




数据传输速率(282)是视频比特率(相匹配MediaInfo);总比特率(286)被合并A / V比特率。






Windows 8中(更新)



虽然上面的代码将出现在Windows 7上运行正常,运行Windows 8,避免电脑在 System.InvalidCastException 以下行...:

 壳牌=新的外壳(); 



...下面的代码将需要运行实例的贝壳文件夹 COM对象:

 键入外壳类型= Type.GetTypeFromProgID(Shell.Application); 
对象的shell = Activator.CreateInstance(外壳类型);
文件夹文件夹=(文件夹)shellType.InvokeMember(命名空间,
BindingFlags.InvokeMethod,空,贝壳,
新的对象[] {Path.GetDirectoryName(文件)});




实例化SHELL32。壳对象中的Visual Studio中论坛的Windows 8 的问题




此外,在Windows 8,看来多个属性已被添加,使得最大索引现在是309(少数空条目)和上述属性具有不同指数:




298 :数据传输速率结果
299:框架高度结果
300:帧率结果
301:框架宽度结果
303:总码率







似乎从SHELL32的回报中有某些字符这防止简单和直接转换到一个int值。对于比特率:

 字符串诺贝特= MyInfo的[比特率]; //获取返回VAL 
诺贝特=新的字符串(bRate.Where(char.IsDigit).ToArray()); //收拾

INT比特率= Convert.ToInt32(诺贝特);


I've been trying to read some values out of the metadata of a .mov file (QuickTime File Format) with limited success. I've been using the following link as a reference:

Introduction to QuickTime File Format Specification

I've managed to correctly locate and read out/calculate the media duration, but I can't seem to find which Atom the Bit Rate information is stored in. (Atoms are the internal blocks of metadata inside the file).

If anyone can point me to the correct Atom to read, I'll be alright reading it... I just can't seem to find it in the documentation even. "Bit Rate" is only mentioned a couple of times in the whole document.


UPDATE >>>

Going by the very limited information provided below by @szatmary, I have parsed the Sample Size Atom and the Time to Sample Atom from the relevant Track Atom, but am getting some bizarre values. For example, I keep getting a Sample Size value of 1 (when reading from multiple different single video .mov files with constant Bit Rates). The related documentation (from the above link) says:

Sample size
A 32-bit integer specifying the sample size. If all the samples are the same size, this field contains that size value. If this field is set to 0, then the samples have different sizes, and those sizes are stored in the sample size table.

So the field has the value of 1, which means that all samples have the same size, and the Number of entries [in the Sample Size Table] field matches that of the Sample Count field in the single entry of the Time to Sample Table (some very large number). The documentation states this:

... if a video media has a constant frame rate, this table would have one entry and the count would be equal to the number of samples.

So the video has a constant Bit Rate. However, when reading the size entries from the Sample Size Table, they are all different and non-sensical... some are 0, while others are very large numbers up to around 40000. Why are they different if the video has a constant Bit Rate, or should I not be reading them in this case?

Another issue that I have found is that the single entry in the Time to Sample Table of the Time to Sample Atom has the following values:

Sample Count: some very large number (expected)
Sample Duration: 1

Unfortunately the documentation (from the above link) is very light here:

Time-to-sample table
A table that defines the duration of each sample in the media. Each table entry contains a count field and a duration field.

So what units do these 1 values use (Sample Duration & Sample Size)?

Any further help with calculating the correct Bit Rate would be greatly appreciated. Please note that I have been taking the Big-Endian-ness of the file into consideration and reversing the bytes of each field value before reading them.


UPDATE 2 >>>

I have managed to work out that the Sampling Rate is calculated like this:

Media Duration = Duration / Timescale (from the Movie Header Atom or Track Header Atom) Sampling Rate = Sample Count (from the Time-to-Sample Atom) / Media Duration

I just need to crack the Bit Rate now and further help is needed.

解决方案

This will get you what you want, "The Bit Rate that is shown in Windows Explorer", but not from the QT metadata. If it is not appropriate for some reason, maybe it will work as a fallback solution until you can work out the Atom based answer or as something to compare the QT Atom results to.

In short, if you want what Explorer shows, get it from Explorer:

// add reference to Microsoft Shell controls and Automation
// from the COM tab
using Shell32;
class ShellInfo
{

    // "columns" we want:
    // FileName = 0;
    const int PerceivedType = 9;
    // FileKind = 11;
    // MediaBitrate = 28;
    // MediaLength = 27;
    static int[] info = {0, 9, 11, 27, 28};

    // note: author and title also available

    public static Dictionary<string, string> GetMediaProperties(string file)
    {
        Dictionary<string, string> xtd = new Dictionary<string, string>();

        Shell32.Shell shell = new Shell32.Shell();
        Shell32.Folder folder;

        folder = shell.NameSpace(Path.GetDirectoryName(file));

        foreach (var s in folder.Items())
        {
            if (folder.GetDetailsOf(s, 0).ToLowerInvariant() ==
                    Path.GetFileName(file).ToLowerInvariant())
            {
                // see if it is video
                // possibly check FileKind ???
                if (folder.GetDetailsOf(s, PerceivedType).ToLowerInvariant() ==
                                "video")
                { 
                    // add just the ones we want using the array of col indices 
                    foreach (int n in info)
                    {
                        xtd.Add(folder.GetDetailsOf(folder.Items(), n),
                            folder.GetDetailsOf(s, n));
                    }                 
                }
                break;
            }
            // ToDo:  freak out when it is not a video or audio type
            // depending what you are trying to do
        }
        return xtd;

    }
}

Usage:

Dictionary<string, string> myinfo;
myinfo = ShellInfo.GetMediaProperties(filepath);

The test file is a sample QT mov from Apple's site, so there is nothing special about it. The view in Explorer:

The results from GetMediaProperties:

The BitRate returned also matched the Audio BitRate returned by MediaProps and MediaTab (both use MediaInfo.DLL to gather all media property values).


The first 35 Shell extended properties are pretty well documented. I think as of Windows 7, this goes to 291(!). Many are file type specific for photos, emails etc. A few which may be of interest:

282: Data rate
283: Frame height
284: Frame rate
285: Frame width
286: Total bitrate

Data rate (282) is the Video BitRate (matches MediaInfo) ; Total Bitrate (286) is the combined a/v bitrate.


Windows 8 (UPDATE)

While the above code appears to run OK on Windows 7, for computers running Windows 8, to avoid a System.InvalidCastException on the following line...:

Shell shell = new Shell();

... the following code will need to be run to instantiate the Shell and Folder COM objects:

Type shellType = Type.GetTypeFromProgID("Shell.Application");
Object shell = Activator.CreateInstance(shellType);
Folder folder = (Folder)shellType.InvokeMember("NameSpace", 
           BindingFlags.InvokeMethod, null, shell, 
           new object[] { Path.GetDirectoryName(file) });

Solution found in the Instantiate Shell32.Shell object in Windows 8 question on the Visual Studio Forum.

Also, on Windows 8, it appears that more attributes have been added so that the maximum index is now 309 (with a few empty entries) and the above mentioned attributes have different indices:

298: Data rate
299: Frame height
300: Frame rate
301: Frame width
303: Total bitrate


It seems the returns from Shell32 has some characters in it which prevent a simple and direct conversion to an int value. For the Bit Rate:

string bRate = myinfo["Bit rate"];       // get return val
bRate = new string(bRate.Where(char.IsDigit).ToArray());  // tidy up

int bitRate = Convert.ToInt32(bRate);

这篇关于如何阅读从.mov影片文件头(QuickTime文件格式)比特率的信息?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆