We play streaming audio with javascript that is running in a WKWebView object on iOS. If that WKWebView is destroyed or no longer displayed, the audio will oftentimes continue playing to completion. The only way for the user to stop the audio is to swipe up to get the lock screen playback controls and hit 'pause'.
Is there a way for the javascript in the WKWebView to be notified that it is about to be shut down, so that it can stop playback of the audio before the WKWebView is destroyed?
I've tried hooking into 'pagehide', 'unload', 'beforeunload', and 'visibilitychange' events, with no luck.
I'm sure a custom event could be triggered from the native code, but I don't have control of that side of things. Is there anything else that works?
This bug was apparently fixed in iOS 8.3+, but the suggested answer of loading a blank page as the view disappears works very well and could be useful if supporting apps running on older OS versions. This approach is also much more resilient than relying on each JS implementation running in the WKWebView to stop its own media playback after being notified of the impending 'shutdown' of the web view:
In your WKWebView view controller class' -(void)viewDidDisappear:(BOOL)animated method, run the following code to load a blank page into your web view. The code assumes your reference to your web view is self.webView, thus modify as needed.
// fix to prevent embedded audio/video from playing once the view has closed...
[self.webView loadHTMLString:#"<html/>" baseURL:nil];
See WKWebView embed video keeps playing sound after release for more details...
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 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 need to stop a HTML5 animation from outside the Web browser.
I have tablets that are showing HTML5 pages with animations.
So, I have a Web View (Basic4Android) in my Android Application that shows the HTML5 web pages.
When an event occurs on the App, I need to stop/pause/play/resume the HTML5 animation.
Is it possible? Is it possible to call javascript functions/events from the App?
Thanks!
Regards.
You need to execute javascript code which will stop animation on page. Please have a look at thread Execute javascript from code
When I long press or scroll on the screen of an Android or iOS device, the Javascript running in the webview pauses. How can I keep js running, and additionally, why does js pause in this case?
This post has a similar question/answer, I believe it is purely a performance optimisation, as scrolling will require the browser to redraw/paint the DOM: This will take alot of resources. In regards to the long press, this may be related to the browser waiting to understand what the wants to do next, i.e. selecting an area to copy/paste or triggering the browsers context menu.
Is there a way to show the controls after a video has started playing. Basically, I'm playing a video with play(), and I want the controls to stay up for a few seconds. Currently (at least on my Android device), the controls fade once the video starts.
Toggling the controls attribute doesn't work, unfortunately.
HTML5 video on Android (iOS too) is not opened inline but in the native player (i.e. outside the browser), so the <video>-tag attributes have no control over what is going to happen in the player.
I don't know if it's possible to "hack" / set-up the native player so I guess you'll have to do research on that. I don't know of any way to remotely influence the behavior of the Android application unfortunately. In case you find out something it would be nice if you could let me know btw.
Also see a recent question of mine (which is rather discouraging unfortunately).