Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / XML

MP3 Player for Windows 7

4.88/5 (123 votes)
1 Feb 2010CPOL5 min read 181.9K   10.6K  
MP3 player which has Windows 7 features like Progressbar and Thumbnail toolbar

Windows7_Mp3_Player/Player.png

Introduction

In this article, we will see how we can develop an MP3 player, using C#.NET, which will use some of the new features of Windows 7.

We will show the progress of the song being played using the "Progress bar" in Taskbar. We will also show the Album art of the song as the "Thumbnail" and we will also have a Thumbnail Toolbar which has the Play/Pause, Next and Previous buttons.

Prerequisites

  1. To play MP3 songs, we will be using the BASS Audio Library.
  2. We will also need Bass.net which is the .NET API for BASS.
  3. TagLib Sharp: We will use this library to read tagging information about the song being played.
  4. Windows® API Code Pack for Microsoft® .NET Framework

Developing the Application

The Player

  1. Create a new project in Visual Studio.
  2. Add the existing projects Shell and Core which can be found under the WindowsAPICodePack\shell and WindowsAPICodePack\core folders.
  3. Add a reference to the above projects and import the following namespaces:
    • Microsoft.WindowsAPICodePack.Dialogs
    • Microsoft.WindowsAPICodePack.Taskbar
    • Microsoft.WindowsAPICodePack.Shell

The first part of the development is developing the player which will have the basic functionality like Play/Pause, Stop, next Previous/Next and Add/Remove songs Buttons. The main form in our application has 7 Buttons, A listbox, Label and a Picture Box.

We will use the Picture Box to display the Album Art and we will use the Label to display the seconds remaining while a song is being played.

Note: Make sure you have added references for Core, Shell, Bass.net and taglib-sharp. Also add bass.dll to your project (Make sure you have set "Copy to Output Directory" as "Copy Always".)

Player Class: This class has all the methods which we will be using to play MP3 files. The first step is to initialize an output device. We use Bass.BASS_Init() for this. Following are the parameters:

  1. -1 denotes default device.
  2. 44100 is the frequency.
  3. BASSInit.BASS_DEVICE_DEFAULT denotes th default device to use
  4. System.IntPtr.Zero denotes the application's main window which is the current foreground window.

Before playing a song, we must first create a stream. We use BASS_StreamCreateFile() to create a stream from a file. We then use BASS_ChanelPlay() to play the stream which we created in the LoadSong() function.

C#
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();
        }
    }		

Song Length and Album Art

Once the player is ready, we will use Taglib sharp to get the length of the song and album art. We will use the picture box to display the album art. We will also use this picture box's location and size to create the Thumbnail.

Once we create the TagLib file from a file (in this case, the selected item in the playlist listbox), we will use Properties.Duration.TotalSeconds to get the length of the song in seconds. We will be using this value to populate the Label and the set the progressbar value.

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

We will also be using taglib sharp to get the album art of the song which is being currently played. Some songs may not have an Album art so we will use TagLibfile.Tag.Pictures.Length to get the numbers of pictures associated with the song. If it is more than zero, then we load the picture box with the album art.

C#
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;
                }
            }            
        }

Progressbar, Thumbnail Toolbar and Player Buttons

Create Taskbar buttons and instance of TaskbarManager.

C#
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;
        }

This is the main function which will play the song. First, we call the SetAlbumArt() function which will set the album art. We use SetTaskBarthumbnail() function to the set the thumbnail. Explanation for this function comes later in this article. We will use GetSongLength() and SetTimerforPlay() to get the song length and activate the timer respectively.

C#
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)));
            }   
        }
C#
//Play song when the song is double clicked in the Listbox
private void playlist_DoubleClick(object sender, EventArgs e)
        {
            PlaySelectedSong();
        }
C#
private void btnPrevious_Click(object sender, EventArgs e)
        {
            PlayPreviousSong(); 
        }
C#
private void PlayPreviousSong()
        {
            if ((playlist.SelectedIndex - 1) >= 0)
            {
                playlist.SelectedItem = playlist.Items[playlist.SelectedIndex - 1];
                PlaySelectedSong();
            }
        }
C#
private void btnNext_Click(object sender, EventArgs e)
        {
            PlayNextSong();            
        }
C#
private void PlayNextSong()
        {
            if ((playlist.SelectedIndex + 1) < playlist.Items.Count)
            {
                playlist.SelectedItem = 
			playlist.Items[playlist.SelectedIndex + 1];
                PlaySelectedSong();
            }
        }
C#
private void btnAddSong_Click(object sender, EventArgs e)
        {
            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                playlist.Items.Add(openFileDialog.FileName);
            }
        }
C#
private void btnRemoveSong_Click(object sender, EventArgs e)
        {
            playlist.Items.Remove(playlist.SelectedItem);
        }

In the below function, we first check whether the song is paused. We use the value of playState for this. Value zero means the song is paused and we use the PlaySong() function to continue playing the song. If the value is not zero, then it denotes that the song should be played from the beginning. In this case, we load the song and then play it.

C#
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;
        }
C#
private void btnPause_Click(object sender, EventArgs e)
        {
            buttonPlayPause.Icon = Properties.Resources.play;
            player.PauseSong();
            playState = 0;
            SetTimerforPause();
        }

This function is called just before playing the song to enable the timer and set the progress bar style. TaskbarProgressBarState.Normal denotes that the progress will be normal. Timer's interval is set as 1000 ms.

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

This is similar to SetTimerforPlay() but we will disable the timer to stop the progress in the progress bar. At the same time, we will also set its style to TaskbarProgressBarState.Error so that the color is set as Red. This function is called when the song is paused.

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

We will be using TabbedThumbnail.SetThumbnailClip to set the thumbnail for our MP3 player. For this, we create a new Rectangle selection inside the main form and then set it as the thumbnail clip. Our motive is to use the Album art which we have already loaded in the Picture Box.

Note: I had to make some adjustments in the Height and Width of the rectangle selection to get a proper thumbnail.

C#
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));
        }

Thumbnail Toolbar should be created during the Form's Shown event. ThumbnailToolbarButton accepts two parameters:

  1. Icon: the Icon to be used for the button
  2. Tooltip: the tool tip for the button

We also add an Event Handler for each of the Button's Click events.

C#
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));
        }

Thumbnail Toolbars: Play/Pause, Next and Previous Buttons

C#
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();
            }
        }
C#
void buttonNext_Click(object sender, EventArgs e)
        {
            PlayNextSong();
        }
C#
void buttonPrevious_Click(object sender, EventArgs e)
        {
            PlayPreviousSong();
        }

Progressbar

Timer's interval is set to 1000ms and it will be enabled as soon as the play button is pressed. We use the SongLength to set the maximum value of the progressbar and increment the progress value every second. Timer will be disabled as soon as the pause button is pressed.

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

Player in Action

Play

Windows7_Mp3_Player/playing.png

Thumbnail

Windows7_Mp3_Player/thumbnail.png

Thumbnail while Paused

Windows7_Mp3_Player/ThumbnailPaused.png

Thumbnail while Playing

Windows7_Mp3_Player/ThumbnailPlay.png

Progressbar while Paused

Windows7_Mp3_Player/paused.png

Conclusion

This is a basic MP3 player which was developed in few hours. The idea was to use progress bar differently. Comments and suggestions are always welcome.

References and Useful Links

History

  • 31st January, 2010: Initial release

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)