GithubHelp home page GithubHelp logo

alexanderkatz / html5-audio Goto Github PK

View Code? Open in Web Editor NEW
35.0 35.0 22.0 600 KB

Custom HTML5 audio interface. I am using javascript to interface with the HTML5 audio tag, so I can create a player that has a standard appearance across multiple browsers.

CSS 41.37% JavaScript 48.97% HTML 9.66%

html5-audio's People

Contributors

alexanderkatz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

html5-audio's Issues

Timeline only tracking after playing once

My timeline just works after i played the audio once till the end.
After pressing play button again, the timeline works fine for me.

But initially it isnt working.
Any idea?

DOMContentLoaded bummed my code hacks.

This code of yours prevented my additional hacks (such as volume control ) from working:

document.addEventListener("DOMContentLoaded", function(event) {
/* DOMContentLoaded*/
});

When I deleted it, my stuff worked. Then again, I'm not savvy at coding. Perhaps my hacks could have worked with your code had I known how to make it work.

added stuff, but would like duration and current times (00:00 / 00:00) and colored audio progress like the (new) volome track has.

You can see it working here with additional styling, looping, and volume control: https://aleks-volume.blogspot.com/
I've hidden the player until it gets appended. However, it can stay visible and un-appended and work just fine.

These are a few of the mechanics I changed:
(These are links to music set inside a list, but the code isn't showing it)

<li><a src='http://www.alexkatz.me/codepen/music/chooseyourweapon.mp3'> Choose</a></li>
<li><a src='http://www.alexkatz.me/codepen/music/interlude.mp3'>Interlude</a></li>
<li><a src='http://www.alexkatz.me/codepen/music/scriptures.mp3'>Scriptures</a></li>

<audio></audio>

var duration = audio.duration; // and all the rest of the "music"s have been changed to "audio"s as well.

var links = document.getElementsByTagName('a');
var link = links;

audioplayer.style.visibility = 'hidden';

// Actions that happen when a link is clicked:

var links = document.getElementsByTagName('a');
var link = links;
for (var m = 0; m < links.length; m++) {
link[m].addEventListener('click', function() {

// Add the classes 'current' and 'visited' to the selected link:
var selected = document.getElementsByClassName('current');
if (selected.length > 0) {
selected[0].className = selected[0].className.replace('current', '');
}
// To work, 'visited' must precede 'current':
this.className += "visited current";

// Attach the player to a 'li' tag. If attached to an 'a' tag,
// the player takes on the tag's styling.
var li = this.parentNode;
li.appendChild(audioplayer);
audioplayer.style.visibility = 'visible';

// Get audio source from an 'a' tag instead of an 'audio' tag:
var source = selected[0].getAttribute('src');
audio.src = source;
audio.play();
})
}; // Actions are finished for the selected link.
};
audio.onplaying = function(){
// remove play, add pause
pButton.className = "pause";
};
// At audio file's end, reset timeline to the beginning.
audio.onended = function(){
playhead.style.marginLeft = "0px";
pButton.className = "play";
};

Improved version usable with absolute/relative and fixed positioning and scrollable and resizeable windows

The original example cannot be used when positioned absolute, relative or fixed in a standard Dom document instead of an iFrame (as is used in the demo). All the calculations used for positioning the elements are done relative to the parent element. Because of this the demo immediately breaks when absolute, relative or fixed positioning are used in the CSS.
I added a function to get the right position (cross browser) and to make all caculations work (even when users zoom in or out and the pixel size varies the real offset is calculated exactly right) . In this way it can also be used in scrollable and resizeable windows if some event listeners and an update routine are added for that purpose (see remarks in the adapted script below). I also added some conditions to avoid errors in case audio.src is empty when the script is initialized.
e.pageX is replaced by e.clientX for wider browser support!
I just hope it will save somebody a lot of time!!!
Maybe Alex can adapt the demo with the below code: ( the last function has been added and some variables in the script have been adapted to use the result values of that function)
HAVE FUN!!!!!

