使用 C# 访问 WMF 元数据






4.33/5 (9投票s)
2006 年 6 月 21 日
2分钟阅读

176502

2427
一篇关于如何使用 C# 和 Windows Media Format SDK 读取 Windows Media Format 文件中的元数据的文章。
引言
那么,您想编写一个 C# 应用程序,可以使用特定的 Windows Media Format (WMF) 元数据字段吗?也许您想列出您拥有的所有电影文件的标题和评级。幸运的是,微软有一个 Windows Media Format 的 SDK。但是,WMF SDK 不是托管代码。但是,它非常出色地为元数据访问提供了托管包装器。实际上,SDK 包含一个用于编辑 WMF 元数据的完整示例程序。那么,为什么不直接使用它呢?因为,在我的情况下,它对于我的客户的需求来说是多余的。在这种情况下,我只需要能够查询一个 WMF 文件(特别是 WMV 文件)以获取作者和版权信息。所以,我编写了自己的类,该类经过优化,专门处理字符串元数据。(它可以很容易地修改以适应其他数据类型,或者通过索引而不是名称来访问元数据。)
由于我需要一些这么简单的东西,我想其他人可能也需要。此外,这个例子可以作为在应用程序中使用 WMF 元数据的一个简单介绍。
背景
首先,我们谈论的是哪种元数据? WMF 元数据字段是四种数据类型之一
QWORD
(四字)DWORD
(双字)BOOL
STRING (字符串)
例如,以下是我测试 WMV 文件之一中可用的元数据属性列表
Index Name Stream Language Type ----- ------ ------ -------- ---- 0 Duration 0 0 QWORD 1 Bitrate 0 0 DWORD 2 Seekable 0 0 BOOL 3 Stridable 0 0 BOOL 4 Broadcast 0 0 BOOL 5 Is_Protected 0 0 BOOL 6 Is_Trusted 0 0 BOOL 7 Signature_Name 0 0 STRING 8 HasAudio 0 0 BOOL 9 HasImage 0 0 BOOL 10 HasScript 0 0 BOOL 11 HasVideo 0 0 BOOL 12 CurrentBitrate 0 0 DWORD 13 OptimalBitrate 0 0 DWORD 14 HasAttachedImages 0 0 BOOL 15 Can_Skip_Backward 0 0 BOOL 16 Can_Skip_Forward 0 0 BOOL 17 FileSize 0 0 QWORD 18 HasArbitraryDataStream 0 0 BOOL 19 HasFileTransferStream 0 0 BOOL 20 WM/ContainerFormat 0 0 DWORD 21 Title 0 0 STRING 22 Author 0 0 STRING 23 Copyright 0 0 STRING 24 Description 0 0 STRING 25 Rating 0 0 STRING 26 BannerImageURL 0 0 STRING 27 CopyrightURL 0 0 STRING 28 WMFSDKVersion 0 0 STRING 29 WMFSDKNeeded 0 0 STRING 30 IsVBR 0 0 BOOL 31 WM/AlbumTitle 0 0 STRING 32 WM/Track 0 0 STRING 33 WM/PromotionURL 0 0 STRING 34 WM/AlbumCoverURL 0 0 STRING 35 WM/Genre 0 0 STRING 36 WM/Year 0 0 STRING 37 WM/GenreID 0 0 STRING 38 WM/Composer 0 0 STRING 39 WM/Lyrics 0 0 STRING 40 WM/ToolName 0 0 STRING 41 WM/ToolVersion 0 0 STRING 42 WM/AlbumArtist 0 0 STRING 43 WM/AuthorURL 0 0 STRING 44 WM/AudioFileURL 0 0 STRING 45 WM/Language 0 0 STRING 46 WM/ParentalRating 0 0 STRING 47 WM/BeatsPerMinute 0 0 STRING 48 WM/InitialKey 0 0 STRING 49 WM/Mood 0 0 STRING 50 WM/DVDID 0 0 STRING 51 WM/UniqueFileIdentifier 0 0 STRING 52 WM/ModifiedBy 0 0 STRING 53 WM/RadioStationName 0 0 STRING 54 WM/RadioStationOwner 0 0 STRING 55 WM/PlaylistDelay 0 0 STRING 56 WM/Codec 0 0 STRING 57 WM/DRM 0 0 STRING 58 WM/ISRC 0 0 STRING 59 WM/Provider 0 0 STRING 60 WM/ProviderRating 0 0 STRING 61 WM/ProviderStyle 0 0 STRING 62 WM/ContentDistributor 0 0 STRING 63 WM/SubscriptionContentID 0 0 STRING 64 WM/ASFPacketCount 0 0 QWORD 65 WM/ASFSecurityObjectsSize 0 0 QWORD
正如您所看到的,可以有很多可用的属性!但是,重要的是要注意,并非所有文件都包含相同的属性列表。请确保您正在查询的文件具有您请求的字段。如果没有,查询将返回一个错误:来自 HRESULT 的异常:0xC00D07F0 或 来自 HRESULT 的异常:0xC00D001D。
使用代码
由于托管包装器是微软的代码,并且是 WMF SDK 的一部分,因此我没有将其作为本文的下载内容包含在内。但您可以从 MSDN 下载 SDK。安装完成后,找到“Managed”目录(对于默认安装,它将是:C:\WMSDK\WMFSDK95\samples\managed\)。在该目录下,您将找到包装器项目。使用它的最简单方法是将该项目导入到您的 Visual Studio 解决方案中,然后在您的主应用程序项目中添加对该项目的引用。现在,将我的 MetaDataReader
类文件导入到您的主项目中,并使用 GetFieldByName
方法检索您所需的元数据字段的值。
这是 MetaDataReader
类
using System;
using System.Collections.Generic;
using System.Text;
using WMFSDKWrapper;
//managed wrapper to WMF SDK -
// provides access to metadata
namespace MyNamespace
{
/// This class contains the functionality
/// for handling interaction with the media file
/// metadata, via the WMF SDK managed wrapper class.
public class MetaDataReader
{
/// Default constructor
public MetaDataReader()
{
}
/// Method to obtain a metadata attribute by passing in its name.
/// Assumes the metadata type is STRING.
/// Uses the SDK function GetAttributeByName.
///
/// param name="filename" - the filename
/// (including path) of media file to interrogate
/// param name="attrName" - the name of the field we're looking for
/// returns - the value of the named attribute,
/// empty string if not found, or error message
public string GetFieldByName(string fileName, string attrName)
{
try
{
//object used to access WMF file
IWMMetadataEditor MetadataEditor;
//object to use access metadata
IWMHeaderInfo3 HeaderInfo3;
//media stream to interrogate
ushort streamNum = 0;
//data type of attribute
WMT_ATTR_DATATYPE wAttribType;
//value of attribute (as returned by method call)
byte[] pbAttribValue = null;
//length of attribute (byte array)
ushort wAttribValueLen = 0;
WMFSDKFunctions.WMCreateEditor(out MetadataEditor);
MetadataEditor.Open(fileName);
HeaderInfo3 = (IWMHeaderInfo3)MetadataEditor;
//make call to get attribute length
HeaderInfo3.GetAttributeByName(ref streamNum, attrName,
out wAttribType, pbAttribValue, ref wAttribValueLen);
//set byte array length
pbAttribValue = new byte[wAttribValueLen];
//make call again, which will get value
//into correct-length byte array
HeaderInfo3.GetAttributeByName(ref streamNum,
attrName, out wAttribType,
pbAttribValue,
ref wAttribValueLen);
MetadataEditor.Close();
return ConvertAttrToString(pbAttribValue,
wAttribValueLen);
}
catch (Exception e)
{
return "ERROR: " + e.Message;
}
}//end method
/// Method to convert byte array value into string.
/// (From the Microsoft WMF SDK sample.)
///
/// param name="pbValue" - byte array value of attribute
/// param name="dwValueLen" - Length of byte array
private string ConvertAttrToString(byte[] pbValue, ushort dwValueLen)
{
string Value = "";
if (0 == dwValueLen)
{
Value = "";
}
else
{
if ((0xFE == Convert.ToInt16(pbValue[0])) &&
(0xFF == Convert.ToInt16(pbValue[1])))
{
Value = "UTF-16LE BOM+";
if (4 <= dwValueLen)
{
for (int i = 0; i < pbValue.Length - 2; i += 2)
{
Value +=
Convert.ToString(BitConverter.ToChar(pbValue, i));
}
}
}
else if ((0xFF == Convert.ToInt16(pbValue[0])) &&
(0xFE == Convert.ToInt16(pbValue[1])))
{
Value = "UTF-16BE BOM+";
if (4 <= dwValueLen)
{
for (int i = 0; i < pbValue.Length - 2; i += 2)
{
Value +=
Convert.ToString(BitConverter.ToChar(pbValue, i));
}
}
}
else
{
Value = "";
if (2 <= dwValueLen)
{
for (int i = 0; i < pbValue.Length - 2; i += 2)
{
Value +=
Convert.ToString(BitConverter.ToChar(pbValue, i));
}
}
}
}//end else not a 0-length string
return Value;
}//end method
}//end class
}
这是一个示例调用的代码片段
MetaDataReader objMetaData = new MetaDataReader();
string Author = objMetaData.GetAttrByName("C:\Videos\MyVideo.wmv", "Author");
就是这样!我希望这个简单的例子能为您提供编写一些访问 WMF 元数据的酷炫应用程序所需的基础知识。
历史
- 06.20.06 - 初始版本。