如何从 .mov 视频文件头(QuickTime 文件格式)中读取比特率信息?
How to read the bit rate information from a .mov video file header (QuickTime File Format)?
我一直试图从 .mov 文件(QuickTime 文件格式)的元数据中读取一些值,但收效甚微。我一直在使用以下 link 作为参考:
我已经设法正确定位并读取 out/calculate 媒体持续时间,但我似乎无法找到比特率信息存储在哪个 Atom 中。(Atom 是内部元数据块文件)。
如果有人能指出我要阅读的正确 Atom,我会很好地阅读它...我什至似乎无法在文档中找到它。 "Bit Rate" 在整个文档中只提到了几次。
更新>>>
根据@szatmary 在下面提供的非常有限的信息,我已经解析了 Sample Size Atom 和 Time to Sample Atom来自相关的 Track Atom,但我得到了一些奇怪的值。例如,我不断得到 Sample Size 值 1
(当从多个不同的单一视频 .mov 文件中读取常量 Bit Rates).相关文档(来自上面link)说:
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.
所以该字段的值为1
,这意味着所有样本具有相同的大小,条目数 [在Sample Size Table] 字段与 Time to Sample Table 的单个条目中的 Sample Count 字段相匹配](一些非常大的数字)。文档说明了这一点:
... 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.
因此视频具有恒定的比特率。然而,当从 样本大小 Table 中读取大小条目时,它们都是不同的并且没有意义......有些是 0,而有些是非常大的数字大约 40000。如果视频具有恒定比特率,为什么它们不同,或者在这种情况下我不应该阅读它们?
我发现的另一个问题是 Time to Sample Table 和 Time to Sample Atom[=65] 中的单个条目=] 具有以下值:
Sample Count: some very large number (expected)
Sample Duration: 1
不幸的是,这里的文档(来自上面 link)非常简单:
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.
那么这些 1
值使用什么单位(样本持续时间 & 样本大小)?
如能进一步帮助计算正确的比特率,我们将不胜感激。请注意,我一直在考虑文件的 Big-Endian-ness 并在读取它们之前反转每个字段值的字节。
更新 2 >>>
我已经设法计算出采样率是这样计算的:
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
我现在只需要破解比特率,还需要进一步的帮助。
它没有记录在任何地方。作为一般规则,存储可以从其他值计算的值是不好的做法。另外,同一视频的比特率会随着时间的推移而变化。您可以做的是将您对 stsz 框感兴趣的帧的大小(原子在 iso 标准中称为框)和来自 stts 框的样本持续时间和数学相加。
这会 你想要什么,"The Bit Rate that is shown in Windows Explorer",但不是来自 QT 元数据。如果由于某种原因它不合适,也许它可以作为后备解决方案,直到您可以计算出基于 Atom 的答案或作为与 QT Atom 结果进行比较的东西。
简而言之,如果您想要资源管理器显示的内容,请从资源管理器中获取:
// 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;
}
}
用法:
Dictionary<string, string> myinfo;
myinfo = ShellInfo.GetMediaProperties(filepath);
测试文件是Apple网站上的示例QT mov,因此没有什么特别之处。资源管理器中的视图:
来自 GetMediaProperties
的结果:
返回的比特率也匹配 MediaProps
和 MediaTab
返回的音频比特率(两者都使用 MediaInfo.DLL
收集 所有 媒体 属性 个值)。
前 35 个 Shell 扩展属性都有很好的记录。我认为从 Windows 7 开始,这将达到 291(!)。许多是特定于照片、电子邮件等的文件类型。一些可能感兴趣:
282: Data rate
283: Frame height
284: Frame rate
285: Frame width
286: Total bitrate
数据速率 (282) 是视频比特率(匹配 MediaInfo);总比特率 (286) 是合并后的 a/v 比特率。
Windows 8(更新)
虽然上面的代码在Windows7上出现运行OK,对于电脑来说运行ning Windows8,避免在System.InvalidCastException
上下一行...:
Shell shell = new Shell();
...下面的代码需要运行实例化Shell
和Folder
COM对象:
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.
此外,在 Windows 8 上,似乎添加了更多属性,因此最大索引现在为 309(有一些空条目),并且上述属性具有不同的索引:
298: Data rate
299: Frame height
300: Frame rate
301: Frame width
303: Total bitrate
似乎 Shell32 中的 returns 中有一些字符阻止简单直接地转换为 int 值。对于比特率:
string bRate = myinfo["Bit rate"]; // get return val
bRate = new string(bRate.Where(char.IsDigit).ToArray()); // tidy up
int bitRate = Convert.ToInt32(bRate);
如果您可以阅读信息值(您已经有了 szatmary 的答案以获得更准确的信息),shell 通过媒体基础 MPEG-4 解析文件和读取元数据来报告这一点 属性处理程序 class.
本机 API 入口点是 PSLookupPropertyHandlerCLSID
,然后是 IPropertyStore
接口的常规 COM 实例化,然后读取属性。即使您没有 C# 接口,您也可以通过 P/Invoke 和互操作层轻松获得它。
您可以通过这种方式阅读的属性很容易被这个帮助应用程序发现,包装 API:FilePropertyStore
(Win32
, x64
)。也就是说,您通过应用程序看到的内容也可以通过提到的API获得。
这是从 .MOV 文件中获取的内容的摘录(注意 PKEY_Audio_EncodingBitrate
和 PKEY_Video_EncodingBitrate
):
## Property
* `PKEY_Media_Duration`, Length: `855000000` (`VT_UI8`) // `855,000,000`
* `PKEY_Audio_EncodingBitrate`, Bit rate: `43744` (`VT_UI4`) // `43,744`
* `PKEY_Audio_ChannelCount`, Channels: `1` (`VT_UI4`) // `1`
* `PKEY_Audio_Format`, Audio format: `{00001610-0000-0010-8000-00AA00389B71}` (`VT_LPWSTR`) // FourCC 0x00001610
* `PKEY_Audio_SampleRate`, Audio sample rate: `32000` (`VT_UI4`) // `32,000`
* `PKEY_Audio_SampleSize`, Audio sample size: `16` (`VT_UI4`) // `16`
* `PKEY_Audio_StreamNumber`: `1` (`VT_UI4`) // `1`
* `PKEY_Video_EncodingBitrate`, Data rate: `263352` (`VT_UI4`) // `263,352`
* `PKEY_Video_FrameWidth`, Frame width: `640` (`VT_UI4`) // `640`
* `PKEY_Video_FrameHeight`, Frame height: `480` (`VT_UI4`) // `480`
该方法也适用于其他媒体文件格式,通过其他容器格式的相应 属性 处理程序使用相同的密钥获取数据。
我一直试图从 .mov 文件(QuickTime 文件格式)的元数据中读取一些值,但收效甚微。我一直在使用以下 link 作为参考:
我已经设法正确定位并读取 out/calculate 媒体持续时间,但我似乎无法找到比特率信息存储在哪个 Atom 中。(Atom 是内部元数据块文件)。
如果有人能指出我要阅读的正确 Atom,我会很好地阅读它...我什至似乎无法在文档中找到它。 "Bit Rate" 在整个文档中只提到了几次。
更新>>>
根据@szatmary 在下面提供的非常有限的信息,我已经解析了 Sample Size Atom 和 Time to Sample Atom来自相关的 Track Atom,但我得到了一些奇怪的值。例如,我不断得到 Sample Size 值 1
(当从多个不同的单一视频 .mov 文件中读取常量 Bit Rates).相关文档(来自上面link)说:
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.
所以该字段的值为1
,这意味着所有样本具有相同的大小,条目数 [在Sample Size Table] 字段与 Time to Sample Table 的单个条目中的 Sample Count 字段相匹配](一些非常大的数字)。文档说明了这一点:
... 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.
因此视频具有恒定的比特率。然而,当从 样本大小 Table 中读取大小条目时,它们都是不同的并且没有意义......有些是 0,而有些是非常大的数字大约 40000。如果视频具有恒定比特率,为什么它们不同,或者在这种情况下我不应该阅读它们?
我发现的另一个问题是 Time to Sample Table 和 Time to Sample Atom[=65] 中的单个条目=] 具有以下值:
Sample Count: some very large number (expected)
Sample Duration: 1
不幸的是,这里的文档(来自上面 link)非常简单:
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.
那么这些 1
值使用什么单位(样本持续时间 & 样本大小)?
如能进一步帮助计算正确的比特率,我们将不胜感激。请注意,我一直在考虑文件的 Big-Endian-ness 并在读取它们之前反转每个字段值的字节。
更新 2 >>>
我已经设法计算出采样率是这样计算的:
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
我现在只需要破解比特率,还需要进一步的帮助。
它没有记录在任何地方。作为一般规则,存储可以从其他值计算的值是不好的做法。另外,同一视频的比特率会随着时间的推移而变化。您可以做的是将您对 stsz 框感兴趣的帧的大小(原子在 iso 标准中称为框)和来自 stts 框的样本持续时间和数学相加。
这会 你想要什么,"The Bit Rate that is shown in Windows Explorer",但不是来自 QT 元数据。如果由于某种原因它不合适,也许它可以作为后备解决方案,直到您可以计算出基于 Atom 的答案或作为与 QT Atom 结果进行比较的东西。
简而言之,如果您想要资源管理器显示的内容,请从资源管理器中获取:
// 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;
}
}
用法:
Dictionary<string, string> myinfo;
myinfo = ShellInfo.GetMediaProperties(filepath);
测试文件是Apple网站上的示例QT mov,因此没有什么特别之处。资源管理器中的视图:
来自 GetMediaProperties
的结果:
返回的比特率也匹配 MediaProps
和 MediaTab
返回的音频比特率(两者都使用 MediaInfo.DLL
收集 所有 媒体 属性 个值)。
前 35 个 Shell 扩展属性都有很好的记录。我认为从 Windows 7 开始,这将达到 291(!)。许多是特定于照片、电子邮件等的文件类型。一些可能感兴趣:
282: Data rate
283: Frame height
284: Frame rate
285: Frame width
286: Total bitrate
数据速率 (282) 是视频比特率(匹配 MediaInfo);总比特率 (286) 是合并后的 a/v 比特率。
Windows 8(更新)
虽然上面的代码在Windows7上出现运行OK,对于电脑来说运行ning Windows8,避免在System.InvalidCastException
上下一行...:
Shell shell = new Shell();
...下面的代码需要运行实例化Shell
和Folder
COM对象:
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.
此外,在 Windows 8 上,似乎添加了更多属性,因此最大索引现在为 309(有一些空条目),并且上述属性具有不同的索引:
298: Data rate
299: Frame height
300: Frame rate
301: Frame width
303: Total bitrate
似乎 Shell32 中的 returns 中有一些字符阻止简单直接地转换为 int 值。对于比特率:
string bRate = myinfo["Bit rate"]; // get return val
bRate = new string(bRate.Where(char.IsDigit).ToArray()); // tidy up
int bitRate = Convert.ToInt32(bRate);
如果您可以阅读信息值(您已经有了 szatmary 的答案以获得更准确的信息),shell 通过媒体基础 MPEG-4 解析文件和读取元数据来报告这一点 属性处理程序 class.
本机 API 入口点是 PSLookupPropertyHandlerCLSID
,然后是 IPropertyStore
接口的常规 COM 实例化,然后读取属性。即使您没有 C# 接口,您也可以通过 P/Invoke 和互操作层轻松获得它。
您可以通过这种方式阅读的属性很容易被这个帮助应用程序发现,包装 API:FilePropertyStore
(Win32
, x64
)。也就是说,您通过应用程序看到的内容也可以通过提到的API获得。
这是从 .MOV 文件中获取的内容的摘录(注意 PKEY_Audio_EncodingBitrate
和 PKEY_Video_EncodingBitrate
):
## Property
* `PKEY_Media_Duration`, Length: `855000000` (`VT_UI8`) // `855,000,000`
* `PKEY_Audio_EncodingBitrate`, Bit rate: `43744` (`VT_UI4`) // `43,744`
* `PKEY_Audio_ChannelCount`, Channels: `1` (`VT_UI4`) // `1`
* `PKEY_Audio_Format`, Audio format: `{00001610-0000-0010-8000-00AA00389B71}` (`VT_LPWSTR`) // FourCC 0x00001610
* `PKEY_Audio_SampleRate`, Audio sample rate: `32000` (`VT_UI4`) // `32,000`
* `PKEY_Audio_SampleSize`, Audio sample size: `16` (`VT_UI4`) // `16`
* `PKEY_Audio_StreamNumber`: `1` (`VT_UI4`) // `1`
* `PKEY_Video_EncodingBitrate`, Data rate: `263352` (`VT_UI4`) // `263,352`
* `PKEY_Video_FrameWidth`, Frame width: `640` (`VT_UI4`) // `640`
* `PKEY_Video_FrameHeight`, Frame height: `480` (`VT_UI4`) // `480`
该方法也适用于其他媒体文件格式,通过其他容器格式的相应 属性 处理程序使用相同的密钥获取数据。