在WinForms里嵌入MediaPlayer的一些版本问题, tlbimp导入, 以及不导入而纯用C#+字符串来动态调用.
网上很多写使用WindowsMediaPlayer WMP控件的文章.
大多数都是从工具栏或COM导入.
最近正在做的CEF整合Asp.Net Core Blazor server side的过程中,
因为CEF编译支持mp4的dll是涉及了版权的问题, 不能随便干的.
要播放mp4, 可以用WinForms代劳. 执行WMP只是一小段代码, 不想导入dll ,
去查API.
发现了微软的官方文档, 和我使用的MediaPlayer的API , 有出入.
?
经过多方查证, 验证, 发现原来 MediaPlayer 一共是2个版本
一个是最后到 6.4 的 classic 版本, 一个是从 7 之后的新版本.
这篇博文用于纪录两者的区别
首先参考这个:
http://w3schools.sinsixx.com/media/media_playerref.asp.htm
6.4 | 7或以后 | |
CLSID | 22D6F312-B0F6-11D0-94AB-0080C74C7E95 | 6BF52A52-394A-11D3-B153-00C04F79FAA6 |
TypeLib | c:\windows\system32\msdxm.tlb | C:\Windows\system32\wmp.dll |
TypeLib | MediaPlayer | WMPLib |
ProgID | MediaPlayer.MediaPlayer | WMPlayer.OCX |
现在微软那边的SDK文档地址为
https://docs.microsoft.com/en-us/windows/win32/wmp/player-object
可以通过VS命令行执行
tlbimp C:\Windows\system32\msdxm.tlb /out:d:\temp\msdxm_out.dll
tlbimp C:\Windows\system32\wmp.dll /out:d:\temp\wmp_out.dll
来到处两个dll , 用ILSPY查看:
6.4的就这样完结了 , 而7的类型列表就超长
总的说来 , 6.4 的 API 更直接一些. 全部都扔进 MediaPlayerClass里了. 7的API非常多类型, 使用起来很复杂
如果不想导入这种类型的dll , 把C#当脚本用, 该如何?
使用这种代码:
string mp4file = System.IO.Path.Combine(whe.WebRootPath, "demo.mp4"); //Windows Media Player 6.4 (classic) //type lib name "MediaPlayer" //VS command : tlbimp C:\Windows\system32\msdxm.tlb /out:d:\temp\msdxm_out.dll Type type = Type.GetTypeFromProgID("MediaPlayer.MediaPlayer.1"); Console.WriteLine(type.GUID); // 22d6f312-b0f6-11d0-94ab-0080c74c7e95 System.Windows.Forms.Form form = new System.Windows.Forms.Form(); MyAxControl player = new MyAxControl(type); form.Controls.Add(player); form.MinimumSize = new System.Drawing.Size(400, 300); form.Size = new System.Drawing.Size(800, 600); form.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; form.Show(); type.InvokeMember("Open", System.Reflection.BindingFlags.InvokeMethod, null, player.GetOcx(), new object[] { mp4file });
string mp4file = System.IO.Path.Combine(whe.WebRootPath, "demo.mp4"); //Windows Media Player 7 or later //tlbimp C:\Windows\system32\wmp.dll /out:d:\temp\wmp_out.dll //type lib name "WMPLib" //https://docs.microsoft.com/en-us/windows/win32/wmp/player-object Type type = Type.GetTypeFromProgID("WMPlayer.OCX"); Console.WriteLine(type.GUID); // 6bf52a52-394a-11d3-b153-00c04f79faa6 System.Windows.Forms.Form form = new System.Windows.Forms.Form(); MyAxControl player = new MyAxControl(type); form.Controls.Add(player); form.MinimumSize = new System.Drawing.Size(400, 300); form.Size = new System.Drawing.Size(800, 600); form.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; form.Show(); type.InvokeMember("URL", System.Reflection.BindingFlags.SetProperty, null, player.GetOcx(), new object[] { mp4file });
公用代码:
class MyAxControl : System.Windows.Forms.AxHost { public MyAxControl(Type type) : base(type.GUID.ToString()) { this.Dock = System.Windows.Forms.DockStyle.Fill; } }
以上两个代码分别调用了6.4和7的 API . 已测试通过.
注意, MyAxControl 的 Dispose 函数并不会随着form关闭而Dispose掉. 需要手动Dispose