2

I'm trying to create own player for html5 audio by javascript.I've got the play,pause and volume option of htm5 audio player like:

<audio id="playe" src="song.ogg"></audio>
<div>
<button onclick="document.getElementById('playe').play()">Play</button>
<button onclick="document.getElementById('playe').pause()">Pause</button>
<button onclick="document.getElementById('playe').volume += 0.1">Vol+ </button>
<button onclick="document.getElementById('playe').volume -= 0.1">Vol- </button>
<button onclick="if(document.getElementById('playe').volume == 0){document.getElementById('playe').volume += 1.0;}else{document.getElementById('playe').volume = 0;}">Mute</button>
</div>

but how can I show the timeline there ? and is that the correct way for 'mute' option that I applied ?

-Thanks.

user1844626
  • 1,838
  • 7
  • 24
  • 37

1 Answers1

4

I assume you already know about the controls attribute and are choosing to create your own player? (View on JSFiddle)

If that's the case, read on...

How can I show the timeline?

I can think of two possible elements that would be ideal to use (on semantic grounds). The first would be the <input type="range"> element. View it here. You could target the element and set the values of the attributes using the currentTime and duration properties of the DOM element in Javascript.

The 5.1 specs say that this element comes 'with the caveat that the exact value is not important'. This probably isn't true for a video timeline, right? We definitely want our users to know the exact value. Nevertheless, that phrase in the specs give an explanation for why there's no ability to display the associated number of the element.

But we can, of course, display the time in a separate element, sort of like how Youtube doesn't display the time over the slider (unless you're hovering it). For this, we should use the output element. It's meant to be used 'for the result of a calculation', and, implicitly, the result of the calculation of another Html element. This is why it has the for attribute; it 'binds' it to the value of another element. In this case, we'd make the for our identifier of the range input.

For a little example of what I just wrote, I suggest you check out Chris Coyier's implementation of this idea. In summary, the Html he uses looks like:

<input type="range" name="foo">
<output for="foo" onforminput="value = foo.valueAsNumber;"></output>

and then he just styles the output with css to look nice. Nifty, huh?

Random note: It happens that the DOM element of the audio element is a child of the HTMLMediaElement, and over at the MDN you'll find a good list of all of the properties and methods of these things. This will surely be useful in building your own audio player. The HTMLAudioElement itself doesn't add much to its parent.

The problem with the range input is that it's an Html widget that most definitely utilizes the Shadow DOM, so styling it is pretty difficult right now (in fact, impossible in every browser except maybe Chrome).

If you really need to style the appearance of the range input, the most control you'll get is by using a Javascript widget that mimics the behavior. You know, throwing a bunch of Html elements together such that they look like a range input, and then wiring functionality into it with Js.

& if this thing is for personal use or a team using Chrome or Safari, you could make this a Web Component, which would be the best, and most future-proof way to go about this. But the Shadow DOM is still poorly supported.

Is that the correct way to mute?

HTMLMediaElements don't have a mute method, so, yes, you'll need to write a little bit of script like that to do it.

I'd probably change how your script works, though. I think users are used to the volume 'saving' when they mute, then returning to that value when they unmute. Right now, your script doesn't have this behavior. I'd definitely add that in!

Other thoughts...

Inline Javascript is generally frowned upon. Why not move everything into an external file, or at least a script tag, so that it's more manageable? You could even write a plugin to make it all modular and stuff.

jamesplease
  • 12,547
  • 6
  • 47
  • 73
  • thanks for your advices. yes, I'll create a javascript function for that, and will add a variable to store the current volume.by the way can you tell me is there any way to add a lighting display with this player like winamp ? – user1844626 May 31 '13 at 02:15
  • Sorry, a lighting display? Can you explain that a bit better? – jamesplease May 31 '13 at 02:16
  • the light bars which ups and downs according to the frequency of music. can that be added there ? – user1844626 May 31 '13 at 02:25
  • Yes, it's possible, but that's a much more involved project than this basic stuff. I refer you to [this SO question, and it's great answers](http://stackoverflow.com/questions/3351147/html5-audio-visualizer), to learn more about how to do that. The answers link to open source examples of visualizers ([like this one](https://github.com/jsantell/dancer.js)) that you can learn from. Do note: it isn't simple! – jamesplease May 31 '13 at 02:29