天天看點

我的媒體播放器——多媒體程式設計

第二個題目是我的播放器,可以播放音頻和視訊。其實略懂計算機多媒體技術的人都清楚,音頻和視訊的差異具體是展現在檔案格式上的。不同的音頻mp3,midi,wav等其實是不同的編碼或者格式,同理不同的視訊avi,rm(rmvb),mov等其實也是不同的編碼格式,這些格式中,大多數都是不公開源代碼的,但是公開标準或者API接口。但程式設計調用依然很繁瑣,我們也沒有精力和能力去研究這些。

.Net本身不帶多媒體庫,但是具有與COM互動的強大能力。恰好,微軟DirectShow技術能滿足上述要求,而且可以跟.NET達到完美的結合。

DirectShow互動程式集是內建在DirectX中的,多數計算機都會有DirectX,微軟也提供下載下傳。廢話少說,開始做吧。

第一,在項目中引用Interop.QuartzTypeLib.dll。這是DirectX的COM互動程式集,其實是個托管調用。其中的類庫和方法介紹最好還是看DirectX的SDK。這裡不班門弄斧了。

第二,播放打開的檔案

        public void RenderMedia(string mediaFileName)

        {

            clearUp();

            try

            {

                objMedia = new FilgraphManager();

                objMedia.RenderFile(mediaFileName);

                volMedia = objMedia as IBasicAudio;

                posMedia = objMedia as IMediaPosition;

                ctlMedia = objMedia as IMediaControl;

                eexMedia = objMedia as IMediaEventEx;

                eexMedia.SetNotifyWindow((int)this.Handle, WM_GRAPHNOTIFY, 0);

                mediaStatus = 1;

                mediaDuration = posMedia.Duration;

                volMedia.Volume = mediaVolum;

                Play();

            }

            catch

                MessageBox.Show("加載檔案失敗!");

                clearUp();

        }

其中ClearUp用于釋放資源

        private void clearUp()

            if (ctlMedia != null)

                ctlMedia.Stop();

            mediaStatus = 1;

            mediaDuration = 0;

            mediaCurPos = 0;

            if (eexMedia != null)

                eexMedia.SetNotifyWindow(0, 0, 0);

            if (ctlMedia != null) ctlMedia = null;

            if (volMedia != null) volMedia = null;

            if (posMedia != null) posMedia = null;

            if (eexMedia != null) eexMedia = null;

            if (objMedia != null) objMedia = null;

基本功能調用代碼比較簡單

        /// <summary>

        /// 播放

        /// </summary>

        public void Play()

            ctlMedia.Run();

            mediaStatus = 3;

        /// 暫停

        public void Pause()

            ctlMedia.Pause();

            mediaStatus = 2;

        /// 停止

        public void Stop()

            ctlMedia.Stop();

            posMedia.CurrentPosition = 0;

        /// 搜尋

        /// <param name="posTar">秒</param>

        public void Seek(int posTar)

            posMedia.CurrentPosition = posTar;

有一點必須注意,播放過程中的窗體消息處理,需要重寫WndProc方法。

        protected override void WndProc(ref Message m)

            if (m.Msg == WM_GRAPHNOTIFY)

                int lEventCode;

                int lParam1, lParam2;

                while (true)

                {

                    try

                    {

                        eexMedia.GetEvent(out lEventCode, out lParam1, out lParam2, 0);

                        eexMedia.FreeEventParams(lEventCode, lParam1, lParam2);

                        if (lEventCode == EC_COMPLETE)

                        {

                            ctlMedia.Stop();

                            posMedia.CurrentPosition = 0;

                            mediaStatus = 1;

                        }

                    }

                    catch (Exception)

                        break;

                }

            base.WndProc(ref m);

主要代碼就這些了。播放器的界面制作純屬個人愛好,這裡不說了,很希望能有做windows應用程式界面高手能指點一番。

這裡的程式有個缺點是播放視窗是新彈出的DirectShow視窗,一時還沒有搞懂是怎麼回事。

順便說一下,DirectShow可不止能讀取媒體檔案,還能編輯或者建立,wonderful!

後來借鑒有人使用了MediaPlayer控件做的播放器,也蠻有趣的,制作簡單了很多,但是受MediaPlayer限制太多,僅作為後備方法吧。

另外媒體播放當然不止DirectShow這一種方式,希望多提寶貴建議。現在我正在用它播放《東成西就》,RMVB格式。

本文轉自 王傑瑞 51CTO部落格,原文連結:http://blog.51cto.com/wangjierui/55940,如需轉載請自行聯系原作者

繼續閱讀