Creating volume slider for Hype audio element


(Trey Yancy) #1

I need to set up a volume slider for controlling standard Hype audio. Not being a JS guy, how do I do this? (As in “step one, two, tree”, rather than “use this code”.) Thanks.


Controlling Audio & Advanced Techniques (Play, Pause, Rewind, Volume control)
#2

Because audio added to Tumult Hype is not an addressable object in JavaScript, there isn’t a way to set the volume for it specifically. You would need to create an audio element and follow the instructions at the bottom of the post you originally replied to:

Hype also uses the Web Audio API for browsers that support it, and falls back to the <audio> element for those that do not. We’d like to improve this support in the future.


How to add sound bites on timeline
#3

Hi Trey!

Here is the Project file I will be referring to: Volume Control.hype.zip (276.0 KB)

Project Demo here.

I am assuming You have read the basics of the linked topic Daniel posted above.

1) We have an audio element that has an id of “prologue”.

We initialize the “audio1” variable in the function below which is called by the “On Scene Load” handler.

	function initAudioVar(hypeDocument, element, event) {
	audio1 = hypeDocument.getElementById('prologue');
	//global var for audio element with id of 'prologue'
}

**2) The "Play~"Pause" function.**
function playSound(hypeDocument, element, event) {
	 	// "audio1" variable set by "initAudioVar()" function;
	 	// called by "On Scene Load" handler
	 		 	
           // set the appropriate label for the "Play"~"Pause" button
	 	if (audio1.paused) {
	 	element.innerHTML = 'Pause';
	 	}
	 	else {
	 	element.innerHTML = 'Play';
	 	}
	 	
		(audio1.paused) ? audio1.play() : audio1.pause();
		//toggles Playing~Pausing of Audio
}

So far so good - pretty straightforward in terms of ease of code reading; not much required.


3) The “Slider Volume Control”.

The next section is for the most part a cut & paste operation. This code was originally posted by @h_classen, to which I’ve made minor changes for this particular project. Link to post here.

There are only a couple of things to understand in order to adapt the function below to your own needs (for this volume control demo).

The length of the slider in my demo is 100 pixels - no accident. I wanted a number that translates easily to control the volume. A slider position of 100 pixels = 100 percent sound volume. 50 pixels = 50% sound volume. The computer does the math of course, but working in logical units is easier for me to visualize.

An Array’s positioning starts from “0”, then followed by “1”, “2”, etc.
So the third position in an array of c = [5, 8, 15, 8] - a value of “15” - is by accessed by c = [2]; c = [3] would be equal to a value of “8” in the array.

“nX” is the only variable we really need to work with for our volume control; it provides the pixel value along the horizontal “slider” line. So, as referenced above, a 100 pixel width line with a value of 35 pixels along the slider will translate (in this demo) to a volume of 35% of full (100%). “nX” is derived from the the second position in the array, c = [1], “c = [0, 100, 8, 8];” at the top of the code just below. This “c = [1]” value is equal to 100, matching the 100 pixel width of the slider.

If You want to work with a slider with a width of 200 pixels then the array at the top of the code is the place to make that change… e.g. “c = [0, 200, 8, 8];”. You also would need to change the math in the code referenced just below for the volume setting.

At the very bottom is where we set the actual volume “audio1.volume= (nX * .01);

As commented in the code below:
Multiplying “nX” by “.01” takes the pixel setting and renders it to a number that works for audio setting
(0 - 1.0). So if “nX” = 50 pixels, then 50 * .01 = “0.5” or a volume setting of 50%.

In summary of this “Slider Volume Control” section:
There only two places You need to change the code for customizing the volume slider’s width~length:

  1. In the “c = [0, 100, 8, 8];” array at the top of the code (change the “100” value).
  2. At the very bottom: audio1.volume= (nX * .01); needs adjusting if the width is different than “100”.


function sliderVolume(hypeDocument, element, event) {
c = [0, 100, 8, 8];// Array. Slider control constrained by box [left, width, top, height]

/* Array positioning starts with "0"
So an array position of c[1] would be = to "100", or the width value;
c[2] would be (the first) "8" or the top value */

p = element.parentNode;
pX = p.getBoundingClientRect().left;
pY = p.getBoundingClientRect().top;
gX = event['hypeGestureXPosition'];
gY = event['hypeGestureYPosition'];

eW = element.getBoundingClientRect().width;
eH = element.getBoundingClientRect().height;

nX = gX - pX - (eW/2);
nY = gY - pY - (eH/2);

/* "nX" is what we care about for setting the volume.
It represents the location along the "x" axis of the slider
which is 100 pixels in length */


if(nX > c[0] && nX < c[1] && nY > c[2] && nY < c[3])
{
	element.style.left = nX + 'px';
	element.style.top = nY + 'px';
}
else if(nX > c[0] && nX < c[1] && (nY <= c[2] || nY >= c[3]))
{
    element.style.left = nX + 'px';
}
else if((nX <= c[0] || nX >= c[1]) && nY > c[2] && nY < c[3])
{
	element.style.top = nY + 'px';
}

audio1.volume= (nX * .01);

/* set the volume for the global variable "audio1";
multiplying by ".01" takes the pixel setting and renders it
to a number that works for audio setting (0 - 1.0).

So if "nX" = 50 pixels, then 50 * .01 = "0.5" or a volume setting of 50%. */
}

#4

Hi Trey!

Another approach that uses a symbol’s timeline to set the volume…
Project: VolumeControl_timeline.hype.zip (278.0 KB)

The initial set-up is similar in many regards to that described above, such as the “initAudioVar” & “playSound” functions; but the code for the volume slider itself is far less as it utilizes the “On Drag” action to constrain the slider’s motion, a symbol timeline and a wee bit of code to indicate where in the timeline the volume slider has been dragged.

The volume slider has been converted to a symbol called “VolumeSet” which has a timeline 5 seconds long. These seconds are translated to volume settings. So the volume slider dragged the equivalent of 1 second is quiet (20% of full volume), and the slider dragged all the way to the right (5 seconds on the timeline) is 100% volume. There is no reason the timeline couldn’t be 10 seconds long, or whatever - just keep an eye on the math to allow a translation to the JavaScript volume range.

Examples - as used in the “sliderVolume” function below:


3 seconds on the timeline multiplied by “0.1” (to translate to the JavaScript value range for volume, 0.0-1.0) which is = “0.3”. The “0.3” is multiplied by 2, for a setting of 60% of full volume. 5 seconds would be (5 * 0.1) = 0.5. Then (0.5 * 2) for a volume setting of 1.0 or 100%.

The following function, called by the “On Drag” action of the slider, tracks where the slider is on the timeline and then sets the volume (the variable “volumeSlider” is initialized in the “initAudioVar” function) :

function sliderVolume(hypeDocument, element, event) {
if (event['hypeGesturePhase'] == hypeDocument.kHypeGesturePhaseMove) {
		var volumeSetting = volumeSlider.currentTimeInTimelineNamed('Volume');	
		audio1.volume = ((volumeSetting * .1) * 2);
	
	}
}

That’s it.



Notes: What I do not like about this approach is the "On Drag" action which, especially on the first drag, is rather rough - the slider does not follow the cursor very well; though it improves after that.

While the first method posted above has more complicated code for the volume slider, it is smoother and it needs only two adjustments to customize to what is basically a “cut & paste” coding operation.