使用MCI接口播放音乐

      在C#中播放音乐主要有三种方式:1、System.Media.SoundPlay;2、MCI接口;3、MediaPlayer控件。SoundPlay是专门用来播放声音的,即.wav文件,使用方法比较简单。MediaPlayer控件是系统自带的播放器,关于它的介绍已经很多了。

      今天我想为大家介绍的MCI接口,关于MCI接口的介绍,大家可以参考MSDN,这里我们只是介绍具体的用法。首先,我们需要定义一个枚举类型来描述播放器的状态。

  public enum PlayState : byte
    {
        Playing = 1,
        Puased = 2,
        Stopped = 3,
    }


      接下来,为了便于后面的继续,我们对MCI接口做了一个封装:

  class WAPI
    {
        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        public static extern int GetShortPathName(
        string lpszLongPath,
        string shortFile,
        int cchBuffer
        );
        [DllImport("winmm.dll", EntryPoint = "mciSendString", CharSet = CharSet.Auto)]
        public static extern int mciSendString(
        string lpstrCommand,
        string lpstrReturnString,
        int uReturnLength,
        int hwndCallback
        );
    }

      关于这两个API函数,大家可以在MSDN找到相关说明。接下来,我们来构建播放器的类:

 public class MPlayer
    {
        //定义歌曲地址
        private string Url = string.Empty;
        //定义歌曲结构的实例
        private Media m = new Media();
        //构造函数
        public MPlayer()
        {
            m.Position = 0;
            m.State = PlayState.Stopped;
            m.Volume = 0;
            m.Speed = 1000;
            m.Duration = 0;
        }


        //FileName属性
        public string FileName
        {
            set
            {
                Url = string.Empty;
                string Name = value;
                m.Position = 0;
                Url = Url.PadLeft(260, ' ');
                WAPI.GetShortPathName(Name, Url, Url.Length);
                Url = GetFileUrl(Url);
                InitDevice();
            }
        }

        //设备初始化
        private void InitDevice()
        {
            string DeviceID = GetDeviceID(Url);//返回类型 
            WAPI.mciSendString("Close All", null, 0, 0);//关闭所有设备
            if (DeviceID != "RealPlay")
            {
                string MciCommand = String.Format("Open {0} type {1} Alias Media", Url, DeviceID);
                WAPI.mciSendString(MciCommand, null, 0, 0);//初始化设备
                m.State = PlayState.Stopped;
            }
        }

        //获取设备ID
        private string GetDeviceID(string Url)
        {
            string Result = string.Empty;
            Url = Url.ToUpper().Trim();
            if (Url.Length < 3)
            {
                return Url;
            }
            switch (Url.Substring(Url.Length - 3))
            {
                case "MID":
                    Result = "Sequencer";
                    break;
                case "RMI":
                    Result = "Sequencer";
                    break;
                case "IDI":
                    Result = "Sequencer";
                    break;
                case "WAV":
                    Result = "Waveaudio";
                    break;
                case "ASX":
                    Result = "MPEGVideo2";
                    break;
                case "IVF":
                    Result = "MPEGVideo2";
                    break;
                case "LSF":
                    Result = "MPEGVideo2";
                    break;
                case "LSX":
                    Result = "MPEGVideo2";
                    break;
                case "P2V":
                    Result = "MPEGVideo2";
                    break;
                case "WAX":
                    Result = "MPEGVideo2";
                    break;
                case "WVX":
                    Result = "MPEGVideo2";
                    break;
                case ".WM":
                    Result = "MPEGVideo2";
                    break;
                case "WMX":
                    Result = "MPEGVideo2";
                    break;
                case "WMP":
                    Result = "MPEGVideo2";
                    break;
                case ".RM":
                    Result = "RealPlay";
                    break;
                case "RAM":
                    Result = "RealPlay";
                    break;
                case ".RA":
                    Result = "RealPlay";
                    break;
                case "MVB":
                    Result = "RealPlay";
                    break;
                default:
                    Result = "MPEGVideo";
                    break;
            }
            return Result;
        }

        //得到当前路径
        private string GetFileUrl(string FileName)
        {
            FileName = FileName.Trim();//去掉空格
            if (FileName.Length > 1)//判断是否为空(name包含'\0')
            {
                FileName = FileName.Substring(0, FileName.Length - 1);//去掉'\0'
            }
            return FileName;
        }

        //判断初始化后设备是否准备好接受命令
        public bool IsReady()
        {
            string Ready = new string(' ', 10);
            WAPI.mciSendString("Status Media Ready", Ready, Ready.Length, 0);
            Ready = Ready.Trim();
            if (Ready.Contains("true"))
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        //播放 
        public void Play()
        {
            if (m.State != PlayState.Playing)
            {
                WAPI.mciSendString("Play Media", null, 0, 0);
                m.State = PlayState.Playing;
            }
        }

        //停止 
        public void Stop()
        {
            if (m.State != PlayState.Stopped)
            {
                WAPI.mciSendString("Stop Media", null, 0, 0);
                m.State = PlayState.Stopped;
            }
        }

        //暂停
        public void Puase()
        {
            if (m.State == PlayState.Playing)
            {
                WAPI.mciSendString("Pause Media", null, 0, 0);
                m.State = PlayState.Puased;
            }
        }

        //恢复播放
        public void Resume()
        {
            int RefInt = WAPI.mciSendString("Resume Media", null, 0, 0);
            m.State = PlayState.Playing;
        }

        //属性Duration
        public int Duration
        {
            get
            {
                WAPI.mciSendString("Set Media Time Format Milliseconds", null, 0, 0);//设置时间格式单位为毫秒
                m.Duration = GetDuration();
                return m.Duration;
            }
        }

        private int GetDuration()
        {
            string Length = string.Empty;
            Length = Length.PadLeft(20, ' ');//设置定长字符串long是19位,足够表示时间了
            WAPI.mciSendString("Status Media Length", Length, Length.Length, 0);
            Length = Length.Trim();
            if (Length.Length > 1)
            {
                Length = Length.Substring(0, Length.Length - 1);
                return (int)(long.Parse(Length) / 1000);
            }
            return 0;
        }

        //属性State
        public PlayState State
        {
            get
            {
                return m.State;
            }
        }

        public string PositionString
        {
            get
            {
                string mm = (this.Position / 60).ToString("00");
                string ss = (this.Position % 60).ToString("00");
                return mm + ":" + ss;
            }
        }

        public string DurationString
        {
            get
            {
                string mm = (this.Duration / 60).ToString("00");
                string ss = (this.Duration % 60).ToString("00");
                return mm + ":" + ss;
            }
        }
        //设置获取当前时间 
        public int Position
        {
            get
            {
                string Position = string.Empty;
                Position = Position.PadLeft(20, ' ');//long表示范围是19位
                WAPI.mciSendString("Status Media Position", Position, Position.Length, 0);
                Position = Position.Trim();
                if (Position.Length > 1)
                {
                    m.Position = (int)(long.Parse(Position) / 1000);//以秒返回
                }
                return m.Position;
            }
            set
            {
                string Command = String.Format("Seek Media to {0}", value*1000);
                WAPI.mciSendString(Command, null, 0, 0);//使播放停止
                m.State = PlayState.Stopped;
                m.Position = value*1000;
                Play();
            }
        }

        //设置静音
        public void VolumeOff(bool IsOff)
        {
            string SetOnOff = string.Empty;
            if (IsOff)
                SetOnOff = "Off";
            else
                SetOnOff = "On";
            string MciCommand = String.Format("Set Audio Media {0}", SetOnOff);
            WAPI.mciSendString(MciCommand, null, 0, 0);
        }

        //Volume
        public int Volume
        {
            get
            {
                return m.Volume;
            }
            set
            {
                if (value >= 0)
                {
                    m.Volume = value;
                    string MciCommand = String.Format("Set Audio Media Volume To {0}", m.Volume);
                    WAPI.mciSendString(MciCommand, null, 0, 0);
                }
            }
        }
        //定义歌曲结构
        private struct Media
        {
            public int Position;
            public PlayState State;
            public int Volume;
            public int Speed;
            public int Duration;
        }
    }

         关于这个类,我想说两点,第一:在设置Position属性即歌曲的进度时,我们对其赋值为value*1000.为什么要乘1000呢?因为在获取Position时为们做了单位转换,除了1000,所以这里要乘以1000,否则程序将不起作用。第二:使用MCI播放的时候,经常会发出嘶嘶的杂音,我的解决办法是,在播放前设置歌曲进度为1秒,即歌曲并不从头开始播放,这样就可以跳过去了,呵呵。好吧,就这样了,睡觉啦!
 

 

   

你可能感兴趣的:(音乐)