Volume for sound not consistent when calling string from localStorage - javascript

I have a function that is behaving in a way that i do not like, and i cannot identify why. The overall function works fine, and when the volume is changed using the range element somewhere else in the interface, that works too. But lets say if I set the object in localStorage to "0.6" it will play at the right volume, BUT every so often it behaves as if the volume is "1" or default(i think). I sent the variable to my console to see what it says and it behaves like there is nothing wrong. The audio still sometimes gives me default volume even though the console says it's the right number stored in LS.
Here is the JS to the function that fires my biting sound:
biteFunc: function () {
var snd, myAu;
myAu = localStorage.getItem("Au");
//the user uses a range input to set this value, works fine
snd = new Audio("../Audio/bite.wav");
//the file in the location i want it to be, works fine
if (!myAu || myAu === "0") {
return false;
//if the user sets the sound to "0", the function will not fire
}
if (myAu) {
snd.volume = myAu;
snd.play();
/*this works and the console shows that each time the sound is fired,
the correct volume is there. But sometimes(especially when tapping
the button quickly) the volume behaves like its default or "1"
even though the object console says the right volume
*/
}
}
-Could my function be firing without reading the volume and spitting out the default volume when that happens?
-I thought it to be a timeline issue so I set the volume inside of the conditional that detects myAu, still nothing.

Related

How can I trigger arrow-key according to the const 'value'?

Hi I know the title of my post is quite tricky, so let me talk about it in detail here. I'm working on html+js page that gets the orientation value from my smartphone. The two devices are connected through google firebase, and it gets the realtime orientation value when my smartphone is on that page. I'm having trouble with connecting this value with the function of triggering the arrow keys.
For example, if the beta value is more than 0, up-key is triggered, etc.
I'm trying to use this orientation value to trigger up, down, left, right keys to be pressed accordingly, but I couldn't find any clue for it. What I get from google or stackflow was usually about connecting functions with the keyboard-events, but what I'm trying to do is the opposite; triggering keyboard-events based on conditions of the orientation values.
I'd appreciate if anyone can give me some clues or quick examples, so that I can twick. Sorry that I couldn't link any jsfiddles or part of the code since it's already connected with my firebase!
p.s. the code part I'm showing below is the part I checked it's working! I checked the orientations values are valid.
const controlAlpha = document.querySelector("#alpha").innerText;
const controlBeta = document.querySelector("#beta").innerText;
const controlGamma = document.querySelector("#gamma").innerText;
betaControl = function(){
if (textBeta<0){
console.log("beta under 0");
}
else{
console.log("beta over 0");
}
}
betaControl();

Adding Audio with JavaScript: FireFox and Chrome show they're playing, but I'm not receiving any sound

My peer and I have a series of JavaScript objects which all have an audio property. The value of that property is a string which provides the relative path to where that audio file is stored on our server.
I wrote a JavaScript function which references those objects and plays their audio files when a new object loads. Everything seemed to be working fine during testing. He just added new audio files today and messaged me that our project wasn't playing audio in IE -- but it still worked in FF and Chrome.
When I checked the error, I noticed IE was getting an invalid state error from the playAudio JavaScript function that I wrote. I made the assumption the mp3 file didn't fully load, so IE was throwing the invalid state error because it couldn't execute the play() command on a file that wasn't available yet. So, tonight I added a media event listener to ensure the function didn't execute until the mp3 resource was available.
That fixed the IE issue, but now both Chrome and FireFox aren't playing sound. And by that I mean, they are receiving the mp3 resource, no errors are being thrown to the console, and they both show the audio icon on the browser's tab above the url bar as though media content were actually playing. It seems like they are playing, but I'm not getting sound through my actual speakers. I'm kind of at a loss as to why this is happening, and will have to look into it more tomorrow -- but I'm hoping someone here might know what could be the cause.
// The playAudio function pulls the audio file from the scenes object and only plays once.
// Afterward, the scenes object receives a new parameter, audio_played, which is set to true.
function playAudio(id) {
// check whether the variable currAudio has been defined.
// If it has, pause currAudio.
if (typeof currAudio !== 'undefined') {
currAudio.pause();
}
// check that the scenes object has an audio parameter
// and that the audio_played parameter is not true
if (scenes[id].audio && scenes[id].audio_played !== true) {
// create a new Audio object using the loaded scene's audio
// parameter and store it in the variable newAudio
var newAudio = new Audio(scenes[id].audio);
// wait for the audio file to load enough data
// to be played, then execute the nested scripts.
newAudio.addEventListener('canplay', function() {
// set newAudio to start at the beginning of the file.
newAudio.currentTime = 0;
// play the audio file
newAudio.play();
// add an audio_played parameter to the
// scenes object and set it's value to true.
scenes[id].audio_played = true;
// update the currAudio variable
var currAudio = newAudio;
}, false);
}
}

