65.9K
CodeProject 正在变化。 阅读更多。
Home

Windows 7 MP3 播放器

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.88/5 (111投票s)

2010年2月1日

CPOL

5分钟阅读

viewsIcon

184300

downloadIcon

10659

具有 Windows 7 功能(如进度条和缩略图工具栏)的 MP3 播放器。

Windows7_Mp3_Player/Player.png

引言

在本文中,我们将了解如何使用 C#.NET 开发一款 MP3 播放器,该播放器将利用 Windows 7 的一些新功能。

我们将使用任务栏中的“进度条”显示正在播放歌曲的进度。我们还将显示歌曲的专辑封面作为“缩略图”,并拥有一个包含播放/暂停、下一首和上一首按钮的缩略图工具栏。

必备组件

  1. 要播放 MP3 歌曲,我们将使用 BASS 音频库
  2. 我们还需要 Bass.net,它是 BASS 的 .NET API。
  3. TagLib Sharp:我们将使用此库读取有关正在播放歌曲的标签信息。
  4. 适用于 Microsoft® .NET Framework 的 Windows® API 代码包

开发应用程序

玩家

  1. 在 Visual Studio 中创建一个新项目。
  2. 添加现有的 Shell 和 Core 项目,它们可以在 WindowsAPICodePack\shellWindowsAPICodePack\core 文件夹下找到。
  3. 添加对上述项目的引用并导入以下命名空间
    • Microsoft.WindowsAPICodePack.Dialogs
    • Microsoft.WindowsAPICodePack.Taskbar
    • Microsoft.WindowsAPICodePack.Shell

开发的第一部分是开发具有基本功能的播放器,例如播放/暂停、停止、下一首/上一首以及添加/删除歌曲按钮。我们应用程序的主窗体有 7 个按钮、一个列表框、一个标签和一个图片框。

我们将使用图片框显示专辑封面,并使用标签显示正在播放歌曲时的剩余秒数。

注意:确保您已添加 Core、Shell、Bass.net 和 taglib-sharp 的引用。还将 bass.dll 添加到您的项目中(确保您已将“复制到输出目录”设置为“始终复制”)。

Player 类:此类包含我们将用于播放 MP3 文件的所有方法。第一步是初始化一个输出设备。我们使用 Bass.BASS_Init() 来执行此操作。以下是参数

  1. -1 表示默认设备。
  2. 44100 是频率。
  3. BASSInit.BASS_DEVICE_DEFAULT 表示要使用的默认设备
  4. System.IntPtr.Zero 表示应用程序的主窗口,即当前的前台窗口。

在播放歌曲之前,我们必须先创建一个流。我们使用 BASS_StreamCreateFile() 从文件创建流。然后,我们在 LoadSong() 函数中使用 BASS_ChanelPlay() 来播放我们创建的流。

class player
    {
        int stream;
        public player()
        {
            Bass.BASS_Init(-1, 44100, BASSInit.BASS_DEVICE_DEFAULT, System.IntPtr.Zero);  
        }
        public void LoadSong(string location)
        {
            stream = Bass.BASS_StreamCreateFile
			(location, 0, 0, BASSFlag.BASS_SAMPLE_FLOAT);
        }

        public void PlaySong()
        {
            Bass.BASS_ChannelPlay(stream,false);
        }

        public void StopSong()
        {
            Bass.BASS_ChannelStop(stream);
        }

        public void PauseSong()
        {
            Bass.BASS_ChannelPause(stream);
        }

        ~player()
        {
            Bass.BASS_Free();
        }
    }		

歌曲长度和专辑封面

一旦播放器准备就绪,我们将使用 Taglib sharp 获取歌曲的长度和专辑封面。我们将使用图片框显示专辑封面。我们还将使用此图片框的位置和大小来创建缩略图。

一旦我们从文件(在本例中是播放列表列表框中选中的项)创建 TagLib 文件,我们将使用 Properties.Duration.TotalSeconds 以秒为单位获取歌曲的长度。我们将使用此值来填充 Label 和设置 progressbar 的值。

private void GetSongLength()
        {
            if (playlist.SelectedItem != null)
            {
                TagLib.File f = TagLib.File.Create(playlist.SelectedItem.ToString());   
                songLength = (int)f.Properties.Duration.TotalSeconds;
            }           
        } 

我们还将使用 taglib sharp 来获取当前正在播放歌曲的专辑封面。有些歌曲可能没有专辑封面,因此我们将使用 TagLibfile.Tag.Pictures.Length 来获取与歌曲关联的图片数量。如果大于零,我们将用专辑封面加载图片框。

private void SetAlbumArt()
        {
            if (playlist.SelectedItem != null)
            {
                TagLib.File file = TagLib.File.Create(playlist.SelectedItem.ToString());
                if (file.Tag.Pictures.Length > 0)
                {
                    var bin = (byte[])(file.Tag.Pictures[0].Data.Data);
                    albumart.Image = 
			Image.FromStream(new MemoryStream(bin)).GetThumbnailImage
					(100, 100, null, IntPtr.Zero);
                }
                else
                {
                    albumart.Image = Properties.Resources.gramophone;
                }
            }            
        }

进度条、缩略图工具栏和播放器按钮

创建任务栏按钮并实例化 TaskbarManager

player player;
int playState, songLength, timerCount;
private ThumbnailToolbarButton buttonPlayPause;
private ThumbnailToolbarButton buttonNext;
private ThumbnailToolbarButton buttonPrevious;
TaskbarManager tbManager = TaskbarManager.Instance;
public Form1()
        {
            InitializeComponent();
            player = new player();
            playState = 1;
            songLength = 0;
            timerCount = 1;
        }

这是播放歌曲的主要函数。首先,我们调用 SetAlbumArt() 函数来设置专辑封面。我们使用 SetTaskBarthumbnail() 函数设置缩略图。该函数的解释将在本文后面提供。我们将使用 GetSongLength() SetTimerforPlay() 来获取歌曲长度并激活计时器。

private void PlaySelectedSong()
        {
            SetAlbumArt();
            SetTaskbarthumbnail();
            GetSongLength();
            timerCount = 1;
            SetTimerforPlay();

            if (playlist.SelectedItem != null)
            {
                buttonPlayPause.Icon = Properties.Resources.Pause;
                player.StopSong();
                player.LoadSong(playlist.SelectedItem.ToString());
                player.PlaySong();
                this.Text = playlist.SelectedItem.ToString().Substring
			(playlist.SelectedItem.ToString().LastIndexOf("\\") + 1,
			(playlist.SelectedItem.ToString().Length - 
			(playlist.SelectedItem.ToString().LastIndexOf("\\") + 1)));
            }   
        }
//Play song when the song is double clicked in the Listbox
private void playlist_DoubleClick(object sender, EventArgs e)
        {
            PlaySelectedSong();
        }
private void btnPrevious_Click(object sender, EventArgs e)
        {
            PlayPreviousSong(); 
        }
private void PlayPreviousSong()
        {
            if ((playlist.SelectedIndex - 1) >= 0)
            {
                playlist.SelectedItem = playlist.Items[playlist.SelectedIndex - 1];
                PlaySelectedSong();
            }
        }
private void btnNext_Click(object sender, EventArgs e)
        {
            PlayNextSong();            
        }
private void PlayNextSong()
        {
            if ((playlist.SelectedIndex + 1) < playlist.Items.Count)
            {
                playlist.SelectedItem = 
			playlist.Items[playlist.SelectedIndex + 1];
                PlaySelectedSong();
            }
        }
private void btnAddSong_Click(object sender, EventArgs e)
        {
            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                playlist.Items.Add(openFileDialog.FileName);
            }
        }
private void btnRemoveSong_Click(object sender, EventArgs e)
        {
            playlist.Items.Remove(playlist.SelectedItem);
        }

在下面的函数中,我们首先检查歌曲是否已暂停。我们为此使用 playState 的值。值为零表示歌曲已暂停,我们使用 PlaySong() 函数继续播放歌曲。如果该值不为零,则表示歌曲应从头开始播放。在这种情况下,我们加载歌曲然后播放它。

private void btnPlay_Click(object sender, EventArgs e)
        {
            if (playState == 0)
            {
                //Paused state so start playing
                player.PlaySong();
                playState = 1;
                SetTimerforPlay();
            }
            else
            {
                //Play from Beginning
                PlaySelectedSong();
            }
            buttonPlayPause.Icon = Properties.Resources.Pause;
        }
private void btnPause_Click(object sender, EventArgs e)
        {
            buttonPlayPause.Icon = Properties.Resources.play;
            player.PauseSong();
            playState = 0;
            SetTimerforPause();
        }

此函数在播放歌曲之前调用,用于启用计时器并设置进度条样式。TaskbarProgressBarState.Normal 表示进度将正常。Timer 的间隔设置为 1000 毫秒。

//Set progressbar Style and Enable Timer 
private void SetTimerforPlay()
        {
            tbManager.SetProgressState(TaskbarProgressBarState.Normal);
            progressbarTimer.Enabled = true;
        }

