利用DirectShow开发C#版的MP3播放器(二)

     继上一次利用DirectShow编写了一个C#版的简单MP3播放器之后,这两天利用空余时间对其作了初步的完善,主要工作如下:
    1、对原有的代码进行拆分,主要拆分成五个类,包括一个Form类FrmPlayer、一个播放核心类MediaPlayCore、一个媒体文件信息类MediaFileInfo、一个基础类Utils(包含各种公共的静态方法)、一个由多个枚举类型组成的枚举类。
    2、增加了以下功能:添加文件/文件夹、删除所选/全部、播放模式(包括单曲播放、单曲循环、顺序播放、循环播放和随机播放)。
    3、修改了播放列表的显示功能,可以显示序号、标题、时长和大小。

    修改完善后的界面如下图所示:

    根据修改后的功能,各个部分的主要代码如下:
1、FrmPlayer.cs
// *************************************************************** //
// Project Name   :  MyMp3Player
// Version        :  1.0.1
// Author Name    :  Simon Huang (http://blog.csdn.net/huangxinfeng)
// Creation Date  :  2010-02-21
// Modified Date  : 
// Modified Disc  :
// Statement      :  Some code of this project from open source.
// *************************************************************** //

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using System.IO;


namespace MyMp3Player
{
    public partial class FrmPlayer : Form
    {
        private const int WM_APP = 0x8000;
        private const int WM_GRAPHNOTIFY = WM_APP + 1;
        private const int EC_COMPLETE = 0x01;

        private MediaPlayCore MediaPlay;

        private PlayMode m_currentPlayMode = PlayMode.Order; // 播放模式

        private string m_strFilePath;  // 文件路径
        private bool m_blnAutoMove = true; // 播放完成后自动移动到下一曲(单曲播放/单曲循环模式除外)
        private bool m_blnNewPlay = true;  // 开始一次全新的播放

        private int m_incrementId = 0;
        private int m_lastPlayIndex = -1;
        private int m_currentPlayIndex = -1;

        private Dictionary<int, MediaFileInfo> m_mediaFileTable;

