Creating a jQuery UI Music Player - J Query

Problem
You need a music player that supports a common set of interface controls whether the music is being played by Flash Player or HTML5 audio or some other browser audio capability. You need the controls to be accessible, flexible, and theme able. A few basic features will do:

  • Play

  • Pause

  • A track bar to show and control the current point in the playback

  • A progress meter to show how much of the song is buffered

  • Volume

In addition to these basic features, you want one more feature. This music player needs to be scalable. The same interface should work at any size, whether resized by the browser, the user, or the application—all the way up to full screen.

Solution

Let’s build a music player using jQuery UI. We’re going to create the play and pause buttons using jQuery UI CSS Framework icons, and we’re going to create the track bar using the jQuery UI Slider plugin. The progress meter will be a jQuery UI Progress bar.
Finally, the volume control will be one more jQuery UI Slider. We’ll wrap these elements in a common container to provide for some nice widget the ming so that not only will each of our controls be the med but also our music player as a whole will be the med.

HTML5 audio

To keep things simple, we’re going to use a minimal subset of the HTML5 Media Element API. This is available in a number of recent browsers, such as Firefox 3.5. We’llimplement it as a compatibility layer so that another playback mechanism, such as Flash Player, could be substituted easily. For this recipe, we need the following from our audio API:

  • Start or resume playback (play)

  • Pause the playback (pause)

  • Get the length of the song (duration)

  • Get the current point that the playback is at (timeupdate)

  • Change to a certain point in the song (currentTime)

  • Get the volume the song is being played at (volumechange)

  • Change to a certain volume (volume)

Assuming an HTML5 audio element exists in the document, here’s the compatibility layer code:

The music player

Let’s use the CSS class mplayer for our music player. This will be the class for our main <div>, and will be used as a prefix in all our CSS rules and jQuery selectors. Here’s the CSS and HTML for our bare player:

I’ve set the width to 40 percent so that we can see we have a flexible player from the ground up. Just resize your browser and watch the player resize. This will be even easier to see when the player isn’t empty.
In addition to the mplayer class, our main <div>gets a ui-widget class. This is to ensure elements within it get styled appropriately.
An empty <div>and no JavaScript make for an invisible and quiet music player. Let’s add a play button and get our music on.

Play and pause button

There’s not yet a button plugin in jQuery UI. We can make do in the meantime with an a element and some semantically named jQuery UI CSS Framework icon classes:
Here’s the CSS:

Here’s the HTML:

With a couple CSS rules, we’re able to have one button serve as both the pause and the play button. With the previous CSS, only one icon, play or pause, will be visible at once, depending on whether our div.mplayer has the paused class. But the same HTML allows for a different designer to decide that both icons will be visible at once, but perhaps with different colors and opacity, depending on whether the song is playing.
Here’s the JavaScript:

Our button needs JavaScript to do the following:

  • Call the audio.play() or audio.pause() function, depending on whether the paused class is on div.mplayer when clicked.

  • Toggle the paused class on the .mplayer.

  • React to mouse and keyboard focus, hover, and blur. This is where a button pluginmight come in handy (there’s one being built), but for a simple icon button like this, it’s not too much code.

Don’t forget the return false; since our button is an <a>with an href of #.
With jQuery, jQuery UI, and the UI Lightness theme loaded,

Play-and-pause-button

Figure :(Play and pause button) shows

what our music player looks like with just the play/pause button.
If you click the play button, it should change to a pause button. If you click again, it should change back. Also notice that you get a hover effect, as well as a visual cue, when tabbing in and out of the button with the keyboard. If you’re in a browser that supports the audio element and it has a src attribute that points to a supported music file, you should even hear something when you click play.

Current and total time labels

The next step is to add two labels, one that shows the current point we’re at in the song and another that shows the total time in the song. These are pretty straightforward.
Here’s the CSS:

Here’s the HTML:

Here’s the JavaScript:

We’ve put the current time on the left and total time on the right, leaving room in the middle for the track bar

Current-and-total-time-labels

(see Figure :(Current and total time labels)).

We want the current time to always reflect where we are in the song, so we bind to audio’s time update notification event. The event itself doesn’t give us the currentTime. For that, we go to the audio.currentTime property.We need a small function to format it as minutes:seconds, since times in the audio layer are in seconds.

Slider track for song position

Now we’re getting somewhere. Next is our track bar. It consists of a simple <div>, but we’re going to give it a track and handle by calling .slider() on it. We’ll use Slider’s range: 'min' option so that the region between 0:00 and the current time will be shaded. Oh yeah, and we have to set max to the duration of the song, in seconds. So if it’s a 3.5-minute song, we’ll set max to 210. No calculations are needed, because audio.duration already gives us the total number of seconds in the song. The other defaults for Slider work for us here: max: 0, step: 1.
Here’s the CSS:

Here’s the HTML:

Here’s the JavaScript:

Slider handles are center aligned, meaning at the min value, the left half of the handle goes beyond the left of the slider, and when at the max point, the right half of the handle goes beyond the right of the slider. We already made the handle skinnier than norma land got rid of the left border so it sticks to the range a little better. But we still need a little bit of adjustment when near the min. That’s what these lines are for:

Also, in the slide callback, we’re checking whether the value is valid before telling theaudio to go to that point. This is a case where the user is dragging the slider around,and we need to move around the playback point in the song. This allows for “scrubbing.”
If we only handled this in the change callback, the audio wouldn’t change until the user let go of the mouse, after clicking or dragging the slider handle to a new point.

Slider-track-for-song-position
Figure :(Slider track for song position) shows the slider we’ve created.

Progress bar in track to show buffering

Get ready for some fun. What if I told you we can call two different jQuery UI pluginson the same element? It works really well in this case. We already have a track bar,which we created as a <div>, calling .slider() on it. In addition to adding a ui slider class to our .track element, the jQuery UI Slider plugin created and appendeda couple elements to our track, a slider handle (.ui-slider-handle) and a slider range(.ui-slider-range), since we specified range: 'min'. Fortunately, that’s as much as it did to our <div>. It’s still a <div>, and it’s still our <div>. So, let’s dual-purpose it and call .progressbar() on it. This will make it so our buffer display runs behind the range display that shows our current time. Check this out.
Here’s the CSS:

Here’s the JavaScript:

There’s no HTML, since we’re reusing the .track element from the previous section. Oh, and in case you hadn’t noticed, that buffering code is totally bogus. Well, it works;it just isn’t representing a song being buffered, only simulating it. But it works great! If you really had a music resource that was coming in and buffering and your audio API supported notifying you of that, you’d bind to the event and set the progress bar value as shown earlier, between 0 and 100. Unlike Slider, you can’t specify a custom max for progress. But that makes sense, right? Progress goes from 0 percent to 100 percent.
OK, so we have got some proof-of-concept code here. When the page loads, the buffer progress will race away as if the file is flying in, but not quite as if it’s local. It’s fun to watch.

Progress-bar-in-track-to-show-buffering

Figure :(Progress bar in track to show buffering)shows

the progress bar we’ve created. The other thing that’s bogus about our buffer progress indicator? Since it isn’t a real buffer progress, you can jump beyond it. What will happen? That depends on your audio API and backend. So, if youdon’t have a buffer progress or don’t want or need one, skip this. Or leave it in for looks.

Volume slider

So, we need to add a volume control. Slider is a good fit. Drag from volume: 0 to volume:
1 and set step to 0.01:

Bam. Why not? Well, that would certainly work. But it would take up a bit of space.And orientation may be an issue. If we lay it out horizontally, which is the default for Slider, we’re competing with the track for horizontal space. Not to mention we’re“lop siding” our player. OK, so should we add orientation: 'vertical' to the slider options? Well, that too would work, but it would mean our player is now 100 pixel stall and only in order to fit the volume control. The rest of the controls need just over30 pixels. There has to be a better way.
There is. Keep the volume slider’s bar hidden when not in use. We’ll keep the slider handle visible and add a little speaker icon to it. Then we’ll hide the rest by setting the height of the control to 0. When the user hovers over the handle, we’ll set the height to 100 pixels. On mouse out, we’ll remove that, and it will go back to 0 height. Also,with its container positioned absolutely in a relative wrapper, it won’t affect the overall height of the player when it is fully visible.
There’s one problem. When the bar appears, let’s say the volume is at 0.10, or 10percent. That would mean the handle is near the bottom. Should the handle jump down? Or the bar up? And what about while the user slides it? What if they drag from10 percent up to 90 percent and then let go? It would jump back down when the bar hides again. Yuck.
So, here’s what we’re going to do. We’re going to keep the handle fixed the whole time.
The user will drag up for increase and down for decrease. The bar, including the range:"min" shaded portion below the handle, will move down and up accordingly.
Here’s the CSS:

Here’s the HTML:

Here’s the JavaScript:

While it’s being dragged, we’re adjusting the negative margin-top of the bar in inverse
proportion to the current value, keeping the handle static. This happens here:

Volume-slider

Figure : shows the volume slider in our player
This interaction requires recognizing that you’re not dragging the bar, which is what’s moving, in the opposite direction of your mouse. But meanwhile, your mouse, the size of the shaded range, and your volume do move in logical concert: down for down, up for up. Also, if you prefer, you can hover so that the bar appears, move your mouse to the position on the bar where you want to set the volume, and click.

Widget background and top styling

OK, let’s add a couple elements with jQuery UI CSS Framework classes to style the player in a way that matches the controls within it:
Here’s the CSS:

Here’s the JavaScript:
Here’s the HTML:

Here we’re using opacity and layering to squeeze a couple more shades out of any jQuery UI theme.

Widget-background-and-top-styling

Figure :(Widget background and top styling) shows

the finished product:

jQuery-UI-media-player-in-a-few-different-ThemeRoller-themes

Figure :(jQuery UI media player in a few different ThemeRoller themes)


All rights reserved © 2018 Wisdom IT Services India Pvt. Ltd DMCA.com Protection Status

J Query Topics