Windows 7 MP3 播放器






4.88/5 (111投票s)
具有 Windows 7 功能(如进度条和缩略图工具栏)的 MP3 播放器。
引言
在本文中,我们将了解如何使用 C#.NET 开发一款 MP3 播放器,该播放器将利用 Windows 7 的一些新功能。
我们将使用任务栏中的“进度条”显示正在播放歌曲的进度。我们还将显示歌曲的专辑封面作为“缩略图”,并拥有一个包含播放/暂停、下一首和上一首按钮的缩略图工具栏。
必备组件
- 要播放 MP3 歌曲,我们将使用 BASS 音频库。
- 我们还需要 Bass.net,它是 BASS 的 .NET API。
- TagLib Sharp:我们将使用此库读取有关正在播放歌曲的标签信息。
- 适用于 Microsoft® .NET Framework 的 Windows® API 代码包
开发应用程序
玩家
- 在 Visual Studio 中创建一个新项目。
- 添加现有的 Shell 和 Core 项目,它们可以在 WindowsAPICodePack\shell 和 WindowsAPICodePack\core 文件夹下找到。
- 添加对上述项目的引用并导入以下命名空间
Microsoft.WindowsAPICodePack.Dialogs
Microsoft.WindowsAPICodePack.Taskbar
Microsoft.WindowsAPICodePack.Shell
开发的第一部分是开发具有基本功能的播放器,例如播放/暂停、停止、下一首/上一首以及添加/删除歌曲按钮。我们应用程序的主窗体有 7 个按钮、一个列表框、一个标签和一个图片框。
我们将使用图片框显示专辑封面,并使用标签显示正在播放歌曲时的剩余秒数。
注意:确保您已添加 Core、Shell、Bass.net 和 taglib-sharp 的引用。还将 bass.dll 添加到您的项目中(确保您已将“复制到输出目录”设置为“始终复制”)。
Player 类:此类包含我们将用于播放 MP3 文件的所有方法。第一步是初始化一个输出设备。我们使用 Bass.BASS_Init()
来执行此操作。以下是参数
- -1 表示默认设备。
- 44100 是频率。
BASSInit.BASS_DEVICE_DEFAULT
表示要使用的默认设备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
选择区域的 Height
和 Width
进行一些调整,才能获得合适的缩略图。
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
接受两个参数
Icon
:要用于按钮的图标Tooltip
:按钮的工具提示
我们还为每个 Button
的 Click
事件添加了一个事件处理程序。
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;
}
正在运行的播放器
播放
Thumbnail
暂停时的缩略图
播放时的缩略图
暂停时的进度条
结论
这是一个在几小时内开发的基本 MP3 播放器。其创意在于以不同的方式使用进度条。欢迎评论和建议。
参考资料和有用链接
历史
- 2010 年 1 月 31 日:首次发布