利用Visual CSharp开发一个媒体播放器Word文档格式.docx
《利用Visual CSharp开发一个媒体播放器Word文档格式.docx》由会员分享,可在线阅读,更多相关《利用Visual CSharp开发一个媒体播放器Word文档格式.docx(11页珍藏版)》请在冰豆网上搜索。
“退出”,退出程序。
可以在多种平台上运行。
核心功能通过JMF(JavaMediaFramework)API实现。
按照本文介绍的步骤,您将创建一个基于Windows窗体的基本应用程序,并在其中嵌入Player控件。
您创建的示例应用程序具有如下特点:
创建DirectShow控件的一个实例。
利用WindowsMediaPlayer主互操作程序集提供组件对象模型(COM)互操作性。
允许用户打开并播放WindowsMedia文件,尤其是文件扩展名为.wma或.wmv的文件。
创建供用户播放、暂停和停止数字媒体内容的传输控制按钮。
显示当前数字媒体文件的标题。
演示如何使用Player对象模型,包括使用属性、方法和事件的示例。
我的这个程序仅仅只是告诉大家如何用DirectShow在C#中做一个播放机,
在这个程序中我们经要解决的一些小问题:
1.如何从你的磁盘上打开媒体文件
2.如何让工具条上的按钮起用和禁用
3.如何设置状态栏的显示文字
4.如何控制时间
5.如何使用时间控件的事件
6.如何用DirectShow来播放媒体文件
7.如何确定播放状态等等...
下图显示了您将要创建的应用程序,其中正在播放名为“Melow”的数字音频文件,同时呈现了可视化效果。
图1
本文假设您已经具备一定的VisualC#和VisualStudio.NET集成开发环境知识。
准备工作
在开始创建应用程序之前,您需要安装必要的软件并注册主互操作程序集(QuartzTypeLib)。
这里简单介绍DirectShow接口:
播放视屏和声音文件我们要用到DiectX为我们提供的DirectShow组件.使用这个接口可以让你方便的播放那些共用的影像和声音文件.你要做的仅仅只是安装DirectShow接口和使用它的功能函数和配置正确的接口参数而已.
不幸的是.net并不正式支持DirectX.是的也许你听说DirectX9支持是吗?
是的,不过在最终版敲定的那一天还没来,我们都得不到最好的效果.但无论如何我们还是要用的不是吗?
要不这篇文章得作废了.是的,也许你用过VB,对了,就是它,我们正是要用到那个.
开始项目
在安装必要软件并注册QuartzTypeLib之后,您就可以启动VisualC#,开始为示例应用程序创建项目。
下面我将给大家介绍这一过程的操作步骤。
创建项目
按以下步骤创建一个空的项目:
1.启动VisualStudio.NET,然后单击NewProject(新建项目)。
2.在VisualC#Projects(VisualC#项目)文件夹中单击WindowsApplication(Windows应用程序),键入新项目的名称(最好为DirectShow),然后单击OK(确定)。
VisualC#使用默认的Windows窗体“Form1”创建一个新的项目。
3.这个名称并没有特别的意义或用处,所以请在Properties(属性)窗口中将窗体名称更改为frmPlayMedia,将窗体文本更改为“媒体播放器”。
在项目中添加对DirectShow的引用
按照以下步骤在项目中添加一个对DirectShow的引用:
1.打开VisualStudio工具箱,然后单击Components(组件)显示该面板。
2.右击面板,然后单击CustomizeToolbox(自定义工具箱),显示对话框。
3.在COMComponents(COM组件)选项卡上,选中Interop.QuartzTypeLib.dll。
(如果Interop.QuartzTypeLib.dll由于某种原因未列出,则单击Browse[浏览]并查找名为QuartzTypeLib.dll的文件。
)
4.单击OK(确定)关闭对话框。
图2
要在代码中使用DirectShow,您需要添加一行代码,以引用DirectShow命名空间。
在窗体代码窗口的顶部,将以下代码添加到所有声明语句之前:
usingQuartzTypeLib;
using语句必须在所有Options语句(本项目中并未使用)之后,并且在所有其他代码之前。
添加该语句后。
开发应用程序
创建通过PIA与Framework连接的Player控件实例之后,您可以向窗体中添加所需的其他元素,并编写完成实际操作的代码。
添加Windows窗体控件
1.在View(视图)菜单中,单击Designer(设计器),或者单击SolutionExplorer(解决方案资源管理器)中的ViewDesigner(视图设计器)按钮,切换到窗体设计器。
2.在窗体上增加文件、播放、信息等菜单。
3.在工具箱的WindowsForms(Windows窗体)面板中,为您的窗体添加一个工具栏、一个状态栏和图片imageList。
4.在Properties(属性)窗口中,将工具栏的名称更改为toolBar1,将在Buttons上增加4个按钮。
状态栏的名称更改为statusBar1,并分别增加三个Panel。
5.在工具箱的面板中,为您的窗体添加一个面版panel1。
6.增加一个定时器timer1。
7.调整控件在窗体中的排列方式,使之符合您的需要而且方便用户使用。
下图为VisualStudioDesigner(设计器)中完成后的窗体布局。
图3
编写代码
如何打开你想要媒体文件?
第一步是编写在frmPlayMedia中打开WindowsMedia文件的代码。
要自动切换到Code(代码)视图并编辑打开菜单的Click事件处理程序(menuItem2_Click)的代码,请双击窗体上的“工具栏”按钮。
将以下代码添加到事件处理程序中:
还记得吗"
文件->
打开..."
是的几乎每个使用windows的人都会这样操作.如何实现?
很简单看看下面的代码:
OpenFileDialogopenFileDialog=newOpenFileDialog();
openFileDialog.Filter="
MediaFiles|*.mpg;
*.avi;
*.wma;
*.mov;
*.wav;
*.mp2;
*.MP3|AllFiles|*.*"
;
if(DialogResult.OK==openFileDialog.ShowDialog())
{
….
}
看吧很简单是吗?
记得写一个函数把它放进去。
当你点击OK按钮的时候,DirectShow接口就会得到你想要播放的文件。
下图解释了它是如何工作的。
DirectShow为多媒体流回放提供最基本的服务,这些多媒体流可以是本地文件,还可以是服务器传输过来的。
特别的,DirectShow可以支持视频回放,支持以不同的文件和流格式压缩视频内容,包括WindowsMedia、MPEG、AVI和WAV。
在DirectShow的核心处,服务是组件的模块化集合,称为过滤器,可以根据媒体类型排列成过滤器图。
过滤器可以操作数据流,如读入、分析、解码、格式化或渲染。
过滤器以树型进行排列,这棵树称为过滤器树,通过过滤器树管理器(FilterGraphManager,简称FGM)进行管理。
使用FGM应用程序可以通过使用MicrosoftWindowsMediaPlayer控件间接控制过滤器树,还可以通过调用COM接口方法直接控制。
DirectShow过滤器树(参阅图1)由从源到目标渲染器的有向过滤器序列组成,所有这些通过输入和输出过滤器引脚连接。
过滤器引脚协商它们将支持哪些媒体类型。
FGM控制树过滤器之间的多媒体数据流。
因为DirectShow有一个灵活的、可重配置的过滤器树体系结构,因此DirectShow可以使用同样的软件成分支持多种媒体类型的回放和分流。
开发人员还可以通过编写自己的过滤器扩展DirectShow多媒体支持。
过滤器
过滤器是注册的DirectShow类,它执行许多媒体信息处理任务。
这些任务包括:
获得源信息(例如,获得媒体流)
分析(例如,在流上执行包读入、分离和格式化)
转换(例如,解码WMA和MPEG-4音频和视频流)
渲染(例如,在适当的时候产生音频PCM或者视频RGB/YUV输出,将数据传给DirectSound和DirectDraw)
过滤器使用几种类型的接口,例如引脚、计数器、传送器和时钟接口,来执行它们的任务。
过滤器实现和开放了许多接口。
FGM可以使用这些接口创建、连接和控制树。
过滤器经常实现包含下列方法的IBaseFilter接口:
运行、停止和暂停过滤器状态。
恢复过滤器和厂商信息。
得到和设置参考时钟。
恢复过滤器状态信息。
枚举过滤器引线。
重建过滤器树时定位引脚
用户单击“打开”时,这段代码将显示一个对话框,供用户在计算机上浏览并选择要播放的.wma或.wmv文件。
用户选择文件(并单击“确定”)时,代码将Player的URL属性设置为用户选择的文件。
由于Player的autoStart属性在默认情况下设置为True,所以Player立即打开并播放用户选择的数字媒体文件。
接下来,添加播放/暂停按钮的代码。
在代码窗口中,在停止、暂停菜单中单击,然后,在方法名称列表中单击Click。
将以下代码添加到VisualC#为您创建的Click事件处理程序中:
看看下面的代码是如何实现的:
CleanUp();
m_objFilterGraph=newFilgraphManager();
m_objFilterGraph.RenderFile(openFileDialog.FileName);
m_objBasicAudio=m_objFilterGraphasIBasicAudio;
try
m_objVideoWindow=m_objFilterGraphasIVideoWindow;
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(Exceptionex)
m_objVideoWindow=null;
m_objMediaEvent=m_objFilterGraphasIMediaEvent;
m_objMediaEventEx=m_objFilterGraphasIMediaEventEx;
m_objMediaEventEx.SetNotifyWindow((int)this.Handle,WM_GRAPHNOTIFY,0);
m_objMediaPosition=m_objFilterGraphasIMediaPosition;
m_objMediaControl=m_objFilterGraphasIMediaControl;
//
如何来播放,暂停,停止?
简单这些函数看字面也知道.
m_objMediaControl.Run();
//播放
m_objMediaControl.Pause();
//暂停
m_objMediaControl.Stop();
//停止
//这段代码非常简单。
当用户单击播放/暂停按钮时,代码将检查Player的playState属性。
如果Player正在播放数字媒体文件,代码就会暂停文件的播放;
如果Player已经暂停或停止,代码就再次启动Player播放文件。
OK,在来看我们是如何控制时间进度的?
privatevoidtimer1_Tick(objectsender,System.EventArgse)
if(m_CurrentStatus==MediaStatus.Running)
{
UpdateStatusBar();
}
看见上面那个UpdateStatusBar();
这里是让它没100ms更新一次状态栏.
代码如下:
privatevoidUpdateStatusBar()
switch(m_CurrentStatus)
caseMediaStatus.None:
statusBarPanel1.Text="
Stopped"
break;
caseMediaStatus.Paused:
Paused"
caseMediaStatus.Running:
Running"
caseMediaStatus.Stopped:
if(m_objMediaPosition!
=null)
ints=(int)m_objMediaPosition.Duration;
inth=s/3600;
intm=(s-(h*3600))/60;
s=s-(h*3600+m*60);
statusBarPanel2.Text=String.Format("
{0:
D2}:
{1:
{2:
D2}"
h,m,s);
s=(int)m_objMediaPosition.CurrentPosition;
h=s/3600;
m=(s-(h*3600))/60;
statusBarPanel3.Text=String.Format("
else
statusBarPanel2.Text="
00:
00"
statusBarPanel3.Text="
还有一个问题程序怎么能够知道它播放完了?
这会有点麻烦了,想想看有什么办法呢?
对了,windows是消息驱动的。
那找找看有什么消息。
有的就EC_COMPLETE。
还记得"
WndProc"
它吗?
是的,我的老朋友,这次我们必须要改写它来捕获EC_COMPLETE消息。
这个消息是DirectShow通知父窗体,播放结束了。
protectedoverridevoidWndProc(refMessagem)
if(m.Msg==WM_GRAPHNOTIFY)
intlEventCode;
intlParam1,lParam2;
while(true)
{
try
{
m_objMediaEventEx.GetEvent(outlEventCode,outlParam1,outlParam2,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(refm);
只要播放状态改变,上述代码就会运行。
如果Player正在播放(用户打开文件时就处于播放状态,因为autoStart设置为True),代码将启用播放/暂停按钮和停止按钮,以便用户执行操作。
之后,代码将播放/暂停按钮的文字更改为“暂停”,这样用户就可以使用该按钮暂停播放过程。
最后,代码检索当前数字媒体文件的标题,并更新标题标签的文字以显示标题。
如果Player被暂停(用户单击了播放/暂停按钮),代码会将播放/暂停按钮的文字更改为“播放”,以提示用户使用该按钮可以恢复播放。
如果Player被停止(用户单击了停止按钮),代码将禁用停止按钮(因Player已经停止工作)并将播放/暂停按钮的文字恢复为默认值“播放”。
一切都结束了,现在要做的事就是做些来找一部影片来享受一下自己的成果了.
编写完示例项目的代码之后,您可以生成并运行解决方案。
生成解决方案
在Build(生成)菜单中单击BuildSolution(生成解决方案)。
VisualStudio开始编译并生成项目。
如果键入内容全部正确,生成过程将顺利完成,不会出现任何错误。
如果生成报告错误,则请检查您的代码并纠正错误。
使用示例应用程序
要在调试器中运行项目,请按键盘上的F5键。
如果出现“查看生成的代码”主题中介绍的未处理的异常,则应该停止调试会话,删除或注释掉生成代码中的相应行,然后再按F5键。
您可以单击“打开”查找.wma或.wmv文件(究竟选择何种文件,取决于您在“打开”对话框中选择的文件类型)。
选择某个文件并单击“确定”之后,“打开”对话框关闭,开始播放数字媒体文件,传输控制按钮的状态也随之改变。
这时您就可以利用传输控制按钮来暂停、重新开始或完全停止播放。