Visual C#使用DirectX实现视频播放

很多人第一次接触到directx大都是通过游戏,至于安装、升级directx的原因无非是满足游戏运行的需要。direct x其实是微软公司推出的一个为windows平台的多媒体api函数库,它提供标准接口来与显卡和声卡、输入设备等进行交互。如果没有这组标准api函数库,那你就需要为每一种显卡、声卡的每个组合和每种类型的键盘、鼠标和游戏杆编写不同的代码。这不又回到了以前的dos时代。为了解决这个问题,微软公司推出了directx。directx从具体的硬件中抽象出来,并且将一组通用指令转换成硬件的具体命令。这样开发语言通过调用统一标准的direct x函数库就可以操作每一种显卡、声卡的每个组合和每种类型的键盘、鼠标和游戏杆等多媒体了。

   一.direct x sdk 9.0安装及类库介绍:

  .net framework sdk中并没有包含direct x sdk,所以为了顺利的完成本文后面介绍,
必须先下载、安装direct x sdk。具体的下载地址为:http://download.microsoft.com/download/a/c/d/acdfb557-266f-4af4-8673-6ab8009b4ddd/dxsdk_apr2005.exe。此版本是2005四月份推出的英文版。这并不妨碍下面的程序实现。安装完direct x后,就会在存在"c:\windows\microsoft.net\managed directx"这样一个目录,此目录中目录中应该有九个dll文件和九个xml文件。九个dll文件大致对应于directx中的十个命名空间。编程中就是使用其中的命名空间来提供对输入设备、声音、网络播放、图形等的支持。direct x sdk 9.0中的定义的命名空间及其主要的作用具体如表01所示:

命名空间 描述
microsoft.directx 公共类和数学结构
microsoft.directx.direct3d 3d图形和助手库
microsoft.directx.directdraw direct draw 图形api。这是旧式命名空间,现在已经不需要使用它。
microsoft.directx.directplay 用于多玩家游戏的网络api
microsoft.directx.directsound 声音支持
microsoft.directx.directinput 输入设备支持(例如,鼠标和游戏杆)
microsoft.directx.audiovideoplayback 播放视频和音频(例如,在电脑上播放各自视频动画文件)
microsoft.directx.diagnostics 疑难解答
microsoft.directx.security 访问安全性
microsoft.directx.security.permissions 访问安全权限
       表01:direct x sdk9.0中的定义的命名空间及其主要的作用

  direct x内容十分丰富,下文介绍的只是其中的一个小的应用,即用visual c#调用direct x中的sdk来播放视频文件为例子,程序中只使用了命名空间"microsoft.directx.audiovideoplayback"。 microsoft.directx.audiovideoplayback命名空间中定义了三个类:"audio"、"video"和"texturerendereventargs"。其中前二个类是最常用的,分别用来支持音频和视频。microsoft.directx.audiovideoplayback命名空间中定义的常用属性及其具体的作用可参阅表02所示:

属性 描述
audio 获取视频文件中的音频对象,可用来后续的音频播放
caption 获取或设置在form上播放视频的名称
currentposition 获取或设置播放视频的当前位置
defaultsize 获取播放视频的缺省的视频大小
fullscreen 获取或设置视频文件是否在全屏模式下播放
iscursorhidden 获取播放的视频时鼠标的状态:隐藏或显示
owner 获取或设置视频播放的宿主组件
paused 获取当前的播放状态是否处于暂停状态
playing 获取当前的播放状态是否处于播放状态.
seekingcaps 获取是否可以搜索性能
size retrieves and sets the size of the video for playback.
state 获取当前的播放状态
stopped 获取当前的播放状态是否处于停止状态
stopposition 获取播放的视频的停止播放位置
    表02:microsoft.directx.audiovideoplayback命名空间中定义的常用属性及其具体的作用

  microsoft.directx.audiovideoplayback命名空间中定义的常用方法及其具体的作用可参阅表03所示:

方法 描述
hidecursor 隐藏当前播放视频的鼠标
open 装入新的文件到video对象中
pause 设置为暂停播放状态.
play 设置为播放状态
seekcurrentposition 搜索转入到制定的播放位置
seekstopposition 设置一个新的停止位置
showcursor 显示当前播放视频的鼠标
stop 设置为停止播放状态
video 初始化一个新的video实例
    表03:microsoft.directx.audiovideoplayback命名空间中定义的常用属性及其具体的作用

  了解了以上这些基础知识后,下面就开始介绍visual c#调用direct x播放视频文件的具体实现方法。

   二.本文章的程序设计、调试和运行的环境:

  (1).微软公司视窗2003中文企业版。

  (2).visual studio .net 2003企业构建版,.net framework sdk 1.1版本号4322。

  三.visual c#使用direct x的实现视频播放


  visual c#使用direct x的实现视频播放难点无非以下几点:

  1. 掌握在visual c#引入dirext x函数库的方法。

  2. 设置direct x视频播放的宿主组件。

  3. 基本的播放命令的设置:播放、停止、暂停等。

  下面就是visual c#使用direct x的实现视频播放具体实现步骤:

  1. 启动visual studio .net。

  2. 选择菜单【文件】|【新建】|【项目】后,弹出【新建项目】对话框。

  3. 将【项目类型】设置为【visual c#项目】。

  4. 将【模板】设置为【windows应用程序】。

  5. 在【名称】文本框中输入【visual c#中使用driectx实现媒体播放】。

  6. 在【位置】的文本框中输入【e:\vs.net项目】,然后单击【确定】按钮。这样在"e:\vs.net项目"目录中就创建了一个名称为"visual c#中使用driectx实现媒体播放"的文件夹,里面存放的就是"visual c#中使用driectx实现媒体播放"项目的所有文件。

  7. 选中【解决方案管理器】|【引用】,单击鼠标右键,选中【添加引用】菜单,具体如图01所示:


图01:添加引用

  8. 选中【添加引用】菜单后,弹出【添加引用】对话框,按照图02所示,在【选定的组件】栏目中加入"microsoft.directx.audiovideoplayback"后,单击【确定】按钮,则引用"microsoft.directx.audiovideoplayback"文件成功。这是因为visual studio .net的缺省编译环境中没有"microsoft.directx.audiovideoplayback.dll"文件,而程序中却使用到"microsoft.directx.audiovideoplayback"命名空间,所以要在编译环境中引用"microsoft.directx.audiovideoplayback"所在的文件。


  9. 把visual studio .net的当前窗口切换到【form1.cs(设计)】窗口,并从【工具箱】中的【windows窗体组件】选项卡中往设计窗体中拖入下列组件,并执行相应操作:

  一个openfiledialog组件,用于选择播放的视频;一个panel组件,作为视频播放的宿主组件;四个button按钮,分别执行视频打开、播放、暂停和停止操作。并在这四个组件拖入设计窗口后分别双击它们,则系统会在form1.cs中分别产生这四个组件click事件对应的处理代码。

  10. 把visual studio .net的当前窗口切换到form1.cs的代码编辑窗口,在form1.cs的首部的引入命名空间的代码区中,用下列代码替换form1.cs中由系统自动产生的引入命名空间代码:

using system ;
using system.drawing ;
using system.collections ;
using system.componentmodel ;
using system.windows.forms ;
using system.data ;
using microsoft.directx.audiovideoplayback ;
//引入视频播放所要使用的direct x命名空间

  11. 在form1.cs的class的代码区中添加下列代码,下列代码是创建全局使用的video实例:

private video myvideo = null ;
//创建一个video实例

  12. 以下面代码替代系统产生的initializecomponent过程。下面代码是对加入窗体的组件以及创建的全局变量进行初始化和定义四个button组件的click事件和form1的load事件:

private void initializecomponent ( )
{
 this.panel1 = new system.windows.forms.panel ( ) ;
 this.button1 = new system.windows.forms.button ( ) ;
 this.button2 = new system.windows.forms.button ( ) ;
 this.button3 = new system.windows.forms.button ( ) ;
 this.button4 = new system.windows.forms.button ( ) ;
 this.openfiledialog1 = new system.windows.forms.openfiledialog ( ) ;
 this.suspendlayout ( ) ;
 this.panel1.dock = system.windows.forms.dockstyle.top ;
 this.panel1.location = new system.drawing.point ( 0, 0 ) ;
 this.panel1.name = "panel1" ;
 this.panel1.size = new system.drawing.size ( 540, 346 ) ;
 this.panel1.tabindex = 0 ;
 this.button1.location = new system.drawing.point ( 62, 380 ) ;
 this.button1.name = "button1" ;
 this.button1.size = new system.drawing.size ( 80, 38 ) ;
 this.button1.tabindex = 1 ;
 this.button1.text = "打开" ;
 this.button1.click += new system.eventhandler ( this.button1_click ) ;
 this.button2.location = new system.drawing.point ( 165, 380 ) ;
 this.button2.name = "button2" ;
 this.button2.size = new system.drawing.size ( 81, 38 ) ;
 this.button2.tabindex = 1 ;
 this.button2.text = "播放" ;
 this.button2.click += new system.eventhandler ( this.button2_click ) ;
 this.button3.location = new system.drawing.point ( 268, 380 ) ;
 this.button3.name = "button3" ;
 this.button3.size = new system.drawing.size ( 80, 38 ) ;
 this.button3.tabindex = 1 ;
 this.button3.text = "暂停" ;
 this.button3.click += new system.eventhandler ( this.button3_click ) ;
 this.button4.location = new system.drawing.point ( 371, 380 ) ;
 this.button4.name = "button4" ;
 this.button4.size = new system.drawing.size ( 81, 38 ) ;
 this.button4.tabindex = 1 ;
 this.button4.text = "停止" ;
 this.button4.click += new system.eventhandler ( this.button4_click ) ;
 this.openfiledialog1.defaultext = "avi" ;
 this.openfiledialog1.filter = "视频文件|*.avi||" ;
 this.openfiledialog1.title = "请选择播放的avi文件" ;
 this.autoscalebasesize = new system.drawing.size ( 6, 14 ) ;
 this.clientsize = new system.drawing.size ( 540, 461 ) ;
 this.controls.add ( this.button1 ) ;
 this.controls.add ( this.panel1 ) ;
 this.controls.add ( this.button2 ) ;
 this.controls.add ( this.button3 ) ;
 this.controls.add ( this.button4 ) ;
 this.formborderstyle = system.windows.forms.formborderstyle.fixeddialog ;
 this.maximizebox = false ;
 this.name = "form1" ;
 this.text = "visual c#中使用driectx实现媒体播放" ;
 this.load += new system.eventhandler ( this.form1_load ) ;
 this.resumelayout ( false ) ;
}

  至此【visual c#中使用driectx实现媒体播放】项目的界面设计和功能实现的前期工作就完成了,设计界面如图03所示:


图03:【visual c#中使用driectx实现媒体播放】项目的界面设计

  13. 用下列代码替换form1.cs中的button1组件的click事件对应的处理代码,下列代码的功能是打开选定的视频文件,并在定义的panel组件上显示开始第一帧:

private void button1_click ( object sender, system.eventargs e )
{
 openfiledialog1.initialdirectory = application.startuppath ;
 if ( openfiledialog1.showdialog ( ) == dialogresult.ok )
 {
  // 记录panel组件的大小
  int height = panel1.height ;
  int width = panel1.width ;
  // 如果存在打开的video文件,释放它
  if ( myvideo != null )
  {
   myvideo.dispose ( ) ;
  }
  // 打开一个新的video文件
  myvideo = new video ( openfiledialog1.filename ) ;
  // 把video文件分配给创建的panel组件
  myvideo.owner = panel1 ;
  // 以记录的panel组件的大小来重新定义
  panel1.width = width ;
  panel1.height = height ;
  // 播放avi文件的第一帧,主要是为了在panel中显示
  myvideo.play ( ) ;
  myvideo.pause ( ) ;
 }
 //确定窗体中的各按钮状态
 if ( myvideo == null )
 {
  button2.enabled = false ;
  button3.enabled = false ;
  button4.enabled = false ;
 }
 else
 {
  button2.enabled = true ;
  button3.enabled = true ;
  button4.enabled = true ;
 }
}

  14. 用下列代码替换form1.cs中的button2组件的click事件对应的处理代码,下列代码的功能播放当前打开的视频文件:

private void button2_click ( object sender, system.eventargs e )
{
 if ( myvideo != null )
 {
  myvideo.play ( ) ;
 }
}

  15. 用下列代码替换form1.cs中的button3组件的click事件对应的处理代码,下列代码的功能暂停播放当前打开的视频文件:

private void button3_click ( object sender, system.eventargs e )
{
 if ( myvideo != null )
 {
  myvideo.pause ( ) ;
 }
}

  16. 用下列代码替换form1.cs中的button4组件的click事件对应的处理代码,下列代码的功能停止播放当前打开的视频文件:

private void button4_click ( object sender, system.eventargs e )
{
 if ( myvideo != null )
 {
  myvideo.stop ( ) ;
 }
}

  17. 在button4的click事件之后,添加下列代码,下列代码的功能是初始化form窗体中的button组件:

//初始化窗体中各按钮的状态
private void form1_load ( object sender, system.eventargs e )
{
 if ( myvideo == null )
 {
  button2.enabled = false ;
  button3.enabled = false ;
  button4.enabled = false ;
 }
 else
 {
  button2.enabled = true ;
  button3.enabled = true ;
  button4.enabled = true ;
 }
}

  18. 至此,在上述步骤都正确完成,并全部保存后,【visual c#中使用driectx实现媒体播放】项目的全部工作就完成了。此时单击快捷键【f5】运行程序后,图04是播放视频文件时得到的程序运行界面:


图04:【visual c#中使用driectx实现媒体播放】项目的运行界面

   四.总结:

  direct x的出现的确解决了程序员的很多底层的工作,把面对各种烦杂硬件的工作交给了direct x了。虽然direct x从非托管版本发展到现在的托管版本,争论一直存在,但越来越多的开发商把自己的软件用托管的direct x或者结合使用托管和非托管direct x开发,也从另外一个方面证明了托管的direct x的生命力。本文结合一个示例具体介绍visual c#调用非托管direct x的方法实现视频播放,这对于托管direct x来说只是其中的一个小应用。最后希望此篇文章对那些希望了解、掌握在visual c#调用direct x编写游戏程序的朋友有所帮助。

 

你可能感兴趣的:(C#)