        public FrmPlayer()
        {
            InitializeComponent();
        }

        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new FrmPlayer());
        }

        #region protected method, override WndProc method
        /// <summary>
        /// 重写WndProc
        /// </summary>
        /// <param name="m"></param>
        protected override void WndProc(ref Message m)
        {
            if (m.Msg == WM_GRAPHNOTIFY)
            {
                int lEventCode;
                int lParam1, lParam2;

                while (true)
                {
                    try
                    {
                        MediaPlay.MediaEventEx.GetEvent(out lEventCode, out lParam1, out lParam2, 0);
                        MediaPlay.MediaEventEx.FreeEventParams(lEventCode, lParam1, lParam2);

                        if (lEventCode == EC_COMPLETE)
                        {
                            m_blnAutoMove = true;
                            this.Next(); // 自动切换到下一曲
                        }
                    }
                    catch (Exception)
                    {
                        break;
                    }
                }
            }

            base.WndProc(ref m);
        }
        #endregion

        private void FrmPlayer_Load(object sender, EventArgs e)
        {
            MediaPlay = new MediaPlayCore();
            m_mediaFileTable = new Dictionary<int, MediaFileInfo>();

            this.UpdatePlayTime();
            this.UpdatePlayList();
            this.UpdatePlayStatus();
        }

        private void FrmPlayer_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (MediaPlay != null)
            {
                MediaPlay.CleanUp();
            }
        }

        #region private methods
        /// <summary>
        /// 播放
        /// </summary>
        private void Play()
        {
            if (m_blnNewPlay)  // 开始一次全新的播放
            {
                this.FirstUpdateMediaPlayList(m_lastPlayIndex);

                MediaFileInfo mediaFileInfo = null;
                lock (m_mediaFileTable)
                {
                    if (m_mediaFileTable.ContainsKey(m_currentPlayIndex))
                    {
                        mediaFileInfo = (MediaFileInfo)m_mediaFileTable[m_currentPlayIndex];
                    }
                }
                if (mediaFileInfo != null)
                {
                    m_strFilePath = mediaFileInfo.Path;
                    lblTitle.Text = mediaFileInfo.Title;

                    MediaPlay.CleanUp();
                    MediaPlay.InitMediaPlayer(m_strFilePath);
                    MediaPlay.MediaEventEx.SetNotifyWindow((int)this.Handle, WM_GRAPHNOTIFY, 0);
                   
                    lblTotalTime.Text = Utils.ConvertTimeToString(MediaPlay.Duration);
                    this.SecondUpdateMediaPlayList(m_currentPlayIndex);

                    m_lastPlayIndex = m_currentPlayIndex;
                }
            }

            MediaPlay.Play();

            this.UpdatePlayTime();
            this.UpdatePlayStatus();
        }

        /// <summary>
        /// 暂停
        /// </summary>
        private void Pause()
        {
            MediaPlay.Pause();
            this.UpdatePlayTime();
            this.UpdatePlayStatus();
        }

        /// <summary>
        /// 停止
        /// </summary>
        private void Stop()
        {
            MediaPlay.Stop();
            this.UpdatePlayStatus();
        }

        #region play previous media file
        /// <summary>
        /// 上一曲
        /// </summary>
        private void Previous()
        {
            int currentIndex = 0;

            switch (m_currentPlayMode)
            {
                case PlayMode.Single:  // 单曲播放
                case PlayMode.SingleCycle:  // 单曲循环
                case PlayMode.Order:  // 顺序播放
                    if (m_currentPlayIndex == 0)
                    {
                        currentIndex = 0;  // 已移到最前面
                    }
                    else
                    {
                        currentIndex = this.FindListViewItemIndex(m_lastPlayIndex);
                        currentIndex -= 1;
                    }
                    break;

                case PlayMode.Cycle:  // 循环播放
                    if (m_currentPlayIndex == 0)
                    {
                        currentIndex = lsvPlayList.Items.Count - 1;
                    }
                    else
                    {
                        currentIndex = this.FindListViewItemIndex(m_lastPlayIndex);
                        currentIndex -= 1;
                    }
                    break;

                case PlayMode.Random:  // 随机播放
                    Random random = new Random();
                    currentIndex = random.Next(lsvPlayList.Items.Count);
                    break;

                default:  // 默认顺序播放
                    if (m_currentPlayIndex == 0)
                    {
                        currentIndex = 0;  // 已移到最前面
                    }
                    else
                    {
                        currentIndex = this.FindListViewItemIndex(m_lastPlayIndex);
                        currentIndex -= 1;
                    }
                    break;
            }

            this.CancelItemSelected();

            m_currentPlayIndex = currentIndex;
            m_blnNewPlay = true;
            this.Play();
        }
        #endregion

        #region play next media file
        /// <summary>
        /// 下一曲
        /// </summary>
        private void Next()
        {
            int currentIndex = 0;

            switch (m_currentPlayMode)
            {
                case PlayMode.Single:  // 单曲播放
                    if (m_blnAutoMove)
                    {
                        this.Stop();
                        currentIndex = -1;
                    }
                    else
                    {
                        if (m_currentPlayIndex == lsvPlayList.Items.Count - 1)
                        {
                            currentIndex = lsvPlayList.Items.Count - 1; // 已移到最后面
                        }
                        else
                        {
                            currentIndex = this.FindListViewItemIndex(m_lastPlayIndex);
                            currentIndex += 1;
                        }
                    }
                    break;

                case PlayMode.SingleCycle:  // 单曲循环
                    if (m_blnAutoMove)
                    {
                        currentIndex = m_lastPlayIndex;
                    }
                    else
                    {
                        if (m_currentPlayIndex == lsvPlayList.Items.Count - 1)
                        {
                            currentIndex = lsvPlayList.Items.Count - 1; // 已移到最后面
                        }
                        else
                        {
                            currentIndex = this.FindListViewItemIndex(m_lastPlayIndex);
                            currentIndex += 1;
                        }
                    }
                    break;

                case PlayMode.Order:  // 顺序播放
                    if (m_currentPlayIndex == lsvPlayList.Items.Count - 1)
                    {
                        currentIndex = lsvPlayList.Items.Count - 1; // 已移到最后面
                    }
                    else
                    {
                        currentIndex = this.FindListViewItemIndex(m_lastPlayIndex);
                        currentIndex += 1;
                    }
                    break;

                case PlayMode.Cycle:  // 循环播放
                    if (m_currentPlayIndex == lsvPlayList.Items.Count - 1)
                    {
                        currentIndex = 0;
                    }
                    else
                    {
                        currentIndex = this.FindListViewItemIndex(m_lastPlayIndex);
                        currentIndex += 1;
                    }
                    break;

                case PlayMode.Random:  // 随机播放
                    Random random = new Random();
                    currentIndex = random.Next(lsvPlayList.Items.Count);
                    break;

                default:  // 默认顺序播放
                    if (m_currentPlayIndex == lsvPlayList.Items.Count - 1)
                    {
                        currentIndex = lsvPlayList.Items.Count - 1; // 已移到最后面
                    }
                    else
                    {
                        currentIndex = this.FindListViewItemIndex(m_lastPlayIndex);
                        currentIndex += 1;
                    }
                    break;
            }

            this.CancelItemSelected();

            if (currentIndex != -1)
            {
                m_currentPlayIndex = currentIndex;
                m_blnNewPlay = true;
                this.Play();
            }      
        }
        #endregion

        /// <summary>
        /// 打开文件
        /// </summary>
        private void AddOpenFiles()
        {
            OpenFileDialog openFileDlg = new OpenFileDialog();

            openFileDlg.Filter = "MP3文件(*.mp3)|*.mp3";
            openFileDlg.Multiselect = true;

            if (DialogResult.OK == openFileDlg.ShowDialog())
            {
                string[] fileNames = openFileDlg.FileNames;

                if (fileNames != null)
                {
                    this.InitFileInfoAndPlay(fileNames);
                }
            }
        }

        /// <summary>
        /// 打开文件夹
        /// </summary>
        private void AddOpenFolder()
        {
            FolderBrowserDialog folderBrowserDlg = new FolderBrowserDialog();
            folderBrowserDlg.Description = "请选择一个文件夹:";
            folderBrowserDlg.ShowNewFolderButton = false;

            if (DialogResult.OK == folderBrowserDlg.ShowDialog())
            {
                string folderName = folderBrowserDlg.SelectedPath;

                string[] fileNames = Directory.GetFiles(folderName, "*.mp3");

                if (fileNames != null)
                {
                    this.InitFileInfoAndPlay(fileNames);
                }
            }
        }

        /// <summary>
        /// 删除所选文件
        /// </summary>
        private void DeleteSelected()
        {
            if (lsvPlayList.SelectedItems.Count == 0)
            {
                MessageBox.Show("请选择要删除的文件!", "信息提示", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
            else
            {
                this.RemoveItemsFormMediaPlayList();
            }
        }

        /// <summary>
        /// 删除所有文件
        /// </summary>
        private void DeleteAll()
        {
            if (m_mediaFileTable != null)
            {
                m_mediaFileTable.Clear();
            }

            if (lsvPlayList.Items.Count > 0)
            {
                lsvPlayList.Items.Clear();
            }

            m_incrementId = 0;
            m_lastPlayIndex = -1;
            m_currentPlayIndex = -1;
        }

        /// <summary>
        /// 获取文件信息并添加到播放列表,然后开始播放
        /// </summary>
        /// <param name="fileNames"></param>
        private void InitFileInfoAndPlay(string[] fileNames)
        {
            foreach (string fileName in fileNames)
            {
                MediaFileInfo mediaFileInfo = new MediaFileInfo();

                FileInfo fi = new FileInfo(fileName);

                mediaFileInfo.ID = m_incrementId;
                mediaFileInfo.Title = Utils.GetFileName(fi.Name);
                mediaFileInfo.Length = Utils.ConvertTimeToString(MediaPlay.GetDuration(fileName));
                mediaFileInfo.Size = Utils.GetSizeInfo(fi.Length);
                mediaFileInfo.Path = fileName;

                m_mediaFileTable.Add(m_incrementId, mediaFileInfo);

                this.AddToMediaPlayList(mediaFileInfo);

                m_incrementId++;
            }

            if (m_currentPlayIndex == -1) // 添加前播放列表为空
            {
                // 选中第一个文件并进行播放
                lsvPlayList.Select();
                lsvPlayList.Items[0].Selected = true;
                m_lastPlayIndex = m_currentPlayIndex = 0;
                this.Play();
            }

            this.UpdatePlayList();
        }

        /// <summary>
        /// 添加文件到播放列表
        /// </summary>
        /// <param name="fileInfo"></param>
        private void AddToMediaPlayList(MediaFileInfo fileInfo)
        {
            lsvPlayList.BeginUpdate();

            ListViewItem lvi;
            lvi = new ListViewItem((fileInfo.ID +1).ToString());
            lvi.SubItems.Add(fileInfo.Title);
            lvi.SubItems.Add(fileInfo.Length);
            lvi.SubItems.Add(fileInfo.Size);

            lsvPlayList.Items.Add(lvi);

            lsvPlayList.EndUpdate();
        }

        /// <summary>
        /// 第一次更新播放列表
        /// </summary>
        /// <param name="id"></param>
        private void FirstUpdateMediaPlayList(int id)
        {
            ListViewItem lvi = lsvPlayList.FindItemWithText((id + 1).ToString());
            if (lvi != null)
            {
                lvi.ForeColor = Color.Black;
            }
        }

        /// <summary>
        /// 第二次更新播放列表
        /// </summary>
        /// <param name="id"></param>
        private void SecondUpdateMediaPlayList(int id)
        {
            ListViewItem lvi = lsvPlayList.FindItemWithText((id + 1).ToString());
            if (lvi != null)
            {
                lvi.ForeColor = Color.Green;
            }
        }

        /// <summary>
        /// 取消已选择项的状态
        /// </summary>
        private void CancelItemSelected()
        {
            foreach (ListViewItem lvi in lsvPlayList.SelectedItems)
            {
                lvi.Selected = false;
            }
        }

        /// <summary>
        /// 从播放列表移除选中的文件
        /// </summary>
        private void RemoveItemsFormMediaPlayList()
        {
            foreach (ListViewItem lvi in lsvPlayList.SelectedItems)
            {
                int playId = Utils.StringToInteger(lvi.Text) - 1;

                lock (m_mediaFileTable)
                {
                    if (m_mediaFileTable.ContainsKey(playId))
                    {
                        m_mediaFileTable.Remove(playId);
                    }
                }

                lvi.Remove();
            }
        }

        //private void UpdatePlayIndex(int playId)
        //{
        //    MediaFileInfo mediaFileInfo = null;
        //    lock (m_mediaFileTable)
        //    {
        //        foreach (int id in m_mediaFileTable.Keys)
        //        {
        //            if (id > playId)
        //            {
        //                if (m_mediaFileTable.ContainsKey(id))
        //                {
        //                    mediaFileInfo = (MediaFileInfo)m_mediaFileTable[id];
        //                }

        //                if (mediaFileInfo != null)
        //                {
        //                    mediaFileInfo.ID = id - 1;
        //                }
        //            }
        //        }
        //    }
        //}

        /// <summary>
        /// 查找并返回指定项的索引
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        private int FindListViewItemIndex(int id)
        {
            ListViewItem lvi = lsvPlayList.FindItemWithText((id + 1).ToString());
            if (lvi != null)
            {
                return lvi.Index;
            }
            else
            {
                return 0;
            }
        }
        #endregion


        #region update control status
        /// <summary>
        /// 更新播放时间及播放进度
        /// </summary>
        private void UpdatePlayTime()
        {
            if (MediaPlay != null)
            {
                lblCurrentTime.Text = Utils.ConvertTimeToString(MediaPlay.CurrentPosition);

                trackBarPlay.Value = (int)(100 * (MediaPlay.CurrentPosition / MediaPlay.Duration));
            }
            else
            {
                lblTotalTime.Text = "00:00";
                lblCurrentTime.Text = "00:00";
            }
        }

        /// <summary>
        /// 根据播放列表状态更新相应按钮状态
        /// </summary>
        private void UpdatePlayList()
        {
            if (lsvPlayList.Items.Count > 0)
            {
                picPrevious.Enabled = true;
                picNext.Enabled = true;
                picPrevious.Image = global::MyMp3Player.Properties.Resources.previous_normal;
                picNext.Image = global::MyMp3Player.Properties.Resources.next_normal;
            }
            else
            {
                picPrevious.Enabled = false;
                picNext.Enabled = false;
                picPrevious.Image = global::MyMp3Player.Properties.Resources.previous_disabled;
                picNext.Image = global::MyMp3Player.Properties.Resources.next_disabled;
            }
        }

        /// <summary>
        /// 更新播放按钮状态
        /// </summary>
        private void UpdatePlayStatus()
        {
            switch (MediaPlay.CurrentStatus)
            {
                case MediaStatus.None:
                    picPlayPause.Enabled = false;
                    picStop.Enabled = false;
                    picPlayPause.Image = global::MyMp3Player.Properties.Resources.play_disabled;
                    picStop.Image = global::MyMp3Player.Properties.Resources.stop_disabled;
                    lblCurrentTime.Text = "00:00";
                    lblTotalTime.Text = "00:00";
                    trackBarPlay.Value = 0;
                    break;

                case MediaStatus.Paused:
                    picPlayPause.Enabled = true;
                    picStop.Enabled = true;
                    picPlayPause.Image = global::MyMp3Player.Properties.Resources.play_normal;
                    picStop.Image = global::MyMp3Player.Properties.Resources.stop_normal;
                    break;

                case MediaStatus.Running:
                    picPlayPause.Enabled = true;
                    picStop.Enabled = true;
                    picPlayPause.Image = global::MyMp3Player.Properties.Resources.pause_normal;
                    picStop.Image = global::MyMp3Player.Properties.Resources.stop_normal;
                    break;

                case MediaStatus.Stopped:
                    picPlayPause.Enabled = true;
                    picStop.Enabled = false;
                    picPlayPause.Image = global::MyMp3Player.Properties.Resources.play_normal;
                    picStop.Image = global::MyMp3Player.Properties.Resources.stop_disabled;
                    lblCurrentTime.Text = "00:00";
                    lblTotalTime.Text = "00:00";
                    trackBarPlay.Value = 0;
                    break;
            }
        }

        /// <summary>
        /// 更新播放模式的菜单选中状态
        /// </summary>
        private void UpdatePlayModeMenuStatus()
        {
            switch (m_currentPlayMode)
            {
                case PlayMode.Single:
                    menuModeSingle.Checked = true;
                    menuModeSingleCycle.Checked = false;
                    menuModeOrder.Checked = false;
                    menuModeCycle.Checked = false;
                    menuModeRandom.Checked = false;
                    break;

                case PlayMode.SingleCycle:
                    menuModeSingle.Checked = false;
                    menuModeSingleCycle.Checked = true;
                    menuModeOrder.Checked = false;
                    menuModeCycle.Checked = false;
                    menuModeRandom.Checked = false;
                    break;

                case PlayMode.Order:
                    menuModeSingle.Checked = false;
                    menuModeSingleCycle.Checked = false;
                    menuModeOrder.Checked = true;
                    menuModeCycle.Checked = false;
                    menuModeRandom.Checked = false;
                    break;

                case PlayMode.Cycle:
                    menuModeSingle.Checked = false;
                    menuModeSingleCycle.Checked = false;
                    menuModeOrder.Checked = false;
                    menuModeCycle.Checked = true;
                    menuModeRandom.Checked = false;
                    break;

                case PlayMode.Random:
                    menuModeSingle.Checked = false;
                    menuModeSingleCycle.Checked = false;
                    menuModeOrder.Checked = false;
                    menuModeCycle.Checked = false;
                    menuModeRandom.Checked = true;
                    break;

                default:
                    menuModeSingle.Checked = true;
                    menuModeSingleCycle.Checked = false;
                    menuModeOrder.Checked = false;
                    menuModeCycle.Checked = false;
                    menuModeRandom.Checked = false;
                    break;
            }
        }

        #endregion

        /// <summary>
        /// 定时器
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void timer1_Tick(object sender, EventArgs e)
        {
            if (MediaPlay.CurrentStatus == MediaStatus.Running)
            {
                this.UpdatePlayTime();
            }
        }

        /// <summary>
        /// 播放进度条控制
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void trackBarPlay_Scroll(object sender, EventArgs e)
        {
            if (MediaPlay.CurrentStatus != MediaStatus.None)
            {
                MediaPlay.CurrentPosition = MediaPlay.Duration * trackBarPlay.Value / 100;
            }
        }

        #region play control click events
        private void picPlayPause_Click(object sender, EventArgs e)
        {
            if (MediaPlay.CurrentStatus == MediaStatus.Running)
            {
                this.Pause();
                picPlayPause.Image = global::MyMp3Player.Properties.Resources.pause_normal;
            }
            else
            {
                m_blnNewPlay = false;
                this.Play();
                picPlayPause.Image = global::MyMp3Player.Properties.Resources.play_normal;
            }
        }

        private void picPlayPause_MouseMove(object sender, MouseEventArgs e)
        {
            if (MediaPlay.CurrentStatus == MediaStatus.Running)
            {
                picPlayPause.Image = global::MyMp3Player.Properties.Resources.pause_over;
            }
            else
            {
                picPlayPause.Image = global::MyMp3Player.Properties.Resources.play_over;
            }
        }

        private void picPlayPause_MouseLeave(object sender, EventArgs e)
        {
            if (MediaPlay.CurrentStatus == MediaStatus.Running)
            {
                picPlayPause.Image = global::MyMp3Player.Properties.Resources.pause_normal;
            }
            else
            {
                picPlayPause.Image = global::MyMp3Player.Properties.Resources.play_normal;
            }
        }

        private void picStop_Click(object sender, EventArgs e)
        {
            this.Stop();
        }

        private void picStop_MouseMove(object sender, MouseEventArgs e)
        {
            picStop.Image = global::MyMp3Player.Properties.Resources.stop_over;
        }

        private void picStop_MouseLeave(object sender, EventArgs e)
        {
            picStop.Image = global::MyMp3Player.Properties.Resources.stop_normal;
        }

        private void picPrevious_Click(object sender, EventArgs e)
        {
            this.Previous();
        }

        private void picPrevious_MouseMove(object sender, MouseEventArgs e)
        {
            picPrevious.Image = global::MyMp3Player.Properties.Resources.previous_over;
        }

        private void picPrevious_MouseLeave(object sender, EventArgs e)
        {
            picPrevious.Image = global::MyMp3Player.Properties.Resources.previous_normal;
        }

        private void picNext_Click(object sender, EventArgs e)
        {
            this.Next();
        }

        private void picNext_MouseMove(object sender, MouseEventArgs e)
        {
            picNext.Image = global::MyMp3Player.Properties.Resources.next_over;
        }

        private void picNext_MouseLeave(object sender, EventArgs e)
        {
            picNext.Image = global::MyMp3Player.Properties.Resources.next_normal;
        }
        #endregion

        #region add file/folder click events
        private void menuAddFile_Click(object sender, EventArgs e)
        {
            this.AddOpenFiles();
        }

        private void menuAddFolder_Click(object sender, EventArgs e)
        {
            this.AddOpenFolder();
        }
        #endregion

        #region delete file/files click events
        private void menuDeleteSelected_Click(object sender, EventArgs e)
        {
            this.DeleteSelected();
        }

        private void menuDeleteAll_Click(object sender, EventArgs e)
        {
            this.DeleteAll();
        }
        #endregion

        #region play mode click events
        private void menuModeSingle_Click(object sender, EventArgs e)
        {
            // 更新播放模式的菜单选择状态
            m_currentPlayMode = PlayMode.Single;
            this.UpdatePlayModeMenuStatus(); 
        }

        private void menuModeSingleCycle_Click(object sender, EventArgs e)
        {
            // 更新播放模式的菜单选择状态
            m_currentPlayMode = PlayMode.SingleCycle;
            this.UpdatePlayModeMenuStatus();
        }

        private void menuModeOrder_Click(object sender, EventArgs e)
        {
            // 更新播放模式的菜单选择状态
            m_currentPlayMode = PlayMode.Order;
            this.UpdatePlayModeMenuStatus();
        }

        private void menuModeCycle_Click(object sender, EventArgs e)
        {
            // 更新播放模式的菜单选择状态
            m_currentPlayMode = PlayMode.Cycle;
            this.UpdatePlayModeMenuStatus();
        }

        private void menuModeRandom_Click(object sender, EventArgs e)
        {
            // 更新播放模式的菜单选择状态
            m_currentPlayMode = PlayMode.Random;
            this.UpdatePlayModeMenuStatus();
        }
        #endregion

        /// <summary>
        /// 双击选中文件并播放
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void lsvPlayList_DoubleClick(object sender, EventArgs e)
        {
            if (lsvPlayList.Items.Count > 0)
            {
                m_blnNewPlay = true;
                m_currentPlayIndex = Utils.StringToInteger(lsvPlayList.SelectedItems[0].SubItems[0].Text) - 1;
                this.Play();
            }
        }
    }
}

 

