一個用C#開發的DirectShow媒體播放器(作者:Daniel Strigl)

來源:互聯網
上載者:User

 
示範程式 


介紹;
由於我第一次寫關於代碼介紹方面的文章,請原諒我的英語很差。我只是在學校中和一些工作中接觸過英文。
我希望每個人可以理解這篇文章的內容。如果有問題我很願意解答。如果發現有錯,請即使糾正-感謝協助我學習英文;-)。
好現在開始
這個小程式示範了,用C#開發的一個DirectShow的播放軟體可以播放視頻和聲音。
該程式包含以下控制:MainMenu, ToolBar, StatusBar, Panel, ImageList,和一個 Timer。
這些屬性都是在屬性欄中填好了,所以我建議你下載該項目,除非你並不是一個初學者。
另一方面,案例程式包含 DirectShow類用來播放視頻和聲音。

...
程式示範了以下內容:
怎樣用OpenFileDialog類來在磁碟上選擇一個媒體檔案。
怎樣啟用工具列桑的按鈕。
怎樣狀態列的資訊。
怎樣使用一個Timer控鍵。
怎樣使用時鐘控制事件。
這樣使用主菜單事件。
怎樣使用工具列事件。
怎樣使用視窗事件。
怎樣用DirectShow播放媒體。
怎樣判定媒體是否已經播放完了。

使用者介面
除了3個按鈕用來播放,停止視頻和聲音的播放,同時用菜單來選擇要播放的媒體檔案,所以在你要播放一個媒體檔案之前,你必須開啟檔案在菜單"File -> Open..."下。如果檔案成功載入,就可以通過按 "Play"按鈕來播放。在播放過程中,程式在狀態列上顯示播放進度。如果播放結束,你可以按"Play"重新播放或選擇另一個檔案。

 

菜單的"Info"命令用來顯示資訊對話方塊。

關於DirectShow:
我們通常用DirectShow類來播放視頻和聲音,它是DirectX中的一個開發工具。通過DirectShow可以非常容易的播放視頻和音效檔,使用它只需要正確設定參數和方法。


不幸的是.NET和C#在DirectX中不包含官方的支援平台,所以DirectX 9中不包含DirectShow。我們用C#開發DirectX通過使用Visual Basic的類型庫API版本是7到8。該文章介紹如何在C#中使用DirectX VB類庫。
在開始.NET DirectShow開發之前,我們需要建立一個到DirectShow COM DLL的引用。拷貝"Interop.QuartzTypeLib.dll"到你的專案檔夾中。在 Visual Studio.NET中通過在項目菜單中選擇和添加來完成。

按"Browse..." 選擇DirectShow COM DLL。
using QuartzTypeLib;

關於代碼:
怎樣建立DirectShow並選擇媒體檔案?
在選擇了主菜單下的"File -> Open..."後,顯示"Open File"對話方塊然後使用者可以選擇一個媒體檔案。在C#中通過建立一個OpenFileDialog類對象並使用ShowDialog()方法來實現。
OpenFileDialog openFileDialog = new OpenFileDialog();

openFileDialog.Filter = "Media Files|*.mpg;*.avi;*.wma;*.mov;" +
                        "*.wav;*.mp2;*.mp3|All Files|*.*";

