編程實戰——電影管理器之利用MediaInfo獲取高清視頻文件的相關信息

隨着高速(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中進行設置

image

在打開的項目屬性中,點開「調試」,勾上「啓用非託管代碼調試」,才能正常調試。

若是沒有勾上,運行時則會出現下面的對話框

image

多是缺乏Lib文件的緣故,不過我沒在官網上找到Lib文件的下載

另,不須要在項目中對MediaInfo.dll引用。引用會出錯,以下所示:

image

 

 

官網上的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個音頻;分別是英文和中文;

 

這個代碼在作高清視頻文件的信息庫的時候特別有用。能夠根據高清視頻文件自動獲取相關信息,毋須再手動填充信息。

相關文章
相關標籤/搜索