在C#中自定义Windows Media Player:实现毫秒级显示与新版外观
解决Visual Studio C#中Windows Media Player毫秒级时间获取与自定义显示问题
核心思路
默认的AxWindowsMediaPlayer控件UI固定,仅支持秒级显示,因此需要:
- 使用功能更完整的WMP COM库获取毫秒级时间数据
- 自定义UI组件替代默认播放栏,实现毫秒格式的时间显示
具体实现步骤
1. 添加Windows Media Player COM引用
不要依赖工具箱中的旧版AxWindowsMediaPlayer控件,直接添加COM引用以获得完整的WMP API访问权限:
- 右键项目 → 选择「添加」→「引用」
- 切换到「COM」标签页,找到并勾选「Windows Media Player」
- 确认后项目会自动生成
Interop.WMPLib.dll引用
2. 获取毫秒级时间数据
WMPLib中的WindowsMediaPlayer类提供了精确到毫秒的时间属性:
- 当前播放位置:
player.Controls.currentPosition(double类型,单位为秒,小数部分即为毫秒,例如123.456表示123秒456毫秒) - 媒体总时长:
player.currentMedia.duration(同样为double类型,带毫秒精度)
3. 实时更新时间显示
通过定时器定时读取时间数据并格式化显示,同时监听播放状态控制定时器启停:
完整代码示例
using WMPLib; using System; using System.Windows.Forms; namespace WMPMillisecondPlayer { public partial class MainForm : Form { private WindowsMediaPlayer _player; private Timer _timeUpdateTimer; public MainForm() { InitializeComponent(); InitializePlayer(); InitializeTimer(); } private void InitializePlayer() { _player = new WindowsMediaPlayer(); // 可通过OpenFileDialog让用户选择媒体文件 // _player.URL = "your-media-file-path.mp3"; _player.PlayStateChange += OnPlayStateChange; } private void InitializeTimer() { _timeUpdateTimer = new Timer { Interval = 100 // 每100毫秒更新一次,平衡精度与性能 }; _timeUpdateTimer.Tick += OnTimeUpdateTick; } private void OnPlayStateChange(int newState) { switch ((WMPPlayState)newState) { case WMPPlayState.wmppsPlaying: _timeUpdateTimer.Start(); break; case WMPPlayState.wmppsPaused: case WMPPlayState.wmppsStopped: case WMPPlayState.wmppsClosed: _timeUpdateTimer.Stop(); break; } } private void OnTimeUpdateTick(object sender, EventArgs e) { if (_player.currentMedia == null) return; double currentPos = _player.Controls.currentPosition; double totalDuration = _player.currentMedia.duration; // 格式化为 mm:ss.fff 格式(分:秒.毫秒) lblCurrentTime.Text = TimeSpan.FromSeconds(currentPos).ToString(@"mm\:ss\.fff"); lblTotalTime.Text = TimeSpan.FromSeconds(totalDuration).ToString(@"mm\:ss\.fff"); // 同步进度条(如果需要) progressBar.Maximum = (int)(totalDuration * 1000); progressBar.Value = Math.Min((int)(currentPos * 1000), progressBar.Maximum); } // 播放按钮点击事件 private void btnPlay_Click(object sender, EventArgs e) { _player.Controls.play(); } // 暂停按钮点击事件 private void btnPause_Click(object sender, EventArgs e) { _player.Controls.pause(); } // 选择媒体文件按钮事件 private void btnSelectFile_Click(object sender, EventArgs e) { using (var openFileDialog = new OpenFileDialog()) { openFileDialog.Filter = "媒体文件|*.mp3;*.wav;*.mp4;*.avi"; if (openFileDialog.ShowDialog() == DialogResult.OK) { _player.URL = openFileDialog.FileName; } } } } }
4. 自定义UI布局
- 隐藏默认的WMP控件(如果使用了的话),改用Label显示格式化后的时间、ProgressBar作为进度条、自定义按钮实现播放/暂停/停止控制
- 可以通过WinForms的布局工具(如TableLayoutPanel、FlowLayoutPanel)实现类似新版WMP的界面样式
注意事项
- 处理媒体未加载的情况:在读取
currentMedia前需判空,避免空引用异常 - 定时器间隔:100毫秒的更新频率足够满足毫秒级显示需求,过短的间隔会增加CPU占用
- 时间格式化:使用
TimeSpan.ToString(@"mm\:ss\.fff")时,需通过转义字符保留冒号和点的字面意义
内容的提问来源于stack exchange,提问作者Adil Ahmed
相关产品推荐
相关产品推荐

