继上一次利用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
    };

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

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

  1. 利用DirectShow开发C#版的MP3播放器(一)

    因工作需要,近期开始接触DirectShow开发的相关技术,由于本人较青睐于C#,因此从网上找了一些关于.NET版的DirectShow库及实例,之后参考相关源码编写了一个用于测试的MP3播放器,源码 ...

  2. 利用DirectShow开发C#版的音频文件播放器(三)

    前面曾经讲到了利用利用DirectShow开发C#版的MP3播放器,这篇文章是对前面两篇文章的补充与升华. 首先,大家不难发现,这篇文章的标题已经修改为音频文件播放器,而不仅仅是针对MP3一种格式,支 ...

  3. 利用DirectShow开发C#版的音频文件播放器(补充完善)

    继今年三月份利用DirectShow开发C#版的音频文件播放器(三)文章之后,一直希望对这个音频文件播放器所存在的一些问题做修改完善,可惜一直忙于工作而无暇顾及这个事情.近日,有读者朋友提到了这个问题 ...

  4. python开发音乐播放器教程_python开发简易版在线音乐播放器示例代码

    在线音乐播放器,使用python的Tkinter库做了一个界面,感觉这个库使用起来还是挺方便的,音乐的数据来自网易云音乐的一个接口,通过urllib.urlopen模块打开网址,使用Json模块进行数 ...

  5. 利用DirectShow开发C#版的视频播放器

    今天这里要给各位朋友介绍的是本人利用业余时间使用C#编写的一个视频播放器,开发环境为Microsoft Visual Studio 2008/C#.Microsoft DirectX 9.0 SDK. ...

  6. swift版QQ音乐播放器(二)

    一 完善部分的QQ音乐效果图 二 需要完善点 1 歌曲的切换和暂停播放 2 歌曲当前播放时间和歌曲总时间的更新 3 进度条的处理 4 歌手头像处理 5 头像动画效果 6 歌词的进度显示 8 完善细节 ...

  7. linux ipod驱动程序,佳能 iPod Classic 驱动程序下载-更新佳能软件(MP3播放器)

    Apple iPod Classic 驱动程序下载 如何手动下载和更新: iPod Classic 设备的默认驱动程序版本可以通过 %%os%% 或 Windows® 更新获取. 内置驱动程序支持Cl ...

  8. alin的学习之路:嵌入式课程设计总结(基于Linux的Qt版MP3播放器)

    嵌入式课程设计总结(基于Linux的Qt版MP3播放器) 废话不多写直接上图上代码,其中有很多不规范的地方,希望大佬们指正. 1.课设题目 设计一个MP3播放器,要求:使用Linux下的madplay ...

  9. 3分钟开发一个冰冰版 3D 音乐播放器,是什么样的体验

    : 一个对开发技术特别执着的程序员,对移动开发有着独到的见解和深入的研究,有着多年的iOS.Android.HTML5开发经验,对NativeApp.HybridApp.WebApp开发有着独到的见解 ...

最新文章

  1. [原创]什么是CMM?
  2. 【Windows 逆向】OD 调试器工具 ( 分析 OD 硬件断点处的关键代码 | 添加硬件断点 | 关键代码 | MOV 指令 | EAX 寄存器值分析 | 使用命令查看 esi+0cc 地址 )
  3. 深入了解C#系列:谈谈C#中垃圾回收与内存管理机制
  4. 保持函数依赖的模式分解可以减轻或解决什么_为什么我更喜欢函数式编程?
  5. springboot 多线程_机密文档!阿里产出SpringBoot/Cloud,细节爆炸
  6. Android之EditText练习
  7. Direct3D11学习:(二)基本绘图概念和基本类型
  8. maters鸿蒙系统,Flutter入门进阶之旅(十)DialogToast
  9. 使用读写锁实现同步数据访问
  10. csv反序列化_Py't'hon之csv,ini序列化,反序列化
  11. Access新手到高手视频教程 109讲
  12. Anaconda版本选择 Python3.6版本的Anaconda下载
  13. 【机器学习】CART决策树原理及python实现
  14. idea 使用中文汉化包教程
  15. pygame UI 框架
  16. ali-oss配合element上传130M以上的文件,浏览器直接崩溃,有大神知道是什么情况么
  17. (学习笔记) SPI通信协议
  18. ChemOffice Suite 2018 18.1.2.18
  19. Gitee是什么?和GitHub的区别?
  20. 能在Windows CE上运行的的二维码识别系统,使用手机摄像头扫描二维码

热门文章

  1. 高级Java程序员技术栈
  2. 随身wifi挑选要注意哪些问题才能避免上当
  3. Photoshop辅助线和标尺的使用技巧
  4. mysql 1045 远程_启用远程mysql连接:错误1045(28000):拒绝用户访问
  5. ch341a i2c 安卓_CH341A实现USB转I2C的问题
  6. 「为了孩子上海淀小学,我一周上七节课」
  7. 两年工作经验,离职了...
  8. IPV6地址基础知识
  9. 「PAT乙级真题解析」Basic Level 1033 旧键盘打字 (问题分析+完整步骤+伪代码描述+提交通过代码)
  10. 2018.4.3晚_京东实习_后端开发面试记录