mediaplayer 在XP下不能播放dat文件(100分)

  • 主题发起人 主题发起人 夺工1
  • 开始时间 开始时间

夺工1

Unregistered / Unconfirmed
GUEST, unregistred user!
我用mediaplayer编了一个播放器,为什么在XP下就不播放呢,本来在Win98下也不播放
后来参照原来的贴子在win.ini 中的[MCI extensions]加了一句dat=MPEGVideo就可以了,但在xp下不行,请大家帮忙看看!
 
我的计算机在用MediaPlayer播放.dat文件前要安装一个DivX才能看,不知道是不是同样的原因
 
我想不会,因为我用其它的程序如MediaPlayer8都可以播放,我猜想它的原因和98下不能正
常播放一致,只是找不到为什么。Delph好像习惯通过文件的扩展名来进行流程控制。
 
转贴一段
最近在使用MediaPlayer控件编程时发现一个奇怪的问题,刚开始百思不得其解,不知道是MediaPlayer的问题,还是Delphi的MMSystem.pas本身就错了
问题如下
MediaPlay.DeviceType的值只能设成dtAutoSelect,否则,不管是AVI,还是MPG文件都不能播放,我用Delphi6 和Delphi6 sp2 在win2000和xp环境下测试,均不能成功。
如果将设备类型设置成明显的错误,MediaPlay控件会报错,如文件是AVI或MPG格式,选择DeviceType=dtCDAudio,会报MCI错误,但是如果用AVI文件,选择dtAVIVideo,则不报任何错误,文件打开,但不管是通过程序,还是通过MediaPlay的Button总之是播放不了文件的,而且MediaPlay.Length的长度也不正确例如:
ExPlay.DeviceType :=dtAVIVideo;
ExPlay.FileName := 'd:/windows/clock.avi';
ExPlay.Open;
ExPlay.Play;
在不得已的情况下我只能去看MediaPlayer的源代码(本人对Delphi实在了解的不多)
分析情况如下
Delphi的TMediaPlayer控件的DeviceType是只能在几种类型中选择,这是在MPlay.pas中定义的几种
TMPDeviceTypes = (dtAutoSelect, dtAVIVideo, dtCDAudio, dtDAT, dtDigitalVideo, dtMMMovie,
dtOther, dtOverlay, dtScanner, dtSequencer, dtVCR, dtVideodisc, dtWaveAudio);
在MCI的定义中有如下结构:
tagMCI_OPEN_PARMSA = record
dwCallback: DWORD;
wDeviceID: MCIDEVICEID;
lpstrDeviceType: PAnsiChar;
//设备类型
lpstrElementName: PAnsiChar;
lpstrAlias: PAnsiChar;
end;

在mplay.pas中
procedure TMediaPlayer.Open;
const
DeviceName: array[TMPDeviceTypes] of PChar = ('', 'AVIVideo', 'CDAudio', 'DAT',
'DigitalVideo', 'MMMovie', 'Other', 'Overlay', 'Scanner', 'Sequencer',
'VCR', 'Videodisc', 'WaveAudio');
...设定了实际传给MCI的DeviceType值................
begin

......(mplay.pas lines 841)
OpenParm.lpstrDeviceType := DeviceName[FDeviceType];
// 你选定的设备类型
......
if FDeviceType <> dtAutoSelect then

FFlags := FFlags or mci_Open_Type;

if FDeviceType <> dtAutoSelect then
//不明白为什么这里要做两次同样的判断
FFlags := FFlags or mci_Open_Type
else

FFlags := FFlags or MCI_OPEN_ELEMENT;
//只有这样才能正确播放,也就是自动模式

OpenParm.dwCallback := Handle;
FError := mciSendCommand(0, mci_Open, FFlags, Longint(@OpenParm));
//。。。。。。

参照上面的情况,我选择DeviceType=dtAVIVideo时传的值就应该是‘AVIVideo’。这也和注册表中的MCI32项中的值对应。为了验证使用lpstrDeviceType的值确实是可以用'AVIVideo'我加载了一个MCI32.OCX,这个控件是在VS6种附带的,其中的DeviceType属性和TMediaPlayer中的DeviceType属性大致相当,只不过MCI32.ocx中的值可以直接指定到设备名,我将MCI32.ocx的DeviceType设成'AVIVideo',结果可以正常播放。
为了找出原因,我将VC的MMSystem.h文件和MMSystem.pas中的参数和数据结构作比较,没有发现有什么差异,基本判断MMSystem,pas是没有问题的,那么问题一定在mplay.pas中了。于是从mplay.pas中另外生成一个控件TDeMediaPlay,跟踪下来,居然也没有发现什么问题,文件打开MCIOpened 、设备号FDeviceID、是否显示FHasVideo等标志正常,GetDeviceCaps函数无异常,唯独GetLength函数中
FError := mciSendCommand( FDeviceID, mci_Status, FFlags, Longint(@StatusParm));
Result := StatusParm.dwReturn;
的返回值不正常,而且居然也没有返回错误,在我的机器上,不管怎么设置timeformat都返回4,您的机器可能会不一样
播放器之类的软件实在是以前没写过,去网上查找关于这方面的Delphi的资料,好像都是让自动选择的也就是dtAutoSelect模式的,但恰恰我的要求是一定要指定具体驱动。
没有办法,再次打开VC,找到一个MCI的例子,仔细阅读,发现了问题,例子中有这样一段代码
mciMO.lpstrDeviceType="MpegVideo";
......
dwFlags=(DWORD)(MCI_OPEN_ELEMENT|MCI_OPEN_TYPE|);
dwResult=mciSendCommand(0,MCI_OPEN,dwFlags, (DWORD)(LPMCI_DGV_OPEN_PARMS) &amp;mciMO);
......
问题好像有了一点头绪,VC代码中dwFlags在指定DeviceType后,并不是仅仅用到了MCI_OPEN_TYPE标志,而是连MCI_OPEN_ELEMENT标志一起带进去的。于是我有回到mplay.pas中,在上面提到的搞不懂为什么两段代码重复的语句中作了修改:
OpenParm.lpstrDeviceType := DeviceName[FDeviceType];
你选定的设备类型
......
if FDeviceType <> dtAutoSelect then

FFlags := FFlags or mci_Open_Type;
if FDeviceType <> dtAutoSelect then

 
找到原文,http://www.csdn.net/develop/read_article.asp?id=14940
正在研究
 
找到了,本来想用app2001的办法,但后来想改过来后还需要添加很多代码。另外我试了一下改源代码后仍未成功,所以就放弃了。后来我仍沿用设置:DeviceType:= dtAutoSelect 。
进行了测试,将XP的注册表关于MEDIA的挨个改。最后总算找到了。在Win98下系统读取的是
Win.ini的值。在XP下系统读取的是注册表的键值。现将注册表的键值公布,方便大家调用。注:仅适用于XP系统.
[HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows NT/CurrentVersion/MCI Extensions]
在此项中增加键:
"dat"="MPEGVideo"
但现在又有一个问题了:我如何判断是环境是XP系统呢!
我这儿有一个函数,但我没有XP系统,请装XP系统的网友帮我查看一下XP环境中Win32Platform 及Win32MajorVersion 的值。

function IsWindows98: Boolean;
begin

Result := (Win32Platform = VER_PLATFORM_WIN32_WINDOWS) and
((Win32MajorVersion > 4) or
((Win32MajorVersion = 4) and (Win32MinorVersion >= 10)));
end;

 
算了!自已解决了
 

Similar threads

后退
顶部