隨着高速(20M)寬帶、HTPC、大容量硬盤(3T)的普及,下載高清片並利用大屏幕觀看也成爲普通的事情。html
隨着下載影片的增多,管理就有了問題,有時在茫茫文件夾下找尋一個影片也是一件費時費力的事。ide
因而萌生了本身編寫電影管理器的想法,並逐步逐步在實現。利用博客記錄編寫的過程,也是和網友之間的交流。指望在交流的過程當中,網友能提出一些中肯的意見,使本身少走些彎路。函數
我在拿到一個高清視頻文件時。我但願能有辦法獲知如下的信息編碼
文件名:視頻文件的文件名,這個比較簡單,利用FileInfo類就能得到spa
文件大小:視頻文件的大小,這個也比較簡單,利用FileInfo類能得到.net
視頻分辨率:視頻文件的分辨率,例如:寬1980像素,高1040像素。3d
視頻時長:視頻文件的時長,例如:長1小時32分調試
音頻數:視頻文件中的音頻數,有很多的高清視頻文件中包含不止一個音頻。有的包含英文、中文2個音頻;有的包含英文、中文、粵語3個音頻code
音頻的語言類型:具體到每一個音頻的語言。例如:音頻1是英文,音頻2是中文等orm
以上信息中的後面四個(視頻分辨率、視頻時長、音頻數、音頻的語言類型),用視頻播放器都能得到。可是如何在本身的程序中得到這些信息呢?
咱們能夠利用MediaInfo來獲取這些信息(視頻分辨率、視頻時長、音頻數、音頻的語言類型)
先看看MediaInfo的介紹,MediaInfo官網。在官網上有相關的介紹,並給出了調用的代碼(很完備。C++,C#,Visual Basic等都有)
高清視頻文件的相關信息都保存在文件的頭部區域,記錄的信息有不少(除卻上面的四種外,還包括碼率、編碼類型等等)。而MediaInfo就是利用讀取頭部區域的信息來得到相關的信息。官網的更新很快,筆者下載的是2013年7月6日發佈的最新版。
下面就介紹如何利用MediaInfo來得到高清視頻文件的相關信息。
一、下載相應的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文件。
二、新建項目
在VS2010中新建項目,把相關的DLL複製到可執行程序的目錄(在項目文件夾下的bin\Debug\,或者複製到系統目錄中)
注:MediaInfo.dll貌似是64位的;MediaInfo_i386.dll貌似是32位的;在後面的調試中,MediaInfo.dll始終會報錯,反而MediaInfo_i386.dll改爲MediaInfo.dll後複製到目錄中調試一遍成功。
三、把官網中的提供的調用代碼添加到項目中來
因爲DLL僅僅提供了函數。而目前的編碼基本上都是面向對象,因此在官網上針對不少的語言都提供了相應的代碼,把函數調用包裝成類,方便調用者使用。Visual Basic的調用代碼在http://sourceforge.net/p/mediainfo/code/5846/tree/MediaInfoLib/trunk/Project/MSVB2010/上,其餘語言在相關的網頁上也能找到,這裏就不贅述了。
要注意的是,在如上所作時,還得在VS2010中進行設置
在打開的項目屬性中,點開「調試」,勾上「啓用非託管代碼調試」,才能正常調試。
若是沒有勾上,運行時則會出現下面的對話框
多是缺乏Lib文件的緣故,不過我沒在官網上找到Lib文件的下載
另,不須要在項目中對MediaInfo.dll引用。引用會出錯,以下所示:
官網上的Visual Basic 2010調用代碼以下:
Imports System.Runtime.InteropServices
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、再次包裝,方便調用
因爲上面的代碼是提供了一個類供調用者使用,所以,我決定再包裝一下,使其看起來簡單一些(我只須要分辨率、時長、音頻數、音頻語言這四個信息)。
我包裝的代碼以下:
Public
Class
clsMediaInfo
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")
那麼,如何能知道有哪些參數呢?參看
MediaInfo參數大全
C#使用MediaInfo查看媒體信息
這兩篇文章對參數介紹的很詳細,只是文章寫得早,提供的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個音頻;分別是英文和中文;
這個代碼在作高清視頻文件的信息庫的時候特別有用。能夠根據高清視頻文件自動獲取相關信息,毋須再手動填充信息。