if (DialogResult.OK == openFileDialog.ShowDialog())
{
    .
    .
    .

在以上完成之後,我們開始建立了DirectShow並開始渲染媒體檔案。
通過以下幾步完成:


建立圖象過濾管理(FGM)
建立圖象過濾(通過FGM)
播放圖象並返回事件
以下代碼示範怎樣建立圖象過濾管理和圖象過濾:
 CollapseCleanUp();

m_objFilterGraph = new FilgraphManager();
m_objFilterGraph.RenderFile(openFileDialog.FileName);

m_objBasicAudio = m_objFilterGraph as IBasicAudio;

try
{
 m_objVideoWindow = m_objFilterGraph as IVideoWindow;
 m_objVideoWindow.Owner = (int) panel1.Handle;
 m_objVideoWindow.WindowStyle = WS_CHILD | WS_CLIPCHILDREN;
 m_objVideoWindow.SetWindowPosition(panel1.ClientRectangle.Left,
  panel1.ClientRectangle.Top,
  panel1.ClientRectangle.Width,
  panel1.ClientRectangle.Height);
}
catch (Exception ex)
{
 m_objVideoWindow = null;
}

m_objMediaEvent = m_objFilterGraph as IMediaEvent;

m_objMediaEventEx = m_objFilterGraph as IMediaEventEx;
m_objMediaEventEx.SetNotifyWindow((int) this.Handle, WM_GRAPHNOTIFY, 0);

m_objMediaPosition = m_objFilterGraph as IMediaPosition;

m_objMediaControl = m_objFilterGraph as IMediaControl;

 通過CleanUp()我們刪除對象,如果對象存在。在我們可以開始渲染一個檔案時,我們必須建立FilterGraphManager的幾個新對象用新的方法。RenderFile()方法建立了一個圖象過濾器用來渲染指定檔案。IBasicAudio類用來設定聲音的大小和品質。IVideoWindow類用來設定視窗風格,視窗位置。該函數是附加的,如果你播放音效檔,你如果調用該方法。可是播放音效檔不需要IVideoWindow類,所以將m_objVideoWindow設定成NULL。IMediaEvent和IMediaEventEx類用來偵聽訊息,用來發送DirectShow資訊到父視窗。通過IMediaPosition類,可以設定當前的位置。通過IMediaControl類來控制開始,停止視頻和聲音的播放。
 想瞭解更多關於DirectShow的內容請讀一下MSDN的文檔。
怎樣播放媒體檔案?


用IMediaControl類的Run()方法來開始播放一個視頻或音效檔。
m_objMediaControl.Run();

怎樣暫停播放?


如果你想要暫停播放一個視頻或音效檔,使用IMediaControl類的Pause()方法。
m_objMediaControl.Pause();

怎樣停止播放?


用IMediaControl類的Stop()方法來停止播放一個視頻或聲音。
m_objMediaControl.Stop();

 

怎樣得到檔案的播放進度和期間?


當媒體檔案被播放時,我們在狀態列指定當前的播放進度和檔案長度。我們讀取全部100MS內IMediaPosition類得到的當前進度並將大小顯示在狀態列。為了得到檔案長度我們讀取了IMediaPosition類的Duration成員變數。
private void timer1_Tick(object sender, System.EventArgs e)
{
    if (m_CurrentStatus == MediaStatus.Running)
    {
        UpdateStatusBar();
    }
}

時間函數每隔100MS調用UpdateStatusBar()方法,用來顯示當前位置和檔案進度。
 Collapseprivate void UpdateStatusBar()
{
    switch (m_CurrentStatus)
    {
        case MediaStatus.None   : statusBarPanel1.Text = "Stopped"; break;
        case MediaStatus.Paused : statusBarPanel1.Text = "Paused "; break;
        case MediaStatus.Running: statusBarPanel1.Text = "Running"; break;
        case MediaStatus.Stopped: statusBarPanel1.Text = "Stopped"; break;
    }

    if (m_objMediaPosition != null)
    {
        int s = (int) m_objMediaPosition.Duration;
        int h = s / 3600;
        int m = (s  - (h * 3600)) / 60;
        s = s - (h * 3600 + m * 60);

        statusBarPanel2.Text = String.Format("{0:D2}:{1:D2}:{2:D2}", h, m, s);

        s = (int) m_objMediaPosition.CurrentPosition;
        h = s / 3600;
        m = (s  - (h * 3600)) / 60;
        s = s - (h * 3600 + m * 60);

        statusBarPanel3.Text = String.Format("{0:D2}:{1:D2}:{2:D2}", h, m, s);
    }
    else
    {
        statusBarPanel2.Text = "00:00:00";
        statusBarPanel3.Text = "00:00:00";
    }
}

當檔案播放結束時會怎樣?
為了判定,檔案是在結束狀態,我們重寫了WndProc函數,處理EC_COMPLETE訊息,當檔案結束播放時,將向視窗發送DirectShow訊息。
 Collapseprotected override void WndProc(ref Message m)
{
    if (m.Msg == WM_GRAPHNOTIFY)
    {
        int lEventCode;
        int lParam1, lParam2;

        while (true)
        {
            try
            {
                m_objMediaEventEx.GetEvent(out lEventCode,
                    out lParam1,
                    out lParam2,
                    0);

                m_objMediaEventEx.FreeEventParams(lEventCode, lParam1, lParam2);

                if (lEventCode == EC_COMPLETE)
                {
                    m_objMediaControl.Stop();
                    m_objMediaPosition.CurrentPosition = 0;
                    m_CurrentStatus = MediaStatus.Stopped;
                    UpdateStatusBar();
                    UpdateToolBar();
                }
            }
            catch (Exception)
            {
                break;
            }
        }
    }

    base.WndProc(ref m);
}

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.