How to prevent users from affecting number of button clicked times

I have a game written in JavaScript and what it basically does is start a ten seconds timer and register the number of times the user is able to click on a certain button, before the timer elapses.
How the code works:
When a user clicks on the button, an element gets added to an array, using push function, then a different function returns the length of the array as the number of times clicked.
The problem with this:
If a user opens up the dev tools and alters the number of times an element is added to the array per click, this will change the outcome of the result.
My Approach:
What I decided to do is to store the length before I ran the push function and also after I ran the push function, then compare their differences and if it's greater than 1, it means something is not right. This seemed to work in my head until I wrote it down in code and discovered that if the user pushed multiple times before I checked the differences then it would go unnoticed. Please big brained guys, help me.
My code:
$('body').on('click', '.btn.z', function () {
// start listening
startCountingClicks()
})
var timerStarted = false;
var tc = [];
function startCountingClicks () {
$('.btn.z').html('ClickZed');
$('.Score').html('Your Score: '+gettc()+" clicks");
if (timerStarted == false) {
startTimer(10, $('#time'));
}
// user does multiple push before this function: startCountingClicks is called
var previous_length = tc.length; // get length before push
tc.push(1);
var new_length = tc.length; // get length after push
if (new_length - previous_length !== 1) {
console.log("fraud"); // this is supposed to catch a thief!!!
}
console.log(new_length+" "+previous_length);
timerStarted = true;
}
function gettc (){
// get number of clicks
return tc.length ;
}
A code that totally breaks this:
$('button').click(function(){tc.push(1); tc.push(1)})
EDIT:
I do not wish to protect against dev tools, though I am not against that method if it works. I just wish to get a better way of counting my clicks, a way that can't be affected by writing code on the dev tools.
You can't really stop people from doing stuff on the client side. It is pointless trying to prevent that. The best thing you can do is make sure whatever is sent matches what you expect on the server side.

jwplayer 6 seeking on element in playlist doesn't work

