C# Media Player控件.docx
《C# Media Player控件.docx》由会员分享,可在线阅读,更多相关《C# Media Player控件.docx(13页珍藏版)》请在冰豆网上搜索。
C#MediaPlayer控件
C#MediaPlayer控件
C#MediaPlayer控件Mediaplayer控件基本使用步骤如下:
一、往控件箱中添加此控件:
wmp.dll
二、往窗体上拖控件
三、wmp.URL=XXXX;wmp.play()即可。
平常应用就这三步就OK了。
但是,我想写个播放器的话,就遇到了一些问题。
在dotnet中使用非基于dotnet的控件,需要做一些额外的事,不过这些事vs已经帮我们做好了,当我们拖了此控件进窗体时,vs会自动调用AxImp.exe,用它根据原有的dll或ocx生成一个用AxHost类包装的新的一组程序集(更为精确的描述见msdn),于是根据WMPLib.dll生成两个文件:
AxInterop.WMPLib.dll、Interop.WMPLib.dll。
这两个文件中包含了转化后的类。
包装后的控件继承自System.Windows.Forms.AxHost。
这是第一个问题,控件怎么使用呢?
如果是拖控件,很简单,无论如何都能有效的使用。
但是,如果手工new创建控件的实例呢?
那就不一定了。
我做过种种实验,获得如下的结论:
在非可视化类中无法创建有UI的控件的实例,或者是在没有把实例加入到一个可视化的容器中时。
我实验了下面的代码:
AxWMPLib.AxWindowsMediaPlayerwmp=newAxWMPLib.AxWindowsMediaPlayer();
this.Controls.Add(wmp);
wmp.URL="约定.mp3";
wmp.Ctlcontrols.play();
这几行代码不一定能运行。
发现,如果这几行代码写在窗体的构造函数中,哪怕show出来都不能运行,只有写在Load或Load之后的事件中,并且把窗体show出来才有运行,否则会抛出一个错误:
引发类型为“System.Windows.Forms.AxHost+InvalidActiveXStateException”的异常。
网上有些人也遇到这个问题,其实都没有谈到点子上。
甚为遗憾。
是不是不show就一定不能运行呢?
我拖了个播放器控件放窗体上,在InitializeComponent后面写了行play的代码,能运行。
可见,这中间有蹊跷啊。
我比较了上面的代码跟拖上去生成的代码,有两点不同:
一、拖控件生成的代码为多一对((System.ComponentModel.ISupportInitialize)(this.wmp1)).BeginInit()/EndInit()
二、拖的控件多了一行:
this.wmp1.OcxState=((System.Windows.Forms.AxHost.State)(resources.GetObject("wmp1.OcxState")));我查了MSDN,ocxstate是控件状态。
用于持久化控件的状态的。
com组件的状态信息被写在对应窗体的资源文件中,用记事本打开窗体资源文件就可以看到。
在手工创建中,这个ocxstate是没法赋值的。
我试了加入BeginInit、EndInit,没用,可见问题是出在控件状态问题上。
没有办法了。
取当前播放媒体的信息,这个很简单,currentMedia就可以取得。
怎样创建播放列表呢?
让播放器依次播放指定的媒体呢?
有办法,我自己摸索出来的:
wmp1.currentPlaylist.appendItem(wmp1.newMedia("约定.mp3"))
我看到网上的兄弟不晓得用currentPlaylist,在自己实现播放列表,我觉得没必要。
郁闷无比,用wmp播放rmvb等非默认支持文件时,会弹出错误消息框,尽可以用一个属性wmp.settings.enableErrorDialogs=false控制它不显示,但是,还是有一个后遗症,就是调用wmp.Ctlcontrols.play()时,它并不会播放,但是单击一下自带播放控制栏中的三角行按钮就能播放了。
郁闷啊。
我又去的了暴风3的mps.dll。
果然,它用的是酷热影音的内核。
不过,酷热提供的这个控件实在太差劲了。
没什么高级功能。
郁闷。
还是wmp好啊。
继续研究wmp。
我现在装的是wmp11。
现在又找到一些更全的关于wmpAPI的资料,如下:
属性/方法名说明:
详尽的API文档(比MSDN更透彻):
[基本属性]
URL:
String;指定媒体位置,本机或网络地址
uiMode:
String;播放器界面模式,可为Full,Mini,None,Invisible(不计大小写)
playState:
integer;播放状态。
这个属性改变时同时引发PlayStateChange事件与StateChange事件。
取值范围为枚举型:
WMPLib.WMPPlayState,它的成员如下:
wmppsUndefined=0; //未知状态
wmppsStopped=1; //播放停止
wmppsPaused=2; //播放暂停
wmppsPlaying=3; //正在播放
wmppsScanForward=4; //向前搜索
wmppsScanReverse=5; //向后搜索
wmppsBuffering=6; //正在缓冲
wmppsWaiting=7; //正在等待流开始
wmppsMediaEnded=8; //播放流已结束
wmppsTransitioning=9; //准备新的媒体文件
wmppsReady=10; //播放准备就绪
wmppsReconnecting=11; //尝试重新连接流媒体数据
wmppsLast=12; //上一次状态,状态没有改变
在PlayStateChange中写代码可以防止播放rmvb等非默认类型的问题(用wmppsReady)。
enableContextMenu:
Boolean; 启用/禁用右键菜单
fullScreen:
boolean; 是否全屏显示
//播放器基本控制
Ctlcontrols.play;播放
Ctlcontrols.pause;暂停
Ctlcontrols.stop;停止
Ctlcontrols.currentPosition:
double;当前进度
Ctlcontrols.currentPositionString:
string;当前进度,字符串格式。
如“00:
23”
Ctlcontrols.fastForward;快进
Ctlcontrols.fastReverse;快退
Ctlcontrols.next;下一曲
Ctlcontrols.previous;上一曲
[settings]wmp.settings//播放器基本设置
settings.volume:
integer;音量,0-100
settings.autoStart:
Boolean;是否自动播放
settings.mute:
Boolean;是否静音
settings.playCount:
integer;播放次数
//顺序播放
wmp.settings.setMode("shuffle",False)
//随机播放
wmp.settings.setMode("shuffle",True)
//循环播放
wmp.settings.setMode("loop",True)
[currentMedia]wmp.currentMedia//当前媒体属性
currentMedia.duration:
double;媒体总长度
currentMedia.durationString:
string;媒体总长度,字符串格式。
如“03:
24”
currentMedia.getItemInfo(conststring);获取当前媒体信息"Title"=媒体标题,"Author"=艺术家,"Copyright"=版权信息,"Description"=媒体内容描述,"Duration"=持续时间(秒),"FileSize"=文件大小,"FileType"=文件类型,"sourceURL"=原始地址
currentMedia.setItemInfo(conststring);通过属性名设置媒体信息
currentMedia.name:
string;同currentMedia.getItemInfo("Title")
[currentPlaylist]wmp.currentPlaylist//当前播放列表属性
currentPlaylist.count:
integer;当前播放列表所包含媒体数
currentPlaylist.Item[integer];获取或设置指定项目媒体信息,其子属性同wmp.currentMedia
axWindowsMediaPlayer1.currentMedia.sourceURL;//获取正在播放的媒体文件的路径
axWindowsMediaPlayer1.currentMedia.name;//获取正在播放的媒体文件的名称
axWindowsMediaPlayer1.Ctlcontrols.Play 播放
axWindowsMediaPlayer1.Ctlcontrols.Stop 停止
axWindowsMediaPlayer1.Ctlcontrols.Pause 暂停
axWindowsMediaPlayer1.Ctlcontrols.PlayCount 文件播放次数
axWindowsMediaPlayer1.Ctlcontrols.AutoRewind 是否循环播放(无效)
axWindowsMediaPlayer1.Ctlcontrols.Balance 声道
axWindowsMediaPlayer1.Ctlcontrols.Volume 音量
axWindowsMediaPlayer1.Ctlcontrols.Mute 静音
axWindowsMediaPlayer1.EnableContextMenu 是否允许在控件上点击鼠标右键时弹出快捷菜单
axWindowsMediaPlayer1.Ctlcontrols.AnimationAtStart 是否在播放前先播放动画(无效)
axWindowsMediaPlayer1.Ctlcontrols.ShowControls 是否显示控件工具栏(无效)
axWindowsMediaPlayer1.Ctlcontrols.ShowAudioControls 是否显示声音控制按钮(无效)
axWindowsMediaPlayer1.Ctlcontrols.ShowDisplay 是否显示数据文件的相关信息(无效)
axWindowsMediaPlayer1.Ctlcontrols.ShowGotoBar 是否显示Goto栏(无效)
axWindowsMediaPlayer1.Ctlcontrols.ShowPositionControls 是否显示位置调节按钮(无效)
axWindowsMediaPlayer1.Ctlcontrols.ShowStatusBar 是否显示状态栏(无效)
axWindowsMediaPlayer1.Ctlcontrols.ShowTracker 是否显示进度条(无效)
axWindowsMediaPlayer1.Ctlcontrols.FastForward 快进
axWindowsMediaPlayer1.Ctlcontrols.FastReverse 快退
axWindowsMediaPlayer1.Ctlcontrols.Rate 快进/快退速率
axWindowsMediaPlayer1.AllowChangeDisplaySize 是否允许自由设置播放图象大小(无效)
axWindowsMediaPlayer1.DisplaySize 设置播放图象大小(无效)
1-MpDefaultSize 原始大小
2-MpHalfSize 原始大小的一半
3-MpDoubleSize 原始大小的两倍
4-MpFullScreen 全屏
5-MpOneSixteenthScreen 屏幕大小的1/16
6-MpOneFourthScreen 屏幕大小的1/4
7-MpOneHalfScreen 屏幕大小的1/2
axWindowsMediaPlayer1.ClickToPlay 是否允许单击播放窗口启动MediaPlayer
在视频播放之后,可以通过如下方式读取源视频的宽度和高度,然后设置其还原为原始的大小.
privatevoidResizeOriginal()
{
intintWidth=axWindowsMediaPlayer1.currentMedia.imageSourceWidth;
intintHeight=axWindowsMediaPlayer1.currentMedia.imageSourceHeight;
axWindowsMediaPlayer1.Width=intWidth+2;
axWindowsMediaPlayer1.Height=intHeight+2;
}
打开媒体文件并播放:
DimfilePathAsString
WithMe.OpenFileDialog1
.Title="打开语音文件"
.CheckPathExists=True
.CheckFileExists=True
.Multiselect=False
.Filter="mp3文件(*.mp3)|*.mp3|所有文件(*.*)|*.*"
If.ShowDialog=DialogResult.CancelThen
ExitSub
EndIf
filePath=.FileName
EndWith
Me.Text="PC复读机-文件"&filePath
AxWindowsMediaPlayer1.URL=filePath
Try
Me.AxWindowsMediaPlayer1.Ctlcontrols.play()
CatchexAsException
MsgBox("对不起,不能播放此格式语音文件",MsgBoxStyle.OKOnly,"PC复读机")
ExitSub
EndTry
注意:
AxWindowsMediaPlayer1.URL中URL是表示要播放的文件名,取消了原来的Name属性.
AxWindowsMediaPlayer1.Ctlcontrols.play()播放,同样还有Pause,Stop等其他属性.
AxWindowsMediaPlayer1.settings.balance表示媒体播放的声道设置,0表示均衡,-1和1表示左右声道.
AxWindowsMediaPlayer1.currentMedia.duration表示要播放的文件的时间长度.可用它获取文件长度.
AxWindowsMediaPlayer1.Ctlcontrols.currentPosition表示正在播放的文件的当前播放位置,可用这个属性来对媒体文件进行前进后退等设置.如
AxWindowsMediaPlayer1.Ctlcontrols.currentPosition+1表示前进1个时间单位.
AxWindowsMediaPlayer1.settings.rate播放速率,一般乘以16后再显示kbps单位.
注意:
在上面程序中,如果在后面加上一个:
msgbox(AxWindowsMediaPlayer1.currentMedia.duration.ToString)
则显示结果很可能为0,因此,这时候很可能获取不到文件的播放时间长度,容易出错。
所以在利用的时候可以加一个timer控件:
PrivateSubTimer1_Tick(ByValsenderAsObject,ByValeAsSystem.EventArgs)HandlesTimer1.Tick
EndPoint=AxWindowsMediaPlayer1.currentMedia.duration
IfEndPoint=0ThenExitSub'可能因为媒体文件的打开需要一定时间,这里等待媒体文件的打开
msgbox(AxWindowsMediaPlayer1.currentMedia.duration.ToString)
EndSub
此时msgbox便会显示文件播放长度。
2.Ctlcontrols属性
Ctlcontrols属性是AxWindowsMediaPlayer的一个重要属性,此控件中有许多常用成员。
(1)方法play
用于播放多媒体文件,其格式为:
窗体名.控件名.Ctlcontrols.play()
如:
AxWindowsMediaPlayer1.Ctlcontrols.play()‘此处缺省窗体名是Me
(2)方法pause
用于暂停正在播放的多媒体文件,其格式为:
窗体名.控件名.Ctlcontrols.pause()
如:
AxWindowsMediaPlayer1.Ctlcontrols.pause()
(3)方法stop
用于停止正在播放的多媒体文件,其格式为:
窗体名.控件名.Ctlcontrols.stop()
如:
AxWindowsMediaPlayer1.Ctlcontrols.stop()
(4)方法fastforward
用于将正在播放的多媒体文件快进,其格式为:
窗体名.控件名.Ctlcontrols.fastforward()
如:
AxWindowsMediaPlayer1.Ctlcontrols.forward()
(5)方法fastreverse
窗体名.控件名.Ctlcontrols.fastreverse()
如:
AxWindowsMediaPlayer1.Ctlcontrols.fastreverse()
6.属性CurrentPosition
用于获取多媒体文件当前的播放进度,其值是数值类型,使用格式为:
窗体名.控件名.Ctlcontrols.currentPosition
d1=AxWindowsMediaPlayer1.Ctlcontrols.currentPosition
其中d1是一个整型变量。
7.属性Duration
用于获取当前多媒体文件的播放的总时间,其值为数值类型,其使用格式为:
窗体名.控件名.currentMedia.duration
如:
d2=AxWindowsMediaPlayer1.currentMedia.duration
其中d2是一个整型变量。
对WMP的感叹
感叹一
这是我找到的关于WMP的最全的中文资料了。
刚才又查了一下,查到了MSDN有更全的API文档,终于找到它了。
上面的资料基本上够用了,但是,如果要写一个更为精致的播放器,这些还不够啊。
看MSDN去也。
WMP11在MSDN中的位置如下:
win32和COM开发-GriphicsAndMultiMedia-AudioAndVedio-WindowsMediaPlayer11SDK
看了一个晚上的MSDN与资料。
发现MSDN上关于WMPSDK的文档也很不扎实。
没有实例。
我要找的答案都不在上面。
唯一的收获是晓得了wpl。
wmp有自己的播放列表文件,但是,我查遍msdn,发现sdk并不提供手动保存播放列表的任何方法。
所以,现在的问题是,我们创建了一个IWMPPlayList,但是,这个接口不提供任何保存的方法,结果。
newPlayList(name,path)只提供打开一个已有列表。
郁闷。
查了英文资料。
老外建议用:
StreamWrite/StreamRead的办法来读写wpl,我也看了。
事实上wpl是一个xml文件。
我们可以用System.Xml中的API来读写。
不过,sdk中的这个漏子我始终无法释怀。
感叹二
从WMP8开始就不支持mms/rtsp协议了,所用wmp.URL="mms:
//xxxx";是不行的了。
点此处见详情,而mms这个协议现在还在广泛使用。
郁闷。
因此,我们不能使用wmp来看网络电视了。
使用WMP的常见问题:
一、升级wmp后,再拖windowsmediaplayer控件至窗体出错的问题(至今没解决,应当是修改工程序文件,用文本编辑器)
二、播放rmvb/rm等非官方格式文件要先双击文件再点播放按钮,而不能直接播放的问题,并弹出消息框:
WindowsMediaPlayer下载文件遇到问题。
有关帮助信息请单击“Web帮助”。
消息下面两个按钮:
关闭、Web帮助。
我没有找到出现这个问题的官方说明。
我个人意见,这是因为wmp默认只播能播放官方指定的几种类型的媒体。
如果不是,wmp会试图下载对应的解码器来播放。
而这个下载过程失败了,所以弹出这个消息框。
wmp好像没有去判断这个解码器是否已经存在。
但是,如果你再点播放的话,又能播放,这是什么原因呢?
应当是wmp在这次会试图搜索本机上的解码器以图播放媒体。
怎样解决这个点两次鼠标的问题呢?
如下:
先设置属性:
wmp.settings.enableErrorDialogs=false;事实上这个属性默认就是false。
不用设置。
privatevoidwmp_PlayStateChange(objectsender,AxWMPLib._WMPOCXEvents_PlayStateChangeEvente)
{
//如果已播放完毕就播放下一个文件
if((WMPLib.WMPPlayState)e.newState==WMPLib.WMPPlayState.wmppsReady)wmp.Ctlcontrols.play();
}
唉,我费了九牛二虎之力总算找到了这个办法解决。
三、怎样获得一个媒体文件中的信息,并且修改媒体的一些信息?
有办法:
AxWindowsMediaPlayer.newMedia(filename),它会创建一个IWMPMedia的实例。
用它的setItemInfo就成了。
至于有哪些信息可供设置,可去msdn中查,里面列举了所有相关信息。
四、IWMPPlayList是不是鸡肋?
?
?
?
?
?
?
?
确实是好大的一块鸡肋!
!
!
!
!
!
!
!
!
!
!