Click here to Skip to main content
15,867,686 members
Articles / Programming Languages / XML

MP3 Player for Windows 7

Rate me:
Please Sign up or sign in to vote.
4.88/5 (123 votes)
1 Feb 2010CPOL5 min read 177.2K   10.6K   145   40
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)


Written By
Software Developer (Senior) Allianz Cornhill
India India
Shoban Kumar currently works with Allianz Cornhill India in Trivandrum as a Senior Software Engineer. He is one of the core member of Kerala Microsoft User's Group http://www.k-mug.org.

SharePoint Blog : http://allaboutmoss.com

He has also written many open source applications which can be found in Codeplex : http://www.codeplex.com/site/users/view/shobankr

Comments and Discussions

 
Questionhow to start with bass lib. Pin
Member 102165025-Jan-15 22:16
Member 102165025-Jan-15 22:16 
QuestionErrror Pin
Damian Darul1-Sep-13 1:51
Damian Darul1-Sep-13 1:51 
GeneralMy vote of 5 Pin
Sad Pencil25-Jul-13 16:16
Sad Pencil25-Jul-13 16:16 
QuestionGraphic Equalizers Pin
gaurav123pareek1-Feb-13 0:40
gaurav123pareek1-Feb-13 0:40 
Generalhi., thank you Pin
ullas kishan30-Jan-13 5:21
ullas kishan30-Jan-13 5:21 
GeneralMy vote of 5 Pin
Mario Majčica28-Jan-13 23:04
professionalMario Majčica28-Jan-13 23:04 
QuestionJump list? Pin
Iandavid12326-Jun-12 15:23
Iandavid12326-Jun-12 15:23 
GeneralMy vote of 5 Pin
vshal5261-Jun-12 1:57
vshal5261-Jun-12 1:57 
GeneralMy Vote of 5 Pin
RaviRanjanKr28-Nov-11 8:31
professionalRaviRanjanKr28-Nov-11 8:31 
QuestionYou can ditch that Bass library requirement for my MP3 library Pin
Shao Voon Wong14-Aug-11 15:19
mvaShao Voon Wong14-Aug-11 15:19 
Questionwhich version of vs? Pin
Member 778883726-Mar-11 21:04
Member 778883726-Mar-11 21:04 
GeneralProblem with error 0x8007000B (Solution) Pin
Riskboy31-Aug-10 9:19
Riskboy31-Aug-10 9:19 
GeneralRe: Problem with error 0x8007000B (Solution) Pin
Alonso Calle10-Mar-11 7:54
Alonso Calle10-Mar-11 7:54 
GeneralRe: Problem with error 0x8007000B (Solution) Pin
Riskboy10-Mar-11 9:44
Riskboy10-Mar-11 9:44 
GeneralRe: Problem with error 0x8007000B (Solution) Pin
Alonso Calle10-Mar-11 10:58
Alonso Calle10-Mar-11 10:58 
GeneralRe: Problem with error 0x8007000B (Solution) Pin
Riskboy13-Mar-11 0:35
Riskboy13-Mar-11 0:35 
GeneralRe: Problem with error 0x8007000B (Solution) Pin
Alonso Calle13-Mar-11 19:23
Alonso Calle13-Mar-11 19:23 
GeneralMy vote of 3 Pin
kimehi23-Aug-10 5:32
kimehi23-Aug-10 5:32 
GeneralProblem with error 0x8007000B Pin
AnkioSei1-Jul-10 23:49
AnkioSei1-Jul-10 23:49 
GeneralLeft-Right channel changing Pin
PowR_TocH20-Apr-10 7:56
PowR_TocH20-Apr-10 7:56 
GeneralGood work... Pin
Sandeep Mewara12-Mar-10 23:55
mveSandeep Mewara12-Mar-10 23:55 
GeneralLooks well but not work in my computer Pin
nicholas_pei9-Mar-10 16:22
nicholas_pei9-Mar-10 16:22 
GeneralRe: Looks well but not work in my computer Pin
Member 418768911-Mar-10 3:54
Member 418768911-Mar-10 3:54 
GeneralRe: Looks well but not work in my computer Pin
faraza13-Mar-10 2:50
faraza13-Mar-10 2:50 
GeneralRe: Looks well but not work in my computer Pin
ach2r15-Mar-10 20:24
ach2r15-Mar-10 20:24 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.