利用DirectShow开发C#版的MP3播放器(一)
??? 因工作需要,近期開始接觸DirectShow開發的相關技術,由于本人較青睞于C#,因此從網上找了一些關于.NET版的DirectShow庫及實例,之后參考相關源碼編寫了一個用于測試的MP3播放器,源碼主要參考了SourceForge(http://sourceforge.net/)上的一份關于DirectShow的源碼實例。
??? 這篇文章展示的是一個初步的不完善的MP3播放器Demo,包括兩部分:播放控制部分和播放列表部分。其中播放控制部分的基本功能包括:播放/暫停、停止、上一曲、下一曲、播放進度條、當前播放時間、播放時長、播放標題。播放列表部分包括:播放列表、添加、刪除。此外,還增加了順序播放和隨機播放兩種播放模式,默認為順序播放模式。
??? 因無法上傳圖片,這里貼出主要代碼:
using System;
using System.Windows.Forms;
using System.IO;
using QuartzTypeLib;
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 const int WS_CHILD = 0x40000000;
??????? private const int WS_CLIPCHILDREN = 0x2000000;
?
??????? private FilgraphManager m_objFilterGraph = null;
??????? private IBasicAudio m_objBasicAudio = null;
??????? private IVideoWindow m_objVideoWindow = null;
??????? private IMediaEvent m_objMediaEvent = null;
??????? private IMediaEventEx m_objMediaEventEx = null;
??????? private IMediaPosition m_objMediaPosition = null;
??????? private IMediaControl m_objMediaControl = null;
?
??????? enum MediaStatus { None, Stopped, Paused, Running };
??????? private MediaStatus m_CurrentStatus = MediaStatus.None;
?
??????? private string m_strFilePath;? // 文件路徑
??????? private bool m_blnRandomPlay = false;? // 隨機播放模式
??????? public FrmPlayer()
??????? {
??????????? InitializeComponent();
??????????? this.UpdatePlayTime();
??????????? this.UpdatePlayList();
??????????? this.UpdateButtonStatus();
??????? }
??????? private void FrmPlayer_Load(object sender, EventArgs e)
??????? {
??????? }
??????? private void FrmPlayer_FormClosing(object sender, FormClosingEventArgs e)
??????? {
??????????? this.CleanUp();
??????? }
??????? /// <summary>
??????? /// 播放/暫停
??????? /// </summary>
??????? /// <param name="sender"></param>
??????? /// <param name="e"></param>
??????? private void btnPlayPause_Click(object sender, EventArgs e)
??????? {
??????????? if (m_CurrentStatus == MediaStatus.Running)
??????????? {
??????????????? this.Pause();
??????????? }
??????????? else
??????????? {
??????????????? this.Play();
??????????? }
??????? }
??????? /// <summary>
??????? /// 停止
??????? /// </summary>
??????? /// <param name="sender"></param>
??????? /// <param name="e"></param>
??????? private void btnStop_Click(object sender, EventArgs e)
??????? {
??????????? this.Stop();
??????? }
??????? /// <summary>
??????? /// 上一曲
??????? /// </summary>
??????? /// <param name="sender"></param>
??????? /// <param name="e"></param>
??????? private void btnPrevious_Click(object sender, EventArgs e)
??????? {
??????????? this.Previous();
??????? }
??????? /// <summary>
??????? /// 下一曲
??????? /// </summary>
??????? /// <param name="sender"></param>
??????? /// <param name="e"></param>
??????? private void btnNext_Click(object sender, EventArgs e)
??????? {
??????????? this.Next();
??????? }
??????? /// <summary>
??????? /// 定時器
??????? /// </summary>
??????? /// <param name="sender"></param>
??????? /// <param name="e"></param>
??????? private void timer1_Tick(object sender, EventArgs e)
??????? {
??????????? if (m_CurrentStatus == MediaStatus.Running)
??????????? {
??????????????? this.UpdatePlayTime();
??????????? }
??????? }
??????? /// <summary>
??????? /// 播放進度條控制
??????? /// </summary>
??????? /// <param name="sender"></param>
??????? /// <param name="e"></param>
??????? private void trackBarPlay_Scroll(object sender, EventArgs e)
??????? {
??????????? if (m_CurrentStatus != MediaStatus.None)
??????????? {
??????????????? m_objMediaPosition.CurrentPosition = m_objMediaPosition.Duration * trackBarPlay.Value / 100;
??????????? }
??????? }
??????? /// <summary>
??????? /// 添加播放文件
??????? /// </summary>
??????? /// <param name="sender"></param>
??????? /// <param name="e"></param>
??????? private void btnAdd_Click(object sender, EventArgs e)
??????? {
??????????? OpenFileDialog openFileDialog = new OpenFileDialog();
??????????? openFileDialog.Filter = "MP3文件(*.mp3)|*.mp3";
??????????? openFileDialog.Multiselect = true;
??????????? if (DialogResult.OK == openFileDialog.ShowDialog())
??????????? {
??????????????? string[] fileNames = openFileDialog.FileNames;
??????????????? if (fileNames != null)
??????????????? {
??????????????????? foreach (string fileName in fileNames)
??????????????????? {
??????????????????????? lstPlayList.Items.Add(fileName);
??????????????????? }
??????????????????? if (lstPlayList.SelectedIndex < 0) // 當前播放列表為空
??????????????????? {
??????????????????????? // 選中第一個文件并進行播放
??????????????????????? lstPlayList.SelectedIndex = 0;
??????????????????????? this.InitPlayer();
??????????????????????? this.Play();
??????????????????? }
??????????????????? this.UpdatePlayList();
??????????????? }
??????????? }
??????? }
??????? /// <summary>
??????? /// 雙擊選中文件并播放
??????? /// </summary>
??????? /// <param name="sender"></param>
??????? /// <param name="e"></param>
??????? private void lstPlayList_DoubleClick(object sender, EventArgs e)
??????? {
??????????? if (lstPlayList.Items.Count > 0)
??????????? {
??????????????? this.InitPlayer();
??????????????? this.Play();
??????????? }
??????? }
??????? /// <summary>
??????? /// 隨機播放模式
??????? /// </summary>
??????? /// <param name="sender"></param>
??????? /// <param name="e"></param>
??????? private void btnPlayRandom_Click(object sender, EventArgs e)
??????? {
??????????? m_blnRandomPlay = true;
??????????? btnPlayOrder.Enabled = true;
??????????? btnPlayRandom.Enabled = false;
??????? }
??????? /// <summary>
??????? /// 順序播放模式
??????? /// </summary>
??????? /// <param name="sender"></param>
??????? /// <param name="e"></param>
??????? private void btnPlayOrder_Click(object sender, EventArgs e)
??????? {
??????????? m_blnRandomPlay = false;
??????????? btnPlayOrder.Enabled = false;
??????????? btnPlayRandom.Enabled = true;
??????? }
??????? /// <summary>
??????? /// 清空播放列表
??????? /// </summary>
??????? /// <param name="sender"></param>
??????? /// <param name="e"></param>
??????? private void btnClear_Click(object sender, EventArgs e)
??????? {
??????????? lstPlayList.Items.Clear();
??????????? btnPlayOrder.Enabled = false;
??????????? btnPlayRandom.Enabled = false;
??????????? btnClear.Enabled = false;
??????? }
??????? #region private methods
??????? /// <summary>
??????? /// 更新播放時間及播放進度
??????? /// </summary>
??????? private void UpdatePlayTime()
??????? {
??????????? if (m_objMediaPosition != null)
??????????? {
??????????????? int s = (int)m_objMediaPosition.Duration;
??????????????? int h = s / 3600;
??????????????? int m = (s - (h * 3600)) / 60;
??????????????? s = s - (h * 3600 + m * 60);
??????????????? lblTotalTime.Text = String.Format("{0:D2}:{1:D2}", m, s);
??????????????? s = (int)m_objMediaPosition.CurrentPosition;
??????????????? h = s / 3600;
??????????????? m = (s - (h * 3600)) / 60;
??????????????? s = s - (h * 3600 + m * 60);
??????????????? lblCurrentTime.Text = String.Format("{0:D2}:{1:D2}", m, s);
??????????????? trackBarPlay.Value = (int)(100 * (m_objMediaPosition.CurrentPosition / m_objMediaPosition.Duration));
??????????? }
??????????? else
??????????? {
??????????????? lblTotalTime.Text = "00:00";
??????????????? lblCurrentTime.Text = "00:00";
??????????? }
??????? }
??????? /// <summary>
??????? /// 根據播放列表狀態更新相應按鈕狀態
??????? /// </summary>
??????? private void UpdatePlayList()
??????? {
??????????? if (lstPlayList.Items.Count > 0)
??????????? {
??????????????? btnPrevious.Enabled = true;
??????????????? btnNext.Enabled = true;
??????????????? btnClear.Enabled = true;
??????????????? btnPlayRandom.Enabled = true;
??????????? }
??????????? else
??????????? {
??????????????? btnPrevious.Enabled = false;
??????????????? btnNext.Enabled = false;
??????????????? btnClear.Enabled = false;
??????????????? btnPlayRandom.Enabled = false;
??????????? }
??????? }
??????? /// <summary>
??????? /// 更新播放按鈕狀態
??????? /// </summary>
??????? private void UpdateButtonStatus()
??????? {
??????????? switch (m_CurrentStatus)
??????????? {
??????????????? case MediaStatus.None:
??????????????????? btnPlayPause.Enabled = false;
??????????????????? btnStop.Enabled = false;
??????????????????? break;
??????????????? case MediaStatus.Paused:
??????????????? case MediaStatus.Running:
??????????????????? btnPlayPause.Enabled = true;
??????????????????? btnStop.Enabled = true;
??????????????????? break;
??????????????? case MediaStatus.Stopped:
??????????????????? btnPlayPause.Enabled = true;
??????????????????? btnStop.Enabled = false;
??????????????????? lblCurrentTime.Text = "00:00";
??????????????????? lblTotalTime.Text = "00:00";
??????????????????? trackBarPlay.Value = 0;
??????????????????? break;
??????????? }
??????? }
??????? /// <summary>
??????? /// 初始化播放
??????? /// </summary>
??????? private void InitPlayer()
??????? {
??????????? this.CleanUp();
??????????? m_strFilePath = lstPlayList.SelectedItem.ToString();
??????????? m_objFilterGraph = new FilgraphManager();
??????????? m_objFilterGraph.RenderFile(m_strFilePath);
??????????? m_objBasicAudio = m_objFilterGraph as IBasicAudio;
??????????? m_objMediaEvent = m_objFilterGraph as IMediaEvent;
??????????? m_objMediaEventEx = m_objFilterGraph as IMediaEventEx;
??????????? m_objMediaEventEx.SetNotifyWindow((int)this.Handle, WM_GRAPHNOTIFY, 0);
??????????? m_objMediaPosition = m_objFilterGraph as IMediaPosition;
??????????? m_objMediaControl = m_objFilterGraph as IMediaControl;
??????? }
??????? /// <summary>
??????? /// 播放
??????? /// </summary>
??????? private void Play()
??????? {
??????????? FileInfo fi = new FileInfo(m_strFilePath);
??????????? string fileName = fi.Name;
??????????? fileName = fileName.Substring(0, fileName.Length - 4);
??????????? if (fileName.IndexOf("&") > 0)
??????????? {
??????????????? fileName = fileName.Replace("&", "&&");
??????????? }
??????????? lblTitle.Text = fileName;
??????????? m_objMediaControl.Run();
??????????? m_CurrentStatus = MediaStatus.Running;
??????????? btnPlayPause.Text = "暫停";
??????????? this.UpdatePlayTime();
??????????? this.UpdateButtonStatus();
??????? }
??????? /// <summary>
??????? /// 暫停
??????? /// </summary>
??????? private void Pause()
??????? {
??????????? m_objMediaControl.Pause();
??????????? m_CurrentStatus = MediaStatus.Paused;
??????????? btnPlayPause.Text = "播放";
??????????? this.UpdatePlayTime();
??????????? this.UpdateButtonStatus();
??????? }
??????? /// <summary>
??????? /// 停止
??????? /// </summary>
??????? private void Stop()
??????? {
??????????? m_objMediaControl.Stop();
??????????? m_objMediaPosition.CurrentPosition = 0;
??????????? m_CurrentStatus = MediaStatus.Stopped;
??????????? btnPlayPause.Text = "播放";
??????????? this.UpdateButtonStatus();
??????? }
??????? /// <summary>
??????? /// 上一曲
??????? /// </summary>
??????? private void Previous()
??????? {
??????????? if (m_blnRandomPlay)? // 隨機播放模式
??????????? {
??????????????? Random random = new Random();
??????????????? lstPlayList.SelectedIndex = random.Next(lstPlayList.Items.Count);
??????????? }
??????????? else? // 順序播放模式
??????????? {
??????????????? if (lstPlayList.SelectedIndex == 0)
??????????????? {
??????????????????? // 已移到最前面,不做任何事情
??????????????? }
??????????????? else
??????????????? {
??????????????????? lstPlayList.SelectedIndex -= 1;
??????????????? }
??????????? }
??????????? this.InitPlayer();
??????????? this.Play();
??????? }
??????? /// <summary>
??????? /// 下一曲
??????? /// </summary>
??????? private void Next()
??????? {
??????????? if (m_blnRandomPlay)? // 隨機播放模式
??????????? {
??????????????? Random random = new Random();
??????????????? lstPlayList.SelectedIndex = random.Next(lstPlayList.Items.Count);
??????????? }
??????????? else? // 順序播放模式
??????????? {
??????????????? if (lstPlayList.SelectedIndex == lstPlayList.Items.Count - 1)
??????????????? {
??????????????????? // 已移到最后面,不做任何事情
??????????????? }
??????????????? else
??????????????? {
??????????????????? lstPlayList.SelectedIndex += 1;
??????????????? }
??????????? }
??????????? this.InitPlayer();
??????????? this.Play();
??????? }
??????? /// <summary>
??????? /// 清理
??????? /// </summary>
??????? private 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_objVideoWindow != null)
??????????? {
??????????????? m_objVideoWindow.Visible = 0;
??????????????? m_objVideoWindow.Owner = 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_objVideoWindow != null) m_objVideoWindow = null;
??????????? if (m_objBasicAudio != null) m_objBasicAudio = null;
??????????? if (m_objFilterGraph != null) m_objFilterGraph = null;
??????? }
??????? /// <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
??????????????????? {
??????????????????????? m_objMediaEventEx.GetEvent(out lEventCode, out lParam1, out lParam2, 0);
??????????????????????? m_objMediaEventEx.FreeEventParams(lEventCode, lParam1, lParam2);
??????????????????????? if (lEventCode == EC_COMPLETE)
??????????????????????? {
??????????????????????????? this.Next(); // 自動切換到下一曲
??????????????????????? }
??????????????????? }
??????????????????? catch (Exception)
??????????????????? {
??????????????????????? break;
??????????????????? }
??????????????? }
??????????? }
??????????? base.WndProc(ref m);
??????? }
??????? #endregion
??? }
}
??? 上面實例使用到了Interop.QuartzTypeLib.dll,并沒有完全使用DirectShow的一些內部機制,僅僅是一個簡單例子,在后面如有時間將會對該播放器進行逐步完善。
總結
以上是生活随笔為你收集整理的利用DirectShow开发C#版的MP3播放器(一)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 将文本中的各个单词的字母顺序翻转(Jav
- 下一篇: c# char unsigned_dll