天天看点

我的媒体播放器——多媒体编程

第二个题目是我的播放器,可以播放音频和视频。其实略懂计算机多媒体技术的人都清楚,音频和视频的差异具体是体现在文件格式上的。不同的音频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,如需转载请自行联系原作者

继续阅读