这与 SetTimerforPlay() 类似,但我们将禁用计时器以停止进度条中的进度。同时,我们将将其样式设置为 TaskbarProgressBarState.Error ,以便颜色设置为 红色。此函数在歌曲暂停时调用。

private void SetTimerforPause()
        {
            tbManager.SetProgressState(TaskbarProgressBarState.Error);
            progressbarTimer.Enabled = false;
        }
private void btnStop_Click(object sender, EventArgs e)
        {
            player.StopSong();
        }

我们将使用 TabbedThumbnail.SetThumbnailClip 为我们的 MP3 播放器设置缩略图。为此,我们在主窗体中创建一个新的 Rectangle 选择区域,然后将其设置为缩略图剪辑。我们的目的是使用我们已经在图片框中加载的专辑封面。

注意:我不得不对 rectangle 选择区域的 HeightWidth 进行一些调整,才能获得合适的缩略图。

private void SetTaskbarthumbnail()
        {
        TaskbarManager.Instance.TabbedThumbnail.SetThumbnailClip
		(this.Handle,new Rectangle(albumart.Location.X+4,
		albumart.Location.Y,albumart.Size.Width-1,albumart.Size.Height-4));
        }

缩略图工具栏应在窗体的 Shown 事件期间创建。ThumbnailToolbarButton 接受两个参数

  1. Icon:要用于按钮的图标
  2. Tooltip:按钮的工具提示

我们还为每个 ButtonClick 事件添加了一个事件处理程序。

private void Form1_Shown(object sender, EventArgs e)
        {
            buttonPlayPause = new ThumbnailToolbarButton
			(Properties.Resources.play, "Play");
            buttonPlayPause.Enabled = true;
            buttonPlayPause.Click += 
	     new EventHandler<thumbnailbuttonclickedeventargs>(buttonPlay_Click);

            buttonNext = new ThumbnailToolbarButton
			(Properties.Resources.nextArrow, "Next");
            buttonNext.Enabled = true;
            buttonNext.Click += 
	     new EventHandler<thumbnailbuttonclickedeventargs>(buttonNext_Click);

            buttonPrevious = new ThumbnailToolbarButton
			(Properties.Resources.prevArrow, "Previous");
            buttonPrevious.Click += 
	     new EventHandler<thumbnailbuttonclickedeventargs>(buttonPrevious_Click);
            TaskbarManager.Instance.ThumbnailToolbars.AddButtons
		(this.Handle, buttonPrevious, buttonPlayPause, buttonNext);
            TaskbarManager.Instance.TabbedThumbnail.SetThumbnailClip
		(this.Handle, new Rectangle(albumart.Location, albumart.Size));
        }

缩略图工具栏:播放/暂停、下一首和上一首按钮

void buttonPlay_Click(object sender, EventArgs e)
        {
            if (playState == 0)
            {
                player.PlaySong();
                playState = 1;
                buttonPlayPause.Icon = Properties.Resources.Pause;
                buttonPlayPause.Tooltip = "Pause";
                SetTimerforPlay();
            }
            else
            {
                player.PauseSong();
                playState = 0;
                buttonPlayPause.Icon = Properties.Resources.play;
                buttonPlayPause.Tooltip = "Play";
                SetTimerforPause();
            }
        }
void buttonNext_Click(object sender, EventArgs e)
        {
            PlayNextSong();
        }
void buttonPrevious_Click(object sender, EventArgs e)
        {
            PlayPreviousSong();
        }

进度条

Timer 的间隔设置为 1000 毫秒,一旦按下播放按钮,它就会被启用。我们使用 SongLength 来设置 progressbar 的最大值,并每秒增加进度值。一旦按下暂停按钮,Timer 就会被禁用。

private void progressbarTimer_Tick(object sender, EventArgs e)
        {
            if (timerCount <= songLength)
            {
                tbManager.SetProgressValue(timerCount, songLength);
            }
            lblSeconds.Text = (songLength - timerCount).ToString() + " seconds";
            timerCount += 1;
        }

正在运行的播放器

播放

Windows7_Mp3_Player/playing.png

Thumbnail

Windows7_Mp3_Player/thumbnail.png

暂停时的缩略图

Windows7_Mp3_Player/ThumbnailPaused.png

播放时的缩略图

Windows7_Mp3_Player/ThumbnailPlay.png

暂停时的进度条

Windows7_Mp3_Player/paused.png

结论

这是一个在几小时内开发的基本 MP3 播放器。其创意在于以不同的方式使用进度条。欢迎评论和建议。

参考资料和有用链接

历史

  • 2010 年 1 月 31 日:首次发布
© . All rights reserved.