编程实战——电影管理器之利用MediaInfo获取高清视频文件的相关信息
随着高速(20M)宽带、HTPC、大容量硬盘(3T)的普及,下载高清片并利用大屏幕观看也成为普通的事情。
随着下载影片的增多,管理就有了问题,有时在茫茫文件夹下找寻一个影片也是一件费时费力的事。
于是萌生了自己编写电影管理器的想法,并逐步逐步在实现。利用博客记录编写的过程,也是和网友之间的交流。期望在交流的过程中,网友能提出一些中肯的意见,使自己少走些弯路。
我在拿到一个高清视频文件时。我希望能有办法获知以下的信息
文件名:视频文件的文件名,这个比较简单,利用FileInfo类就能获得
文件大小:视频文件的大小,这个也比较简单,利用FileInfo类能获得
视频分辨率:视频文件的分辨率,例如:宽1980像素,高1040像素。
视频时长:视频文件的时长,例如:长1小时32分
音频数:视频文件中的音频数,有不少的高清视频文件中包含不止一个音频。有的包含英文、中文2个音频;有的包含英文、中文、粤语3个音频
音频的语言类型:具体到每个音频的语言。例如:音频1是英文,音频2是中文等
以上信息中的后面四个(视频分辨率、视频时长、音频数、音频的语言类型),用视频播放器都能获得。但是如何在自己的程序中获得这些信息呢?
我们可以利用MediaInfo来获取这些信息(视频分辨率、视频时长、音频数、音频的语言类型)
先看看MediaInfo的介绍,MediaInfo官网。在官网上有相关的介绍,并给出了调用的代码(很完备。C++,C#,Visual Basic等都有)
高清视频文件的相关信息都保存在文件的头部区域,记录的信息有很多(除却上面的四种外,还包括码率、编码类型等等)。而MediaInfo就是利用读取头部区域的信息来获得相关的信息。官网的更新很快,笔者下载的是2013年7月6日发布的最新版。
下面就介绍如何利用MediaInfo来获得高清视频文件的相关信息。
1、下载相应的DLL
在http://sourceforge.net/projects/mediainfo/files/development_snapshots/上点击Download MediaInfo_GUI_0.7.64_Windows.exe (4.5 MB),下载最新的版本。安装后在安装的目录中找到MediaInfo.dll和MediaInfo_i386.dll这两个DLL文件。
2、新建项目
在VS2010中新建项目,把相关的DLL复制到可执行程序的目录(在项目文件夹下的bin\Debug\,或者复制到系统目录中)
注:MediaInfo.dll貌似是64位的;MediaInfo_i386.dll貌似是32位的;在后面的调试中,MediaInfo.dll始终会报错,反而MediaInfo_i386.dll改成MediaInfo.dll后复制到目录中调试一遍成功。
3、把官网中的提供的调用代码添加到项目中来
由于DLL仅仅提供了函数。而目前的编码基本上都是面向对象,所以在官网上针对很多的语言都提供了相应的代码,把函数调用包装成类,方便调用者使用。Visual Basic的调用代码在http://sourceforge.net/p/mediainfo/code/5846/tree/MediaInfoLib/trunk/Project/MSVB2010/上,其他语言在相关的网页上也能找到,这里就不赘述了。
要注意的是,在如上所做时,还得在VS2010中进行设置

在打开的项目属性中,点开“调试”,勾上“启用非托管代码调试”,才能正常调试。
如果没有勾上,运行时则会出现下面的对话框

可能是缺少Lib文件的缘故,不过我没在官网上找到Lib文件的下载
另,不需要在项目中对MediaInfo.dll引用。引用会出错,如下所示:

官网上的Visual Basic 2010调用代码如下:
Public Enum StreamKind As UInteger
General
Visual
Audio
Text
Chapters
Image
Menu
Max
End Enum
Public Enum InfoKind As UInteger
Name
Text
Measure
Options
NameText
MeasureText
Info
HowTo
Max
End Enum
Public Enum InfoOptions As UInteger
ShowInInform
Reserved
ShowInSupported
TypeOfValue
Max
End Enum
Public Class MediaInfo
Private Declare Unicode Function MediaInfo_New Lib "MediaInfo.DLL" () As IntPtr
Private Declare Unicode Sub MediaInfo_Delete Lib "MediaInfo.DLL" (ByVal Handle As IntPtr)
Private Declare Unicode Function MediaInfo_Open Lib "MediaInfo.DLL" (ByVal Handle As IntPtr, ByVal FileName As String) As UIntPtr
Private Declare Unicode Sub MediaInfo_Close Lib "MediaInfo.DLL" (ByVal Handle As IntPtr)
Private Declare Unicode Function MediaInfo_Inform Lib "MediaInfo.DLL" (ByVal Handle As IntPtr, ByVal Reserved As UIntPtr) As IntPtr
Private Declare Unicode Function MediaInfo_GetI Lib "MediaInfo.DLL" (ByVal Handle As IntPtr, ByVal StreamKind As UIntPtr, ByVal StreamNumber As UIntPtr, ByVal Parameter As UIntPtr, ByVal KindOfInfo As UIntPtr) As IntPtr
Private Declare Unicode Function MediaInfo_Get Lib "MediaInfo.DLL" (ByVal Handle As IntPtr, ByVal StreamKind As UIntPtr, ByVal StreamNumber As UIntPtr, ByVal Parameter As String, ByVal KindOfInfo As UIntPtr, ByVal KindOfSearch As UIntPtr) As IntPtr
Private Declare Unicode Function MediaInfo_Option Lib "MediaInfo.DLL" (ByVal Handle As IntPtr, ByVal Option_ As String, ByVal Value As String) As IntPtr
Private Declare Unicode Function MediaInfo_State_Get Lib "MediaInfo.DLL" (ByVal Handle As IntPtr) As UIntPtr
Private Declare Unicode Function MediaInfo_Count_Get Lib "MediaInfo.DLL" (ByVal Handle As IntPtr, ByVal StreamKind As UIntPtr, ByVal StreamNumber As IntPtr) As UIntPtr
Dim Handle As IntPtr
Sub New()
Handle = MediaInfo_New()
End Sub
Protected Overrides Sub Finalize()
MediaInfo_Delete(Handle)
End Sub
Function Open(ByVal FileName As String) As System.UIntPtr
Return MediaInfo_Open(Handle, FileName)
End Function
Sub Close()
MediaInfo_Close(Handle)
End Sub
Function Inform() As String
Return Marshal.PtrToStringUni(MediaInfo_Inform(Handle, CType(0, UIntPtr)))
End Function
Function Get_(ByVal StreamKind As StreamKind, ByVal StreamNumber As Integer, ByVal Parameter As Integer, Optional ByVal KindOfInfo As InfoKind = InfoKind.Text) As String
Return Marshal.PtrToStringUni(MediaInfo_GetI(Handle, CType(StreamKind, UIntPtr), CType(StreamNumber, UIntPtr), CType(Parameter, UIntPtr), CType(KindOfInfo, UIntPtr)))
End Function
Function Get_(ByVal StreamKind As StreamKind, ByVal StreamNumber As Integer, ByVal Parameter As String, Optional ByVal KindOfInfo As InfoKind = InfoKind.Text, Optional ByVal KindOfSearch As InfoKind = InfoKind.Name) As String
Return Marshal.PtrToStringUni(MediaInfo_Get(Handle, CType(StreamKind, UIntPtr), CType(StreamNumber, UIntPtr), Parameter, CType(KindOfInfo, UIntPtr), CType(KindOfSearch, UIntPtr)))
End Function
Function Option_(ByVal Option__ As String, Optional ByVal Value As String = "") As String
Return Marshal.PtrToStringUni(MediaInfo_Option(Handle, Option__, Value))
End Function
Function State_Get() As Integer
Return CInt(MediaInfo_State_Get(Handle))
End Function
Function Count_Get(ByVal StreamKind As StreamKind, Optional ByVal StreamNumber As UInteger = UInteger.MaxValue) As Integer
If StreamNumber = UInteger.MaxValue Then
Return CInt(MediaInfo_Count_Get(Handle, CType(StreamKind, UIntPtr), CType(-1, IntPtr)))
Else
Return CInt(MediaInfo_Count_Get(Handle, CType(StreamKind, UIntPtr), CType(StreamNumber, IntPtr)))
End If
End Function
End Class
4、再次包装,方便调用
由于上面的代码是提供了一个类供调用者使用,因此,我决定再包装一下,使其看起来简单一些(我只需要分辨率、时长、音频数、音频语言这四个信息)。
我包装的代码如下:
Private _M As MediaInfo
Public Sub New()
_M = New MediaInfo
End Sub
Public Function GetInfo(FileName As String) As String
_M.Open(FileName)
_M.Option_("Complete")
Return _M.Inform
End Function
Public Function Width() As String
Return _M.Get_(StreamKind.Visual, 0, "Width")
End Function
Public Function Height() As String
Return _M.Get_(StreamKind.Visual, 0, "Height")
End Function
Public Function Duration() As String
Return _M.Get_(StreamKind.General, 0, "Duration/String3")
End Function
Public Function AudioCount() As Integer
Return Convert.ToInt32(_M.Get_(StreamKind.General, 0, "AudioCount"))
End Function
Public Function AudioLanguage(Index As Integer) As String
If Index < 0 OrElse Index > AudioCount() - 1 Then Index = 0
Return _M.Get_(StreamKind.Audio, Index, "Language/String")
End Function
Public Function AudioLanguage() As String()
Dim I As Integer, C As Integer = AudioCount()
Dim L(C - 1) As String
For I = 0 To C - 1
L(I) = _M.Get_(StreamKind.Audio, I, "Language/String")
Next
Return L
End Function
End Class
解释一下:
首先在类的内部定义一个MediaInfo类的实例,具体的功能都是通过该实例来完成。
在查看信息前,需调用GetInfo(FileName As String)函数,该函数的目的是获得相关的信息,一共三句话
_M.Open(FileName)
_M.Option_("Complete")
Return _M.Inform
第1句,打开FileName指定的文件;第2句,获取相关信息,并通知类,已经获取完毕(可能在DLL中会有释放资源等操作);第3句,返回视频文件的相关信息。
第3句话返回的是所有的信息,长长的一串。
如果仅仅是想获得某一个信息,则需要调用下面的语句
_M.Get_(StreamKind.Visual, 0, "Width")
一共三个参数。
第1个参数,获取信息的类别。一般取StreamKind.General(通用信息)、StreamKind.Visual(视频信息)、StreamKind.Audio(音频信息)
第2个参数,获取信息的流编号。一般取0(第1个流,视频一般就1个流,音频有可能多于1个流),音频的话,取相应的流编号(0开始,到流数减1)
第3个参数,获取信息的名字。根据该参数返回对应的信息。
那么,对应的调用就是
视频宽度:_M.Get_(StreamKind.Visual, 0, "Width")
视频高度:_M.Get_(StreamKind.Visual, 0, "Height")
视频时长:_M.Get_(StreamKind.General, 0, "Duration/String3")。这个有多种选择,该调用返回 01:34:48.683 这种格式;如果是:_M.Get_(StreamKind.General, 0, "Duration"),则返回 5688683 ,还需要自己转换。
音频个数:_M.Get_(StreamKind.General, 0, "AudioCount")
音频语言:_M.Get_(StreamKind.Audio, I, "Language/String")。也是多种选择,该调用返回 English 这种格式;如果是:_M.Get_(StreamKind.Audio, I, "Language"),则返回 en 这种格式。
如果想获取其他的信息,直接给出相应的参数就行了。例如想获得视频的最大码率,给出参数BitRate_Maximum就行了。如下调用
_M.Get_(StreamKind.Visual, 0, "BitRate_Maximum")
那么,如何能知道有哪些参数呢?参看
这两篇文章对参数介绍的很详细,只是文章写得早,提供的DLL版本比较低罢了
下面是获取 G:\Despicable.Me.2010.BluRay.1080p.DTS.2Audio.x264-CHD.mkv 这个高清视频文件信息的调用代码:
Dim S As New clsMediaInfo
S.GetInfo("G:\Despicable.Me.2010.BluRay.1080p.DTS.2Audio.x264-CHD.mkv")
Dim S1 As String = ""
S1 &= S.Width & " " & S.Height & vbNewLine
S1 &= S.Duration & vbNewLine
S1 &= S.AudioCount & vbNewLine
S1 &= S.AudioLanguage(0) & "," & S.AudioLanguage(1)
RichTextBox1.Text = S1
返回的信息如下:
1920 1040
01:34:48.683
2
English,Chinese
说明视频分辨率为1920*1040;时长:1小时34分48秒;2个音频;分别是英文和中文;
这个代码在做高清视频文件的信息库的时候特别有用。可以根据高清视频文件自动获取相关信息,毋须再手动填充信息。
编程实战——电影管理器之利用MediaInfo获取高清视频文件的相关信息的更多相关文章
- 编程实战——电影管理器之界面UI及动画切换
编程实战——电影管理器之界面UI及动画切换 在前文“编程实战——电影管理器之利用MediaInfo获取高清视频文件的相关信息”中提到电影管理器的目的是方便播放影片,在想看影片时不需要在茫茫的文件夹下找 ...
- 编程实战——电影管理器之XML存储电影信息数据
但凡管理器之类的软件,存储数据是必不可少的.存储数据的话,有几种选择.一是用数据库,把数据存储到数据库里:一是用文本文件,把数据存储到文本文件里:一种是利用XML文件,把数据对象转换为XML后,存储到 ...
- 电影管理器之XML存储电影信息数据
电影管理器之XML存储电影信息数据 但凡管理器之类的软件,存储数据是必不可少的.存储数据的话,有几种选择.一是用数据库,把数据存储到数据库里:一是用文本文件,把数据存储到文本文件里:一种是利用XML文 ...
- AD命令获取计算机、用户相关信息
1. 获取AD用户相关信息(用户名.创建日期.最后修改密码日期.最后登录日期) Get AD users, Name/Created Date/Last change passwd Date/Last ...
- .NET C#利用反射获取类文件以及其中的方法&属性 并获取类及方法上的特性
了解C#特性类并声明我们自己的特性类[AttributeTest]代码如下 using System; namespace AttributeTest { /* 特性说明 特性本质是一个继承和使用了系 ...
- Python实例获取mp3文件的tag信息
下面利用一个python的实例程序,来学习python.这个程序的目的就是分析出所有MP3文件的Tag信息并输出. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ...
- 在Autodesk Vault 2014中使用VDF(Vault Development Framework) API获取所有文件的属性信息
这几天在玩儿Vault API, 从Autodesk Vault 2014开始提供了Vault Development Framework(VDF) API,让开发工作更简单了.在Vault 20 ...
- 总结描述用户和组管理类命令的使用方法,系统用户相关信息,取出主机IP地址
1.列出当前系统上所有已经登录的用户的用户名,注意:同一个用户登录多次,则只显示一次即可. [root@db146 ~]# who|cut -f1 -d' ' |sort -u root 2.取出最后 ...
- 利用DNSLOG获取看不到的信息(给盲注带上眼镜)
一.前言 本文原创作者:sucppVK,本文属i春秋原创奖励计划,未经许可禁止转载! 毕业设计总算搞得差不多了,这个心累啊.这不,完成了学校的任务,赶紧回来给蛋总交作业.今天给大家分享一个姿势吧,不是 ...
随机推荐
- git 拉取和获取 pull 和 fetch 区别
使用Git 直接提交的话 直接 push 获取最新版本 有两种 拉取 和 获取 pull 和 fetch git pull 从远程拉取最新版本 到本地 自动合并 merge ...
- Memcache 分布式高可用集群介绍
分布式缓存需考虑如下三点: 1.缓存本身的水平线性扩展的问题. 2.缓存大病罚下的本身性能问题. 3.避免缓存的单点鼓掌问题. 分布式缓存存在的问题: 1.内存本身的管理问题.内存的分配,管理和回收机 ...
- delphi project of object
http://www.cnblogs.com/ywangzi/archive/2012/08/28/2659811.html 其实要了解这些东西,适当的学些反汇编,WINDOWS内存管理机制,PE结构 ...
- 未经处理的异常:System.Net.Sockets.SocketException: 以一种访问权限不允许的方式做了一个访问套接字的尝试
报错:未经处理的异常:System.Net.Sockets.SocketException: 以一种访问权限不允许的方式做了一个访问套接字的尝试 → 尝试以"管理员身份"运行程序, ...
- C#编程(五十八)----------并行集合
并行集合 对于并行任务,与其相关紧密的就是对一些共享资源,数据结构的并行访问.经常要做的就是对一些队列进行加锁-解锁,然后执行类似插入,删除等等互斥操作. .NET4提供了一些封装好的支持并行操作数据 ...
- 配置Oracle E-Business Suite Integrated SOA Gateway Release 12.1.2/12.1.3
3.3 配置Oracle E-Business Suite Integrated SOA Gateway Release 12.1.2 注意: 在多节点环境上配置Oracle E-Business S ...
- C++类静态数据成员与类静态成员函数
from:://http://blog.csdn.net/taina2008/article/details/1684834 把类中的函数都定义成静态函数,这样相当于在编译时就分配了空间,这样不需要实 ...
- ASP.NET MVC:Cookie 的过期时间在服务器端是获取不到的
现状 一旦 Cookie 在服务器端设置后,在后续的请求中是获取不到过期时间的,因为:Cookie 是存储和过期处理都是由客户端管理的,在后续的请求中,浏览器向服务器发送 Cookie 的时候就不包含 ...
- Java实现用汉明距离进行图片相似度检测的
Google.Baidu 等搜索引擎相继推出了以图搜图的功能,测试了下效果还不错~ 那这种技术的原理是什么呢?计算机怎么知道两张图片相似呢? 根据Neal Krawetz博士的解释,原理非常简单易懂. ...
- Java并发编程的艺术(十)——线程池(1)
线程池的作用 减少资源的开销 减少了每次创建线程.销毁线程的开销. 提高响应速度 每次请求到来时,由于线程的创建已经完成,故可以直接执行任务,因此提高了响应速度. 提高线程的可管理性 线程是一种稀缺资 ...