We're using an external scrubber (a UI element that is not the default seek bar) for seeking (via jquery ui draggable) and it is not updating the jwplayer when it should be.
Synopsis of our code:
$('#scrubber').draggable({
// ...
stop: function (event, ui) {
$('#scrubber').draggable('enable');
var intSecFromEnd,
intSeek,
intTotalTime = 0,
intScrubPosition = ui.position.left,
intScrubTime = intScrubPosition;
// Find which video in the playlist to use
$.each(playlist, function (i, obj) {
intTotalTime += parseInt(obj.duration);
if (intTotalTime > (intScrubTime)) {
intSecFromEnd = intTotalTime - parseInt(intScrubTime);
intSeek = Math.floor((parseInt(obj.duration) - intSecFromEnd));
jwplayer('videoPlayer').load(playlist);
jwplayer('videoPlayer').playlistItem(i);
jwplayer('videoPlayer').seek(intSeek);
jwplayer('videoPlayer').pause();
/*
Play the video for 1 second to refresh the video player, so it is correctly displaying the current point in the video
Does not work either
*/
// setTimeout(function () {
// jwplayer('videoPlayer').pause();
// }, 1000);
return false;
}
});
}
});
You'll notice the key bit:
jwplayer('videoPlayer').load(playlist);
jwplayer('videoPlayer').playlistItem(i);
jwplayer('videoPlayer').seek(intSeek);
jwplayer('videoPlayer').pause();
When i put this into the console directly with an integer value where intSeek is it works exactly as it should, so I'm puzzled where the disconnect might be.
variation (that only works one one item in the playlist)
This works on the first member of the playlist only because the seek() function is defaulted to element 0 in the playlist.
jwplayer('videoPlayer').load(playlist);
jwplayer('videoPlayer').seek(intSeek);
jwplayer('videoPlayer').pause();
Naturally, it would stand to reason that jwplayer('videoPlayer').playlistItem(i) would retrieve the item at the index we want and, according to the docs, should:
Start playback of the playlist item at the specified index.
but, as this is effectively what is in the first example, it doesn't work.
Notes
When triggering the .seek() method externally from the player, the onSeek() method never gets fired by the jwplayer.
putting in the following, the jwplayer onReady event never gets fired. jwplayer(strVideo).playlistItem(i).onReady({ console.log('ready'); });
we're trying onPlaylistItem(index).seek(seconds) but this doesn't works.
This work only on active playlistitem and -of course- only about first file.
We're trying to use a pre-loaded playlist with seek button for every item of playlist.
We use a playlist with more files and the user can go to a specific file and second clicking a button that call:
jwplayer().onPlaylistItem(<index_file>).seek(seconds);
This jump to the seconds but not to the correct playlist item.
With a previuos test using "playListItem" player jump to the correct file but start from beginning and not seek to seconds. (but work only in html5 mode and not with flash).
Now we've tested this code
<a onclick='var only_once =false;jwplayer().playlistItem(1);jwplayer().onPlay(function () {
if (only_once == false) {
only_once = true;
jwplayer().seek(60);
}
});' class="btn">HLS play 2nd file at 1 min</a>
but this solution works only in Flash mode and not in html 5 mode player!

JS .play() on iPad plays wrong file...suggestions?

So, I am building a web app that has a div with text that changes on various user actions (it's stepping through an array of pieces of text). I'm trying to add audio to it, so I made another array with the sound files in the appropriate positions:
var phrases=['Please hand me the awl.','etc1','etc2','etc3'];
var phrasesAudio=['awl.mp3','etc1.mp3','etc2.mp3','etc3.mp3'];
And on each action completion, a 'counter' variable in incremented, and each array looks for the object at that counter
var audio = document.createElement("audio"),
canPlayMP3 = (typeof audio.canPlayType === "function" &&
audio.canPlayType("audio/mpeg") !== "");
function onAction(){
correct++;
document.getElementById('speech').innerHTML=phrases[correct];
if(canPlayMP3){
snd = new Audio(phrasesAudio[correct]);
}
else{
snd = new Audio(phrasesAudioOgg[correct]);
}
snd.play();
}
(the text replaces a div's HTML and I use .play() for the audio object)...usually works okay (and ALWAYS does in a 'real' browser), but on the iPad (the actual target device) after a few successful iterations, the TEXT continues to progress accurately, but the AUDIO will hiccup and repeat a sound file one or more times. I added some logging and looking there it reports that it's playing screw.mp3 (just an example, no particular file is more or less error prone), but in actuality it plays screwdriver.mp3 (the prior file, if there is an error, the audio always LAGS, never LEADS)...because of this I am thinking that the problem is with my use of .play()...so I tried setting snd=null; between each sound, but nothing changed...Any suggestions for how to proceed? This is my first use of audio elements so any advice is appreciated. Thanks.
edit: I've also tried setting the files with snd.src (based on https://wiki.mozilla.org/Audio_Data_API) and this caused no audio to play
for iPad you need to call snd.load() before snd.play() - otherwise you get "odd" behaviour...
see for some insight:
http://jnjnjn.com/187/playing-audio-on-the-ipad-with-html5-and-javascript/
Autoplay audio files on an iPad with HTML5
EDIT - as per comment from the OP:
Here https://developer.mozilla.org/En/Using_audio_and_video_in_Firefox you can find a tip on halting a currently playing piece of media with
var mediaElement = document.getElementById("myMediaElementID");
mediaElement.pause();
mediaElement.src = "";
and, following that with setting the correct src, load(), play() works great

Categories

Resources