Click here to Skip to main content
15,879,348 members
Articles / Programming Languages / C#

Media Player Class

Rate me:
Please Sign up or sign in to vote.
4.85/5 (6 votes)
18 Nov 2010CDDL4 min read 65K   7.4K   27   5
An advanced media player class using WindowsMediaPlayerClass. Supports cross-fading/fading.

Introduction

I little while ago, I found myself writing a media player, and consequently was looking for an easy way to play MP3, Wav, midi, and other file types as well. I came across the WindowsMediaPlayerClass. It can be found in the COM library WMP.dll. However, it provided no features for fading or cross-fading songs. So, I wrote a more advanced wrapper class for it that uses WindowsMediaPlayerClass objects to fade and cross-fade songs.

Using the code

To use my code, download the source files and add the Media Player.cs file to your existing/new project. Then you must add a reference to the COM library WMPLib. Its description is Windows Media Player, and the file name is wmp.dll. Finally, make sure the reference's attribute Embed Interop Types is set to false. This is necessary for VS2010, I am not sure about earlier versions.

The class uses two WindowsMediaPlayerClass objects to play files and to enable cross-fading. When you are using the class, it appears only as if there is one player though. With the exception of events, which I will describe later.

The code has five main methods: Play, Pause, Stop, Resume, and Fade. These are the only public methods. Play is fairly basic; if the player is paused, it resumes play. If the player is stopped, it plays the file specified. Depending on whether you have set fade to true, the player will either just use player one for playing without fading or cross-fading. However, if you want fading/cross-fading, the player alternates between the two internal players, fading them in and out as is relevant.

Pause simply pauses the current internal player. If a fade is specified, it starts the fade process. Stop does the same thing except it stops the internal player completely, making it lose its current position. Also, Stop will set the player state to stopped so the first subsequent call to Play will play the new specified file. The first call after Pause will make the player continue playing the current track from the last position. The first call to Play after Pause will call Resume, so Resume and Play can be used interchangeably. The final method Fade simply starts a fade from the current volume to a new specified volume.

The main code that is useful is Crossfade, which fades one song up and another down in a set period of time, thus creating a linear cross-fade effect. The code uses a timer ticking every 500 milliseconds to adjust the volumes of the two internal players by a small amount, specified before the cross-fade starts, each time a tick event occurs. The volume may be changed during a fade/cross-fade; however, a sudden jump in volume would be heard at the end of the fade/cross-fade if you do. It is advisable, therefore, not to change the volume during a fade/cross-fade.

The first chunk of code in CrossfadeTimer_Tick determines whether it is the start of a cross-fade. If it is, then it starts the new player at volume 0, ready to fade up. The code is as follows:

C#
if (CrossfadeTotalRunTime <= 0)
{
    switch (StoppingPlayer)
    {
        case Players.Player1:
            PlayingPlayer = Players.Player2;
            Player2.volume = 0;
            Player2.URL = Player2Song;
            Player2.play();
            break;

        case Players.Player2:
            PlayingPlayer = Players.Player1;
            Player1.volume = 0;
            Player1.URL = Player1Song;
            Player1.play();
            break;
    }
}

The next chunk runs while the cross-fade is occurring. It adjusts the volume of both the stopping and playing players, fading the playing up and stopping down. This is the cross-fade.

C#
else if(CrossfadeTotalRunTime < (CrossfadeTime * 1000))
{
    switch (PlayingPlayer)
    {
        case Players.Player1:
            {
                Player1.volume = (int)(CrossfadeVolumeAdjustment * 
                                 ((float)CrossfadeTotalRunTime / 1000));
                Player2.volume = (int)(Volume - (CrossfadeVolumeAdjustment * 
                                 (float)(CrossfadeTotalRunTime / 1000)));
            }
            break;

        case Players.Player2:
            {
                Player1.volume = (int)(Volume - (CrossfadeVolumeAdjustment * 
                                 ((float)CrossfadeTotalRunTime / 1000)));
                Player2.volume = (int)(CrossfadeVolumeAdjustment * 
                                 ((float)CrossfadeTotalRunTime / 1000));
            }
            break;
    }
}

The final chunk runs when the fade is over. It does not stop the stopping player, but lets it run till its media ends. Also, it makes sure the player's volume of the internal player is the same as the volume set by the user. This is the reason a change in volume during a fade/cross-fade will result in a sudden jump at the end of the fade. The final volume used is just set; if it is different, there is no smooth fade between the two volumes. To implement that, one would increase the apparent length of the cross-fade/fade, and would be harder to implement than not changing the volume in the first place.

C#
else if (CrossfadeTotalRunTime >= (CrossfadeTime * 1000))
{
    CrossfadeTimer.Enabled = false;
    CrossfadeTimer.Stop();
    InCrossfade = false;

    switch (PlayingPlayer)
    {
        case Players.Player1:
            Player1.volume = Volume;
            Player2.volume = 0;
            break;

        case Players.Player2:
            Player2.volume = Volume;
            Player1.volume = 0;
            break;
    }
}

The final thing to note is that events such as media-end are fired even if externally you have only just called Play. This is because separate events are fired for each player, but externally, they appear as one player, which sounds confusing, but is useful because, if say, you are playing a playlist of cross-fading tracks, you will still get the media-end event even after the next track has started playing. This allows easier programming of play counts and similar song attributes.

License

This article, along with any associated source code and files, is licensed under The Common Development and Distribution License (CDDL)


Written By
Student
United Kingdom United Kingdom
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionCould you give me a VB.NET code Pin
Tinhiuvanoinho24-Jul-11 0:25
Tinhiuvanoinho24-Jul-11 0:25 
GeneralMy vote of 5 Pin
Tinhiuvanoinho24-Jul-11 0:24
Tinhiuvanoinho24-Jul-11 0:24 
GeneralI used the MediaPlayer control for my degree project Pin
Sacha Barber18-Nov-10 6:33
Sacha Barber18-Nov-10 6:33 
RantThe appended zip has 0 KB :-( Pin
thelittleguy18-Nov-10 5:14
thelittleguy18-Nov-10 5:14 
AnswerRe: The appended zip has 0 KB :-( Pin
Ed Nutting18-Nov-10 6:02
Ed Nutting18-Nov-10 6:02 

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.