Click here to Skip to main content
Click here to Skip to main content

Media Player Class

, 18 Nov 2010 CDDL
Rate this:
Please Sign up or sign in to vote.
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:

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.

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.

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)

Share

About the Author

Ed Nutting
Student
United Kingdom United Kingdom
Hi,
 
I am Edward Nutting, born March 1996 and I am currently an Electrical and Electronic Engineering undergraduate at the University of Bristol, UK. I've been self-teaching programming since I was eight years old and have dabbled in many different areas from web development (where I had my own advertising startup) to low level operating system stuff (my current project Fling OS).
 
The articles and code on this profile are some of my early work (from when I was aged about 13 to 16) but despite my young age, it has been well received by CodeProject users. My more recent work has been for companies or on projects hosted on GitHub, CodePlex or BitBucket.
 
I keep an eye on many things techy and am open to any and all ideas, so please feel free to contact me if you think I can help! Smile | :)
 
Cheers,
Ed Nutting
Follow on   Twitter   LinkedIn

Comments and Discussions

 
QuestionCould you give me a VB.NET code PinmemberTinhiuvanoinho24-Jul-11 1:25 
GeneralMy vote of 5 PinmemberTinhiuvanoinho24-Jul-11 1:24 
GeneralI used the MediaPlayer control for my degree project PinmvpSacha Barber18-Nov-10 7:33 
RantThe appended zip has 0 KB :-( Pinmemberthelittleguy18-Nov-10 6:14 
AnswerRe: The appended zip has 0 KB :-( PinmemberEdMan19618-Nov-10 7:02 

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

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

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.1411023.1 | Last Updated 18 Nov 2010
Article Copyright 2010 by Ed Nutting
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid