I'm currently implementing HowlerJS and I got it working. But the following happens on Safari using El Capitan:
Open Safari and enter HowlerJS and click play, and it starts loading.
For several of the machines it never plays
Refresh page, click play, it works.
Close open Safari, happens again.
And it is also happening on iOS. Now I've seen that you need to wait for a user click to play audio, which is what I'm doing.
On click of the button it loads and plays the audio. Has anyone faced this problem? I'm using the stable version 1.1.28.
Safari 9 has started to suspend audio on initial page load. In addition to all the other song and dance you usually have to do, now we have to instruct the AudioContext to resume and defer our business logic until that promise resolves. You'll probably want this check just inside a click handler.
if(Howler.ctx && Howler.ctx.state && Howler.ctx.state == "suspended") {
Howler.ctx.resume().then(function() {
console.log("AudioContext resumed!");
// fire your callback here
});
}
Howler 2.0 has supposedly already fixed this, but no such luck as of 1.1.28 for us stable users >_>
Related
I have blazor WASM app with "correct" .mp3 file that is played via javascript code. On the Desktop lets say its pretty instant after pressing button but on the phone its skips few ms and then it seems there is delay and its not good user experience. I tried to look up some solutions but couldnt find anything. Is there any way to solve it or its just because of phone (Iphone 7)?
sounds.js:
window.PlayAudio = (elementName) => {
document.getElementById(elementName).play();
}
*.razor:
<audio id="sound" src="#navManager.BaseUri/sound/correct.mp3" />
<button id="soundButton" #onclick="PlaySound">Click me to play "correct" sound</button>
...
public async Task PlaySound()
{
await JSRuntime.InvokeAsync<string>("PlayAudio", "sound");
}
Please see the repo and webapp:
https://github.com/Laftek/BlazorWASMPWAStaticPublish
https://laftek.github.io/BlazorWASMPWAStaticPublish/Lottie/7
Thank you any help would be much apprieciated.
This is not a Blazor issue-- it's a client browser behavior. It was once the standard across all devices, but I think newer devices have dropped some of the restrictions as audio files are no longer considered "large files."
Getting consistent media playback across all platforms has always been EXTREMELY difficult-- especially apple products, and most especially older apple products. I suspect that the sound will not start loading at all until a user action (like a button click). Then, unless you have fast data transfer, it will take some time to buffer. This was a common security feature for mobile devices to prevent sites from wasting users' data with media they didn't want.
The solution is to catch a click early on in the site's progress-- usually with a loading screen and "click here to enter." Then IN THAT CLICK HANDLER (important) you pre-start all your audio files by playing them and immediately pausing them again. Now, they will (probably) load, and when you really want to play the file, it will be loaded and ready.
Note that a simulated click will not work, so you can't just do element.onclick() after the page renders. It has to be an actual user interaction.
Javascript audio elements have various events, like canplay which let you know when enough of an audio source is loaded that you can start playing it.
https://www.w3schools.com/tags/ref_av_dom.asp
If you're lucky, Blazor has exposed the oncanplay event. Then you can use that even to enable your plaback button. I don't know if they have got around to audio events yet or not.
I want to use the HTMLMediaElement.play() method to play a sound when a button is clicked. Everything working fine in Chrome and Firefox, but Safari 15... Every time I click the button there is some kind of delay or it is not even played. I used the code as described below:
const mainButton = document.getElementById('main-button');
const buttonSound = new Audio (button-sound.mp3);
mainButton.addEventListener('click', e => {
buttonSound.play();
});
It would be great if someone could help!
I have not tried it yet, but this seems like a viable solution: https://browserhow.com/how-to-allow-or-block-auto-play-sound-access-in-safari-mac/ it sounds like it is disabled by default in the browser so if you enable it, it should then play. If it is delayed, does the sound file start from 0 seconds? I know that sounds obvious but that could be a reason for the delay.
This can be changed I believe by going into the safari settings specifically the article indicates to do this as follows:
Launch the Safari app on a mac computer.
Select Safari from the menubar options.
Choose Preferences… option under the Safari menu.
Switch to the Websites tab within the Preferences popup window.
Choose the Auto-Play in the sidebar.
At the bottom of the drop-down — When visiting other websites select
Allow All Auto-Play.
I have a website set-up, where the background is a YouTube video using Tubular.js plugin. There is a problem with chrome browsers, that auto pauses the youtube video if I load it with mute: false flag. Chrome is the only offender, as it works with opera, firefox etc. If I change the flag to mute: true the video will atuplay fine.
Chrome recently started to block atuplayed videos with sound. Is there an option to bypass this on chrome, or at least modify the tubular.js library/js call so that it will only mute (regardless of settings) on chrome user-agents?
https://codepen.io/anon/pen/MGEZrO
Thanks in advance
According to chrome logic it is impossible to autoplay video if it is NOT muted. However they allow to autoplay video if it is muted and WILL NOT stop it if user will unmute it. By this (user interaction) chrome means just a single tap OR click by the user on the website (everywhere, not video components only).
Just make your user to make a single click on your webpage and THEN you can mount/start video with autoplay and sound.
I have the similar situation with my react spa. And I force my user to make a single click before mounting the video. Only this way it starts to play with sound.
I also had the situation where the video MUST have started even without click and the I just addEventListener on whole page to unmute it as soon as possible
play(from = null) {
document.addEventListener('click', () => {
// any click will force my video to unmute
this.player.muted = false;
});
// rest code for updating state etc
}
Unfortunately, triggering click is not working (the video will stop automatically)
According to their guidelines about autoplay on chrome ;
Unfortunately, Chrome cannot provide any whitelist exceptions to the autoplay policy.
They also explain how to present the content in a less-invasive way (muted video first) and some other tips about the policy.
I have created a Web App which plays music playlist and it works well on desktop browsers and also in mozilla and opera of android. But When I play the songs on Chrome browser of Android and I turn off the screen, it stops after playing the current song. And as soon as I turn the screen on, it starts loading the next song in line.
From my observations, what I have understood is Google Chrome browser on android pauses the javascript code from executing if the screen is turned off till the screen is not waken up again. Is there any way I can prevent my specific library from pausing? Any approach or events?
Some related this question is what I am looking for: JavaScript halts in inactive android Chrome tab
There are so many WebApps which does not stop playing music. Does it need some permissions from Google App Store?
check what happens with youtube, at least few years ago i had an awful time dealing with that and that's what proved to my client it cant be done in the given time frame and budget. that was actually device specific, on some devices it worked fine and on others it didnt. check if it happens on other devices. the only solutions i could think of ware either to prevent screen turn off (on problematic devices or all of them at the beginning), or to build an app and handle onPause event
I don't think that you can change the behaviour of the Chrome app, if they want to save battery in the background and stop the javascript, you won't reactivate it.
There are maybe some other ways to get it working.
Tell your users that they should use Firefox or Opera on their mobile device.
All apps are allowed to play or stream music in the background, so you could make or use an app for your task.
Maybe you can use the default music player app on android. Open a playlist of streams using the app. (I don't know if this is possible, because I have no android device.)
I know that is not exactly what you want, but a maybe a way to get it working.
I'm implementing a video player using VideoJS. Two key functions of this video player are:
a) If the user leaves the page, resume the video at that point when they come back or on refresh
b) Include HLS (h.264/mp4) support to provide better video quality depending on the connection.
The API for saving and retrieving a user's timestamp is already in place, and using the excellent HLS plugin, the video player works almost fine in all browsers as expected. The following code is used to initialize the player and jump to the saved time:
videojs.options.flash.swf = '../video-js/video-js.swf';
var player = videojs(videoId);
supportHLS = videojs.Hls.isSupported();
player.ready(function() {
[[event listeners for media controls]]
this.on('seeked', function() { console.log('seeked');});
this.on('seeking',function() { console.log('seeking');});
var PLAYER_LOADED = 'loadedmetadata';
if(!supportHLS) { PLAYER_LOADED = 'canplay';}
this.one(PLAYER_LOADED, function() {
this.one('canplay', function() {
this.play();
});
this.currentTime(savedPosition);
lastViewed = savedPosition;
});
});
(Reason for the roundabout logic: Chrome had issues with playing the video before the new data (after the seek) had loaded, which caused a number of problems with the data in the buffer. Also, Safari 7.1 would break if you tried this during the 'loadedmetadata' event)
However, there's still one problem, specific to Safari. The loading spinner doesn't always go away when you refresh the page. Examining the logs and listeners seems to indicate that the 'seeking' and 'seeked' events fire at about the same time, but in different orders; the problem always arises whenever 'seeked' fires first, and never occurs when 'seeking' is first. Furthermore, any seeking after the video is playing removes the spinner, so it has to be caused by the initial seek.
It's interesting that Safari supports HLS streaming natively, yet consistently causes the most problems with this player implementation. This is the last Safari bug to iron out, but though it's small it still has a negative impact on user experience.
What causes Safari to fire the 'seeked' and 'seeking' events out of order like this? What can I do to work around it, or is there a cleaner solution for what I'm trying to accomplish?