2、MediaPlayCore.CS
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using QuartzTypeLib;

namespace MyMp3Player
{
    class MediaPlayCore
    {
        #region member fields

        private FilgraphManager m_objFilterGraph = null;
        private IBasicAudio m_objBasicAudio = null;
        private IMediaEvent m_objMediaEvent = null;
        private IMediaEventEx m_objMediaEventEx = null;
        private IMediaPosition m_objMediaPosition = null;
        private IMediaControl m_objMediaControl = null;

        private MediaStatus m_currentStatus = MediaStatus.None;

        #endregion

        #region public properties

        public IMediaEventEx MediaEventEx
        {
            get { return m_objMediaEventEx; }
        }

        public MediaStatus CurrentStatus
        {
            get { return m_currentStatus; }
            set { m_currentStatus = value; }
        }

        public double Duration
        {
            get
            {
                if (m_objMediaPosition != null)
                {
                    return m_objMediaPosition.Duration;
                }
                else
                {
                    return 0.1;
                }
            }
        }

        public double CurrentPosition
        {
            get
            {
                if (m_objMediaPosition != null)
                {
                    return m_objMediaPosition.CurrentPosition;
                }
                else
                {
                    return 0.0;
                }
            }

            set
            {
                if (m_objMediaPosition != null)
                {
                    m_objMediaPosition.CurrentPosition = value;
                }
            }
        }

