C#基础(②音乐播发器MCI(Media Control Interface))
winmm.dll
是 Windows 操作系统中一个重要的动态链接库(DLL)文件,全称为 Windows Multimedia Library(Windows 多媒体库)。它包含了一系列用于处理多媒体相关功能的函数,是 Windows 系统实现音频、视频等多媒体操作的核心组件之一。
核心函数:mciSendString
[DllImport("winmm.dll")]
private static extern long mciSendString(string command, // 要执行的MCI命令(字符串)StringBuilder returnValue, // 存储返回结果的缓冲区int returnLength, // 缓冲区长度IntPtr winHandle // 窗口句柄(通常传IntPtr.Zero)
);
常用 MCI 命令及用法
1. 打开媒体文件
// 格式:open "文件路径" type 类型 alias 别名
// 作用:加载媒体文件并给它起一个别名(方便后续操作)
SendMCICommand("open \"C:\\music.mp3\" type mpegvideo alias MediaFile");
type mpegvideo:指定媒体类型(音频通常用 mpegvideo 或 waveaudio)
alias MediaFile:给文件起个别名 “MediaFile”,后续命令用别名操作,无需重复写路径
2. 播放 / 暂停 / 继续 / 停止
// 播放(从当前位置开始)
SendMCICommand("play MediaFile");// 暂停
SendMCICommand("pause MediaFile");// 继续(从暂停处恢复)
SendMCICommand("resume MediaFile");// 停止并回到开头
SendMCICommand("stop MediaFile");
SendMCICommand("seek MediaFile to start"); // 定位到开始位置
3. 调整音量
// 格式:setaudio 别名 volume to 音量值(范围0-1000)
SendMCICommand("setaudio MediaFile volume to 500"); // 50%音量
注意:MCI 音量范围是 0-1000,代码中通过 currentVolume * 10 转换(0-100 → 0-1000)
4. 获取媒体信息(需接收返回值)
// 获取当前播放位置(毫秒)
string position = GetMCIString("status MediaFile position");// 获取媒体总长度(毫秒)
string length = GetMCIString("status MediaFile length");// 获取播放状态(playing/paused/stopped)
string status = GetMCIString("status MediaFile mode");
5. 定位播放位置
// 格式:seek 别名 to 位置(毫秒)
SendMCICommand("seek MediaFile to 10000"); // 定位到10秒位置(10000毫秒)
6. 关闭媒体文件
// 关闭单个文件(通过别名)
SendMCICommand("close MediaFile");// 关闭所有打开的媒体文件
SendMCICommand("close all");
完整代码
Form1.Designer.cs
namespace music
{partial class Form1{/// <summary>/// 必需的设计器变量。/// </summary>private System.ComponentModel.IContainer components = null;/// <summary>/// 清理所有正在使用的资源。/// </summary>/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>protected override void Dispose(bool disposing){if (disposing && (components != null)){components.Dispose();}base.Dispose(disposing);}#region Windows 窗体设计器生成的代码/// <summary>/// 设计器支持所需的方法 - 不要修改/// 使用代码编辑器修改此方法的内容。/// </summary>private void InitializeComponent(){this.components = new System.ComponentModel.Container();this.btnPlay = new System.Windows.Forms.Button();this.btnPause = new System.Windows.Forms.Button();this.btnStop = new System.Windows.Forms.Button();this.btnAdd = new System.Windows.Forms.Button();this.btnPrev = new System.Windows.Forms.Button();this.btnNext = new System.Windows.Forms.Button();this.listBoxMusic = new System.Windows.Forms.ListBox();this.trackBarProgress = new System.Windows.Forms.TrackBar();this.trackBarVolume = new System.Windows.Forms.TrackBar();this.lblCurrentSong = new System.Windows.Forms.Label();this.lblTime = new System.Windows.Forms.Label();this.timerProgress = new System.Windows.Forms.Timer(this.components);this.SuspendLayout();// // btnPlay// this.btnPlay.Location = new System.Drawing.Point(106, 347);this.btnPlay.Name = "btnPlay";this.btnPlay.Size = new System.Drawing.Size(75, 23);this.btnPlay.TabIndex = 0;this.btnPlay.Text = "播放";this.btnPlay.UseVisualStyleBackColor = true;// // btnPause// this.btnPause.Location = new System.Drawing.Point(297, 347);this.btnPause.Name = "btnPause";this.btnPause.Size = new System.Drawing.Size(75, 23);this.btnPause.TabIndex = 1;this.btnPause.Text = "暂停";this.btnPause.UseVisualStyleBackColor = true;// // btnStop// this.btnStop.Location = new System.Drawing.Point(500, 381);this.btnStop.Name = "btnStop";this.btnStop.Size = new System.Drawing.Size(75, 23);this.btnStop.TabIndex = 2;this.btnStop.Text = "停止";this.btnStop.UseVisualStyleBackColor = true;this.btnStop.Click += new System.EventHandler(this.button3_Click);// // btnAdd// this.btnAdd.Location = new System.Drawing.Point(679, 380);this.btnAdd.Name = "btnAdd";this.btnAdd.Size = new System.Drawing.Size(75, 23);this.btnAdd.TabIndex = 3;this.btnAdd.Text = "添加音乐";this.btnAdd.UseVisualStyleBackColor = true;// // btnPrev// this.btnPrev.Location = new System.Drawing.Point(859, 380);this.btnPrev.Name = "btnPrev";this.btnPrev.Size = new System.Drawing.Size(75, 23);this.btnPrev.TabIndex = 4;this.btnPrev.Text = "上一首";this.btnPrev.UseVisualStyleBackColor = true;// // btnNext// this.btnNext.Location = new System.Drawing.Point(1051, 393);this.btnNext.Name = "btnNext";this.btnNext.Size = new System.Drawing.Size(75, 23);this.btnNext.TabIndex = 5;this.btnNext.Text = "下一首";this.btnNext.UseVisualStyleBackColor = true;// // listBoxMusic// this.listBoxMusic.FormattingEnabled = true;this.listBoxMusic.ItemHeight = 15;this.listBoxMusic.Location = new System.Drawing.Point(542, 115);this.listBoxMusic.Name = "listBoxMusic";this.listBoxMusic.Size = new System.Drawing.Size(510, 214);this.listBoxMusic.TabIndex = 6;// // trackBarProgress// this.trackBarProgress.Location = new System.Drawing.Point(223, 48);this.trackBarProgress.Name = "trackBarProgress";this.trackBarProgress.Size = new System.Drawing.Size(427, 56);this.trackBarProgress.TabIndex = 7;// // trackBarVolume// this.trackBarVolume.Location = new System.Drawing.Point(816, 48);this.trackBarVolume.Name = "trackBarVolume";this.trackBarVolume.Size = new System.Drawing.Size(276, 56);this.trackBarVolume.TabIndex = 8;// // lblCurrentSong// this.lblCurrentSong.AutoSize = true;this.lblCurrentSong.Location = new System.Drawing.Point(172, 199);this.lblCurrentSong.Name = "lblCurrentSong";this.lblCurrentSong.Size = new System.Drawing.Size(52, 15);this.lblCurrentSong.TabIndex = 9;this.lblCurrentSong.Text = "歌曲名";// // lblTime// this.lblTime.AutoSize = true;this.lblTime.Location = new System.Drawing.Point(278, 264);this.lblTime.Name = "lblTime";this.lblTime.Size = new System.Drawing.Size(67, 15);this.lblTime.TabIndex = 10;this.lblTime.Text = "播放时间";// // Form1// this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 15F);this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;this.ClientSize = new System.Drawing.Size(1274, 541);this.Controls.Add(this.lblTime);this.Controls.Add(this.lblCurrentSong);this.Controls.Add(this.trackBarVolume);this.Controls.Add(this.trackBarProgress);this.Controls.Add(this.listBoxMusic);this.Controls.Add(this.btnNext);this.Controls.Add(this.btnPrev);this.Controls.Add(this.btnAdd);this.Controls.Add(this.btnStop);this.Controls.Add(this.btnPause);this.Controls.Add(this.btnPlay);this.Name = "Form1";this.Text = "Form1";this.Load += new System.EventHandler(this.Form1_Load);((System.ComponentModel.ISupportInitialize)(this.trackBarProgress)).EndInit();((System.ComponentModel.ISupportInitialize)(this.trackBarVolume)).EndInit();this.ResumeLayout(false);this.PerformLayout();}#endregionprivate System.Windows.Forms.Button btnPlay;private System.Windows.Forms.Button btnPause;private System.Windows.Forms.Button btnStop;private System.Windows.Forms.Button btnAdd;private System.Windows.Forms.Button btnPrev;private System.Windows.Forms.Button btnNext;private System.Windows.Forms.ListBox listBoxMusic;private System.Windows.Forms.TrackBar trackBarProgress;private System.Windows.Forms.TrackBar trackBarVolume;private System.Windows.Forms.Label lblCurrentSong;private System.Windows.Forms.Label lblTime;private System.Windows.Forms.Timer timerProgress;}
}
Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;namespace music
{public partial class Form1 : Form{// MCI API 声明[DllImport("winmm.dll")]private static extern long mciSendString(string command, StringBuilder returnValue, int returnLength, IntPtr winHandle);private List<string> playlist;private int currentSongIndex = -1;private bool isDragging = false;private bool isPlaying = false;private bool isPaused = false;private int songLength = 0;private int currentVolume = 50;public Form1(){InitializeComponent();playlist = new List<string>();}private void Form1_Load(object sender, EventArgs e){// 初始化界面trackBarVolume.Maximum = 100;trackBarVolume.Minimum = 0;trackBarVolume.Value = 50;currentVolume = 50;trackBarProgress.Maximum = 1000;trackBarProgress.Minimum = 0;trackBarProgress.Value = 0;lblCurrentSong.Text = "未选择歌曲";lblTime.Text = "00:00 / 00:00";// 绑定事件btnPlay.Click += BtnPlay_Click;btnPause.Click += BtnPause_Click;btnStop.Click += BtnStop_Click;btnAdd.Click += BtnAdd_Click;btnPrev.Click += BtnPrev_Click;btnNext.Click += BtnNext_Click;listBoxMusic.SelectedIndexChanged += ListBoxMusic_SelectedIndexChanged;trackBarVolume.Scroll += TrackBarVolume_Scroll;trackBarProgress.MouseDown += TrackBarProgress_MouseDown;trackBarProgress.MouseUp += TrackBarProgress_MouseUp;trackBarProgress.Scroll += TrackBarProgress_Scroll;timerProgress.Interval = 1000;timerProgress.Tick += TimerProgress_Tick;timerProgress.Start();}// MCI 帮助方法private void SendMCICommand(string command){mciSendString(command, null, 0, IntPtr.Zero);}private string GetMCIString(string command){StringBuilder buffer = new StringBuilder(128);mciSendString(command, buffer, 128, IntPtr.Zero);return buffer.ToString();}private void LoadSong(string filePath){try{SendMCICommand("close all");SendMCICommand($"open \"{filePath}\" type mpegvideo alias MediaFile");// 获取歌曲长度string lengthStr = GetMCIString("status MediaFile length");if (int.TryParse(lengthStr, out songLength)){// MCI返回的时间单位是毫秒songLength = songLength / 1000; // 转换为秒}// 设置音量SendMCICommand($"setaudio MediaFile volume to {currentVolume * 10}");}catch (Exception ex){MessageBox.Show($"加载音乐文件失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);}}private void BtnPlay_Click(object sender, EventArgs e){if (currentSongIndex >= 0 && currentSongIndex < playlist.Count){if (isPaused){SendMCICommand("resume MediaFile");isPaused = false;isPlaying = true;}else if (!isPlaying){LoadSong(playlist[currentSongIndex]);SendMCICommand("play MediaFile");isPlaying = true;isPaused = false;UpdateCurrentSongDisplay();}}else if (playlist.Count > 0){currentSongIndex = 0;listBoxMusic.SelectedIndex = 0;LoadSong(playlist[currentSongIndex]);SendMCICommand("play MediaFile");isPlaying = true;isPaused = false;UpdateCurrentSongDisplay();}}private void BtnPause_Click(object sender, EventArgs e){if (isPlaying && !isPaused){SendMCICommand("pause MediaFile");isPaused = true;}}private void BtnStop_Click(object sender, EventArgs e){SendMCICommand("stop MediaFile");SendMCICommand("seek MediaFile to start");isPlaying = false;isPaused = false;trackBarProgress.Value = 0;lblTime.Text = "00:00 / 00:00";}private void BtnAdd_Click(object sender, EventArgs e){OpenFileDialog openFileDialog = new OpenFileDialog();openFileDialog.Filter = "音乐文件|*.mp3;*.wav;*.wma;*.flac;*.m4a|所有文件|*.*";openFileDialog.Multiselect = true;openFileDialog.Title = "选择音乐文件";if (openFileDialog.ShowDialog() == DialogResult.OK){foreach (string fileName in openFileDialog.FileNames){playlist.Add(fileName);listBoxMusic.Items.Add(Path.GetFileNameWithoutExtension(fileName));}}}private void BtnPrev_Click(object sender, EventArgs e){if (playlist.Count > 0){currentSongIndex--;if (currentSongIndex < 0)currentSongIndex = playlist.Count - 1;listBoxMusic.SelectedIndex = currentSongIndex;LoadSong(playlist[currentSongIndex]);SendMCICommand("play MediaFile");isPlaying = true;isPaused = false;UpdateCurrentSongDisplay();}}private void BtnNext_Click(object sender, EventArgs e){if (playlist.Count > 0){currentSongIndex++;if (currentSongIndex >= playlist.Count)currentSongIndex = 0;listBoxMusic.SelectedIndex = currentSongIndex;LoadSong(playlist[currentSongIndex]);SendMCICommand("play MediaFile");isPlaying = true;isPaused = false;UpdateCurrentSongDisplay();}}private void ListBoxMusic_SelectedIndexChanged(object sender, EventArgs e){if (listBoxMusic.SelectedIndex >= 0){currentSongIndex = listBoxMusic.SelectedIndex;UpdateCurrentSongDisplay();}}private void TrackBarVolume_Scroll(object sender, EventArgs e){currentVolume = trackBarVolume.Value;SendMCICommand($"setaudio MediaFile volume to {currentVolume * 10}");}private void TrackBarProgress_MouseDown(object sender, MouseEventArgs e){isDragging = true;}private void TrackBarProgress_MouseUp(object sender, MouseEventArgs e){isDragging = false;if (isPlaying && songLength > 0){int newPosition = (int)((double)trackBarProgress.Value / trackBarProgress.Maximum * songLength * 1000);SendMCICommand($"seek MediaFile to {newPosition}");if (!isPaused){SendMCICommand("play MediaFile");}}}private void TrackBarProgress_Scroll(object sender, EventArgs e){if (isDragging && songLength > 0){double newPosition = (double)trackBarProgress.Value / trackBarProgress.Maximum * songLength;UpdateTimeDisplay(newPosition, songLength);}}private int GetCurrentPosition(){string positionStr = GetMCIString("status MediaFile position");if (int.TryParse(positionStr, out int position)){return position / 1000; // 转换为秒}return 0;}private string GetPlayStatus(){return GetMCIString("status MediaFile mode");}private void TimerProgress_Tick(object sender, EventArgs e){if (isPlaying && !isDragging){string status = GetPlayStatus();// 检查是否还在播放if (status == "stopped" && isPlaying){// 歌曲播放完成,自动播放下一首if (playlist.Count > 1){BtnNext_Click(sender, e);return;}else{isPlaying = false;isPaused = false;trackBarProgress.Value = 0;lblTime.Text = "00:00 / 00:00";return;}}if (status == "playing" || status == "paused"){int currentPosition = GetCurrentPosition();if (songLength > 0){int progress = (int)((double)currentPosition / songLength * trackBarProgress.Maximum);trackBarProgress.Value = Math.Min(progress, trackBarProgress.Maximum);}UpdateTimeDisplay(currentPosition, songLength);}}}private void UpdateCurrentSongDisplay(){if (currentSongIndex >= 0 && currentSongIndex < playlist.Count){string fileName = Path.GetFileNameWithoutExtension(playlist[currentSongIndex]);lblCurrentSong.Text = fileName;}}private void UpdateTimeDisplay(double currentPosition, double duration){string currentTime = TimeSpan.FromSeconds(currentPosition).ToString(@"mm\:ss");string totalTime = TimeSpan.FromSeconds(duration).ToString(@"mm\:ss");lblTime.Text = $"{currentTime} / {totalTime}";}private void button3_Click(object sender, EventArgs e){BtnStop_Click(sender, e);}protected override void OnFormClosing(FormClosingEventArgs e){// 清理MCI资源SendMCICommand("close all");base.OnFormClosing(e);}}
}
123