function showControls() { 

	/*---------------------------------------------------------------------------------------------------------------------------------------
	Script source; http://alexkatz.me/posts/building-a-custom-html5-audio-player-with-javascript/
	Icon source: Icon source: https://www.iconfinder.com/search/?q=play&maximum=16
	REMARKS !! : 
		- By adding the function 'getPosition(el)' the script also works fine for absolute/relative and fixed positioning.
		  Also scrolling and window resize can be used by adding listeners for those events and updating the position for them.
		- e.pageX is replaced by e.clientX, this works just as well, with e.clientX the script is also stable and this has the advantage of a
		  wider browser support. e.pageX is not supported by IE 8 (only from IE 9 and up). Although there is an issue with e.clientX in lower
		  IE versions from 7 and down described at http://help.dottoro.com/ljsqnefp.php in the following way:
			  In Internet Explorer earlier than version 8, the clientX property retrieves the position of the mouse in physical pixel size,
			  while from version 8, it returns the position in logical pixel size. What does it mean?
			  If the browser is not at the normal zoom level (the user has the ability to zoom in or out a web page: CTRL and +, CTRL and -),
			  the clientX property works differently from version 8 than in earlier versions. The position of the mouse pointer is calculated
			  in the default pixel size in Internet Explorer before version 8 even if the current pixel size in the document is different.
			  From Internet Explorer 8 and in Firefox, Opera, Google Chrome and Safari, the position is calculated in the current pixel size.
			  So then e.clientX is not influenced by user zooming.
	----------------------------------------------------------------------------------------------------------------------------------------*/
	
	// get references to variables
	var audio = document.getElementById('audio');	 				 		// audio object
	var pButton = document.getElementById('pButton'); 				 		// play button
	var playhead = document.getElementById('playhead');				 		// moving playhead
	var timeline = document.getElementById('timeline');				 		// timeline for playhead																			
	var timelineWidth = timeline.offsetWidth - playhead.offsetWidth; 		// timeline width adjusted for playhead
	
	if (audio.src) {														// 'duration' is globally declared (see top of script) to keep track of 
		duration = audio.duration;											// the duration of the audio clip ( 'zero' if audio.src = '' )
	}																		// duration is constantly updated by EventListener "canplaythrough"
																			// !!!!!! in case of changing multiple media sources !!!!!!!; be sure to
																			// get the new value of 'audio.duration' every time 'audio.src' is changed
	  
	// timeupdate event listener
	audio.addEventListener("timeupdate", timeUpdate, false);
	
	// makes timeline clickable
	timeline.addEventListener("click", function (event) {
		moveplayhead(event);
		if (!duration == 0 || !duration == NaN) {							// this is to avoid errors if no audio is loaded; audio.src=''
			audio.currentTime = duration * clickPercent(event);
		} 
	}, false);
	
	// returns click as decimal (.77) of the total timelineWidths
	function clickPercent(e) {
		return (e.clientX - getPosition(timeline).x) / timelineWidth;
	}
	
	// makes playhead draggable 
	playhead.addEventListener('mousedown', mouseDown, false);
	window.addEventListener('mouseup', mouseUp, false);
	
	// boolean value so that mouse is moved on mouseUp only when the playhead is released 
	var onplayhead = false;
	
	// mouseDown EventListener
	function mouseDown() {
		onplayhead = true;
		window.addEventListener('mousemove', moveplayhead, true);
		audio.removeEventListener('timeupdate', timeUpdate, false);
	}
	
	// mouseUp EventListener
	// getting input from all mouse clicks
	function mouseUp(e) {
		if (onplayhead == true) {
			
			moveplayhead(e);
			window.removeEventListener('mousemove', moveplayhead, true);
			
			if (!duration == 0 || !duration == NaN) {						// this is to avoid errors if no audio is loaded; audio.src=''
				audio.currentTime = duration * clickPercent(e);	
			} 
			audio.addEventListener('timeupdate', timeUpdate, false);
		}
		onplayhead = false;
	}
	
	// mousemove EventListener
	// Moves playhead as user drags
	function moveplayhead(e) {
		
		var newMargLeft = e.clientX - getPosition(timeline).x;
		if (newMargLeft >= 0 && newMargLeft <= timelineWidth) {
			playhead.style.marginLeft = newMargLeft + "px";
		}
		
		if (newMargLeft < 0) {
			playhead.style.marginLeft = "0px";
		}
		
		if (newMargLeft > timelineWidth) {
			playhead.style.marginLeft = timelineWidth + "px";
		}
		
	}
	
	// timeUpdate synchronizes playhead position with current point in audio 
	function timeUpdate() {
		
		var playPercent = timelineWidth * (audio.currentTime / duration);
		playhead.style.marginLeft = playPercent + "px";
		
		if (audio.currentTime == duration) {
			
			pButton.className = "";
			pButton.className = "play";
			
		}
		
	}
	
	// gets audio file duration
	audio.addEventListener("canplaythrough", function () {
		duration = audio.duration;  
	}, false);
	
	// getPosition(el) ; cross browser function to get an element's exact (absolute) position from the entry
	// point(=html tag) of the DOM document. This is used to make the controls available in any positon.
	// see document "Javascript; Get an Element's Position Using JavaScript.docx"
	// N.B. ===>Deal with the page getting resized or scrolled: add the 2 below event listeners
	// 				window.addEventListener("scroll", updatePosition, false);
	// 				window.addEventListener("resize", updatePosition, false); 
	// and a function like this:
	// 			function updatePosition() {
	// 				add your code to update the position when your browser
	// 				is resized or scrolled
	//			}
	
	function getPosition(el) {
	  var xPos = 0;
	  var yPos = 0;
	 
	  while (el) {
		if (el.tagName == "BODY") {
		  // deal with browser quirks with body/window/document and page scroll
		  var xScroll = el.scrollLeft || document.documentElement.scrollLeft;
		  var yScroll = el.scrollTop || document.documentElement.scrollTop;
	 
		  xPos += (el.offsetLeft - xScroll + el.clientLeft);
		  yPos += (el.offsetTop - yScroll + el.clientTop);
		  
		} else {
			
		  // for all other non-BODY elements
		  xPos += (el.offsetLeft - el.scrollLeft + el.clientLeft);
		  yPos += (el.offsetTop - el.scrollTop + el.clientTop);
		  
		}
	 
		el = el.offsetParent;
		
	  }
	  return {
		x: xPos,
		y: yPos
	  };
	}
	
}

Multiple Audio Players

Hey ๐Ÿ™‚,

I wanted to have multiple audio players like this
image but the second doesn't seem to work. I changed the ID of the second audio player and added it to a querySelector in the JS file, like this: var music = document.querySelector('#music', '#music1'); // id for audio element var duration; // Duration of audio clip var pButton = document.getElementById('pButton'); // play button var playhead = document.getElementById('playhead'); // playhead var timeline = document.getElementById('timeline'); // timeline and my second audio looks like this in the HTML: `


	<div id="wrapper">
		<!--Audio Player Interface-->
		<div id="audioplayer">
			<button id="pButton" class="play"></button>
			<div id="timeline">
				<div id="playhead"></div>
			</div>
		</div>
	</div>`

If someone could shed some light, that would be great! :)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.