首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 媒体动画 > 多媒体 >

一个用C#开发的DirectShow媒体播放器(著者:Daniel Strigl)

2012-08-27 
一个用C#开发的DirectShow媒体播放器(作者:Daniel Strigl)演示程序介绍;由于我第一次写关于代码介绍方面的

一个用C#开发的DirectShow媒体播放器(作者:Daniel Strigl)
演示程序
 
介绍;
由于我第一次写关于代码介绍方面的文章,请原谅我的英语很差。我只是在学校中和一些工作中接触过英文。
我希望每个人可以理解这篇文章的内容。如果有问题我很愿意解答。如果发现有错,请即使纠正-感谢帮助我学习英文;-)。
好现在开始
这个小程序演示了,用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);
}

[解决办法]
呵呵,支持下
[解决办法]
有点难度哦

热点排行