I have a control panel for restaurants and it plays an alert sound when an order is given. The problem is that when the control panel tab is not the active tab in Chrome (it's also same for Firefox) the alert sound doesn't play. After clicking the tab it plays the sound.
I see some sites (Facebook Chat, Cloudstats.me server alert, ...) play sound even if they are in inactive tab, so what is the workaround for this problem?
Had a similar thing happen to me as well, we were trying to play a marketclock when the stock market opened and closed for the day. The issue we had was we tried to load the mp3 then play it when the condition is met. So originally I had.
var bell;
// Update the clock, countdown, and tooltips as needed.
function updateClock() {
service.getMarketDate(function(data) {
if (data.soundMarketBell) {
if (!bell) {
bell = new Audio('/sounds/marketclock.mp3');
}
bell.play();
}
});
}
var intervalId = $interval(updateClock, 1000);
By moving the resource loading to happen on page load and then just calling the Audio.play it fixed the issue
var bell = new Audio('/sounds/marketclock.mp3');
// Update the clock, countdown, and tooltips as needed.
function updateClock() {
service.getMarketDate(function(data) {
if (data.soundMarketBell) {
bell.play();
}
});
}
// check for a time update every second
// to balance accuracy with performance
var intervalId = $interval(updateClock, 1000)
Browsers restrict loading resources when a tab is inactive
There's also the possibility that the audio wouldn't play because of browsers Autoplay policy.
For example, in Chrome the audio won't play until the user actively click the web page.
you may find the full list here:
https://developers.google.com/web/updates/2017/09/autoplay-policy-changes
Related
Tested on Chrome/Firefox/Edge. I'm working on Win10 with VS code and the "Live Server" extension.
The page loads, first audio file(.mp3) plays, then different elements appear with Jquery delays, etc. Upon a certain < ul > fading in, the second audio file plays.
With "Live Server" 's auto-reloading on save feature or by clicking on my navbar's link to the same page (testing purposes), the sounds and Jquery functions work fine, but if I refresh with the browser itself, the sound files don't play again.
I tried solutions found on google, like setting currentTime, onLoad, but they didn't really answer a similar problem, the most success I've had was achieving the same results I had from the start.
I'm just starting to learn JS and Jquery, so I'm sorry if the code is messy.
<script type="text/javascript" src="script/jquery-3.5.1.min.js"></script>
<script type="text/javascript" src="script/main.js"></script>
<script>
var audio1 = $("#mantra")[0];
var audio2 = $("#wind")[0];
audio1.play()
$("document").ready(function () {
$(".choix").hide() // .choix is the class of fig1, fig2, fig3, fig4
$("#fig1").delay(9500).fadeIn(3000);
$("#fig2").delay(9550).fadeIn(3000);
$("#fig3").delay(9600).fadeIn(3000);
$("#fig4").delay(9650).fadeIn(3000);
$("#tagline").hide().delay(2000).fadeIn(1500)
.delay(1500).fadeOut(2000).queue(function(n) {
$(this).html("<br> Start here");
n();
}).delay(700).fadeIn(2000);
$(".textNav").hide().delay(800).fadeIn(1500);
});
$("#wind").stop("true").delay(9400).queue(function() { //9400ms delay to start just before fig1+
audio2.play()
});
});
</script>
In cases when the audio is not playing, check the console and you will find an error stating
DOMException: play() failed because the user didn't interact with the
document first.
This is because browsers don't allow music autoplay on page-load. It is necessary for the user to make some interaction (click, tap, etc.) with the window before playing the audio.
Source
I like listening music with a Chrome tab on Youtube while I'm working, but every hour the music stops and a message "Are you still there?" is displayed on it.
Yes, I'm still there, like everyday, 7 times a day :)
So I installed a Chrome extension called "Custom Stylesheet & Script" to run this simple JavaScript stuff:
setInterval(function(){
let overlay = document.querySelector('iron-overlay-backdrop');
if(overlay) overlay.click();
}, 1000);
This works great, but only if I am on the YouTube tab. If I'm working on another one the music eventually stops and I have to click on the YT tab for this JavaScript to run (so not really a win after all).
I found some posts mentioning that setInterval in inactive tabs have a low priority and will only trigger once or twice a second, in my case they don't trigger at all.
Thanks for any hint on what to look at :)
After some tests, I found that the click on the "Ok" button to confirm was disabled by YouTube if the chrome tab isn't active, the setInterval was perfectly working after all.
If anyone is interested, I tried the MutationObserver method suggested by wOxxOm, and instead of clicking the confirmation button I just reload the page.
Here is the code I'm using now:
if(-1 !== window.location.host.indexOf('youtube')) {
document.addEventListener('DOMContentLoaded', (event) => {
let popupContainer = document.querySelector('ytd-popup-container');
let observer = new MutationObserver(function(mutationsList) {
let confirmButton = popupContainer.querySelector('.yt-confirm-dialog-renderer paper-button');
if(confirmButton){
// confirmButton.click();
document.location.reload(true);
}
});
observer.observe(popupContainer, {childList: true});
});
}
I'm currently using VideoJS in a Rails application (where there is a video player on every page) to display videos and I'm encountering a very strange problem:
The player works perfectly fine on the first page I visit but if I play the video and visit another page, the video from the first page keeps playing in the background even though the page isn't open anymore (you can hear the audio) and the video on the page you visited doesn't initialize properly (options aren't applied which means the video can't be played because controls are an option) and the console reads VIDEOJS: WARN: Player "player" is already initialised. Options will not be applied.
How to I get VideoJS to unload itself when the user leaves the page and why does it keep playing in the first place, the HTML5 video player didn't do that before.
Is the best way around this to get VideoJS to reload itself manually on page load? If so, how can that be done?
Note: If I navigate to any other page within the website the videos continue to not initialize, but if I reload the page, any page, the video on said page works again.
Note 2: Turns out that the onbeforeunload javascript event doesn't even fire if I click a link to another page, it only fires if you're going to a whole different website, so I can't even use that to .dispose() VideoJS on page unload.
Note 3: .reset() doesn't seem to be working either.
You can check to see if the player already exists and unload it, then reload it.
I was actually able to figure out a fairly simple and elegant solution:
if (player) {player.dispose()} else {var player}
player = videojs('player', {
//options
});
First it checks to see if the player exists. If it does, it destroys the VideoJS instance. If it doesn't, it creates the variable. Then it initializes the player.
By Referring this issue : https://github.com/videojs/video.js/issues/2904
We can re-write the above solution to something like this:
const playerId = 'video-player';
const videoOptions = {
controls: true,
sources: [{
src: 'test-file.mp4',
type: 'video/mp4',
}]
};
let player;
let players = videojs.players;
const imaOptions = { adTagUrl };
if (players && Object.keys(players).length) {
player = players[playerId];
player.dispose();
}
player = videojs(playerId,videoOptions);
player.ima(imaOptions);
I found this one to be the solution:
var oldPlayer = document.getElementById('my-player');
videojs(oldPlayer).dispose();
it's in the docs actually
I'm trying to play a sound effect when the user clicks a button in my web app.
I first tried this method:
var sound = new Audio("soundeffect.ogg");
function clickHandler(){
sound.play();
}
However, if the user presses the button twice in quick succession, the sound is only played once. I assumed this is because the sound hasn't finished playing, and therefore isn't rewinded.
I then tried this solution.
var sound = new Audio("soundeffect.ogg");
function clickHandler(){
sound.currentTime = 0;
sound.play();
}
However, this causes the first sound to cut off before the next one is played.
I then tried this version, which creates a new sound effect each time the button is clicked:
function clickHandler(){
var sound = new Audio("soundeffect.ogg");
sound.play();
}
This works perfectly on my developer machine, but using android chrome on mobile data, the sound effect seems to have to load each time the button is clicked, causing a delay of several seconds before the sound is played.
I was hoping declaring the sound effect in the global scope, then cloning it might help keep it in the cache, but it didnt seem to help.
var sound = new Audio("soundeffect.ogg");
function clickHandler(){
var oneShotSound = sound.cloneNode();
oneShotSound.play();
}
I wrote a web audio library, Wad.js, which I think will help you in this case.
var sound = new Wad({ source : 'soundeffect.ogg' });
sound.play();
Wad.js will create a new audio buffer source node every time you call play(), so you can hear multiple instances of the same sound, but all of those audio buffer source nodes use the same audio buffer, which saves you lots of computational work.
Check it out. https://github.com/rserota/wad
However, cross-browser compatibility is not perfect. I expect it'll work in chrome for android, but I haven't tested it.
I'm having a problem preloading HTML5 audio content and then using what I have in cache rather than attempting to redownload the audio every time I try to replay it.
http://cs.sandbox.millennialmedia.com/~tkirchner/rich/K/kungFuPanda2_tj/
The experience is suppose to be that when someone clicks on the banner, it pops up an ad with a loading bar. THe loading bar is loading all the images necessary for the animation. In the meantime, the audio is also getting loaded via audio tags already on in the DOM (which is fine). After all the images are loaded, the loading bar disappears and the user can continue on. There are 4 buttons on the bottom of the screen that they can click. Clicking one of them plays the audio file and images do a flipbook-style animation thats synced to the audio.
Audio Tags:
<audio id="mmviperTrack" src='tigress.mp3'></audio>
<audio id="mmmantisTrack" src='viper.mp3'></audio>
<audio id="mmtigressTrack" src='kungfu3.mp3'></audio>
<audio id="mmcraneTrack" src='crane.wav'></audio>
Play Button Event Listeners:
button.addEventListener('click',function(){
if ( f.playing ) return false;
f.playing = true;
button.audio.play();
},false);
button.audio.addEventListener('playing', function(){
animate();
}, false);
The problem is, in javascript, everytime I click play(), it reloads the audio file and then plays it. I can't seem to get it to load the audio once in the beginning and go off of whats stored in memory rather than try to reload the audio every single time I click the button.
I've tried experimenting with the preload and autobuffer properties, but it seems that mobile safari ignores those properties, because no matter what I set them too, the behavior is always the same. I've tried experimenting with source tags and different file formats... nothing.
Any ideas?
Alright, so the solution was a bit of a hack, cheat, workaround, whatever you want to call it.
What I noticed is that if I hit the play button on an audio file that I just played, it doesn't reload itself. It could be because I paused the audio after it finished playing through, but I'm not 100% sure on that. In any case, what I did is I combined all 4 audio files into one large audio file (yay Audacity~!). Then, every time I hit one of the play buttons I would set the currentTime property of the audio object to whatever the starting point of that track and then play the track until it hit its ending point, and then pause it again. Mission accomplished! Loaded once in the beginning and never again for each play.
Not crazy about the idea that I had to combine all the different audio tracks, but hey it works.
Oh, also. To get the audio track to load and fire a "canplaythrough" event, I attached this function to a user click event:
var track;
function addHTMLAudio() {
track = document.createElement('audio');
track.id = 'mm_audio'
track.autoplay = false;
track.preload = false;
track.addEventListener('canplaythrough',function(){
track.removeEventListener('canplaythrough');
audioLoaded = true;
},false);
document.getElementById('body').appendChild(track);
track.src = f.trackURL;
track.play();
setTimeout(function(){ track.pause(); },1);
}
playButton.addEventListener('click',function(e){
if ( playStatus > 0 ) return;
playStatus = 1;
var myId = e.target.parentNode.id;
var myClip = findClip( myId );
myClip.state = 'active';
track.currentTime = myClip.tIndex.start;
track.play();
runAnimation(myClip);
},false);