        #endregion

        #region public methods
        /// <summary>
        /// 初始化播放
        /// </summary>
        /// <param name="fileName">文件名称(全路径)</param>
        public void InitMediaPlayer(string fileName)
        {
            m_objFilterGraph = new FilgraphManager();
            m_objFilterGraph.RenderFile(fileName);

            m_objBasicAudio = m_objFilterGraph as IBasicAudio;
            m_objMediaEvent = m_objFilterGraph as IMediaEvent;

            m_objMediaEventEx = m_objFilterGraph as IMediaEventEx;

            m_objMediaPosition = m_objFilterGraph as IMediaPosition;

            m_objMediaControl = m_objFilterGraph as IMediaControl;
        }

        /// <summary>
        /// 播放
        /// </summary>
        public void Play()
        {
            m_objMediaControl.Run();
            m_currentStatus = MediaStatus.Running;
        }

        /// <summary>
        /// 暂停
        /// </summary>
        public void Pause()
        {
            m_objMediaControl.Pause();
            m_currentStatus = MediaStatus.Paused;
        }

        /// <summary>
        /// 停止
        /// </summary>
        public void Stop()
        {
            m_objMediaControl.Stop();
            m_objMediaPosition.CurrentPosition = 0;
            m_currentStatus = MediaStatus.Stopped;
        }

        /// <summary>
        /// 获取文件的播放时长
        /// </summary>
        /// <param name="fileNameList">文件</param>
        /// <returns>播放时长</returns>
        public double GetDuration(string fileName)
        {
            FilgraphManager filterGraph = new FilgraphManager();

            filterGraph.RenderFile(fileName);
            IMediaPosition mediaPosition = filterGraph as IMediaPosition;

            return mediaPosition.Duration;
        }

        /// <summary>
        /// 清理资源
        /// </summary>
        public void CleanUp()
        {
            if (m_objMediaControl != null)
                m_objMediaControl.Stop();

            m_currentStatus = MediaStatus.Stopped;

            if (m_objMediaEventEx != null)
                m_objMediaEventEx.SetNotifyWindow(0, 0, 0);

            if (m_objMediaControl != null) m_objMediaControl = null;
            if (m_objMediaPosition != null) m_objMediaPosition = null;
            if (m_objMediaEventEx != null) m_objMediaEventEx = null;
            if (m_objMediaEvent != null) m_objMediaEvent = null;
            if (m_objBasicAudio != null) m_objBasicAudio = null;
            if (m_objFilterGraph != null) m_objFilterGraph = null;
        }
        #endregion
    }
}

   

3、MediaFileInfo.CS
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MyMp3Player
{
    class MediaFileInfo
    {
        private int m_id;  // 流水号
        private string m_title = string.Empty;  // 标题
        private string m_length = string.Empty;  // 时长
        private string m_size = string.Empty;  // 大小
        private string m_path = string.Empty;  // 文件路径

        public int ID
        {
            get { return m_id; }
            set { m_id = value; }
        }

        public string Title
        {
            get { return m_title; }
            set { m_title = value; }
        }

        public string Length
        {
            get { return m_length; }
            set { m_length = value; }
        }

        public string Size
        {
            get { return m_size; }
            set { m_size = value; }
        }

        public string Path
        {
            get { return m_path; }
            set { m_path = value; }
        }
    }
}

   

4、Utils.CS
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MyMp3Player
{
    class Utils
    {
        /// <summary>
        /// 将时长转换为字符串的时间格式
        /// </summary>
        /// <param name="duration">时长</param>
        /// <returns>字符串的时间格式</returns>
        public static string ConvertTimeToString(double duration)
        {
            int s = (int)duration;
            int h = s / 3600;
            int m = (s - (h * 3600)) / 60;
            s = s - (h * 3600 + m * 60);

            return String.Format("{0:D2}:{1:D2}", m, s);
        }

        /// <summary>
        /// 获取文件名称
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public static string GetFileName(string name)
        {
            string fileName = name;
            fileName = fileName.Substring(0, fileName.Length - 4);
            if (fileName.IndexOf("&") > 0)
            {
                fileName = fileName.Replace("&", "&&");
            }

            return fileName;
        }

        /// <summary>
        /// 转换文件大小
        /// </summary>
        /// <param name="size">大小(字节数)</param>
        /// <returns>转换后的大小</returns>
        public static string GetSizeInfo(long size)
        {
            string retval = "";

            if (size < 1024)
            {
                retval = string.Format("{0:n2} Byte", size);
            }
            else if ((size / 1024) < 1024)
            {
                retval = string.Format("{0:n2} KB", ((double)size / 1024));
            }
            else if ((size / 1024 / 1024) < 1024)
            {
                retval = string.Format("{0:n2} MB", ((double)size / 1024 / 1024));
            }
            else if ((size / 1024 / 1024 / 1024) < 1024)
            {
                retval = string.Format("{0:n2} GB", ((double)size / 1024 / 1024 / 1024));
            }

            return retval;
        }

        /// <summary>
        /// 将字符串数值转换为整型数值
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static int StringToInteger(string s)
        {
            int retval = 0;

            if (!string.IsNullOrEmpty(s))
            {
                retval = Int32.Parse(s);
            }

            return retval;
        }
    }
}

   

5、枚举
public enum MediaStatus
    {
        None,
        Stopped,
        Paused,
        Running
    };

    public enum SortType
    {
        ASC,
        DES
    };

    public enum PlayMode
    {
        Single,
        SingleCycle,
        Order,
        Cycle,
        Random
    };

 

    在测试过程中,仍然发现了一些问题,需要在后续进行完善,敬请期待。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

踏雪无痕大黄蜂

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值