I'm trying to trigger Pictuer-in-picture (PiP) on a HTML video using the following code:
await videoElement.requestPictureInPicture().catch((error) =>
alert(`PiP failed, ${error}`);
);
This works fine in Safari, but when you use 'Add to home screen' with "display": "standalone" set in the manifest, this code returns an error saying picture in picture is unsupported.
Additionally the built-in PiP control is missing from the video player.
Any ideas why this is happening or how to fix it? I assumed the PWA/standalone version uses the same browser/js engine behind the scenes as regular Safari on the device, but it looks like it may be different?
As of March 2021:
Unfortunately, I don't think there is a way to trigger PiP mode in PWAs (yet).
The API is missing in standalone mode.
I did some research and tried to find some workarounds.
The only thing that somehow works is to force the user to load the page containing the video in Safari. In order for this to work you have to play with the scope param inside your manifest.
Put your PWA in a subfolder like /pwa and set "scope": "/pwa"
Put your Video pages in another subfolder like /videos
Everytime a user navigates to a video page, the scope of your PWA will be left. As soon as this happens, your PWA will leave the fullscreen mode and safari will render its top and bottoms bars.
Inside the bottom bar will be a small safari icon. The user must click it. Safari will open, PiP will be available.
To make the process a little bit smoother you can render a custom PiP button as video control. If the user clicks it, you check if your app is running in standalone mode by checking window.navigator.standalone. If it's false, just request PiP.
Otherwise, you navigate out of your PWAs scope. Use the history API (history.pushState) to change the location without reloading the page. You can add a query param like autopip=true. Finally, you show an overlay describing that the user should click the safari button in the bottom right corner.
Safari will open the page you pushed to the history. In Safari, check if the query param autopip=true is set and use JS to request PiP after video has loaded.
The big gotcha: There is no way to redirect the user back to your PWA.
Related
I'm working on a site that uses a video recorded via the user's webcam. The recorder library is not my code, but at a high level, it tries to use HTML5 (Media Recorder API) where possible and falls back onto Flash where not. On Safari, this means Flash. Basically, I supply the library with a div where I want the recorder to appear and it inserts it there.
However, some of my users were reporting confusion on Safari (the video recorder was not showing up) and I was able to reproduce this confusing situation. With Safari 12.0 on Mac OS 10.13.6 with Adobe Flash installed and enabled in Safari:
when I navigate to the page with the video recorder, I expect to see a "Click to use Flash" button on the video recorder area. But, when I first load the page, the area is complete blank. Strangely, it appears that the button is indeed there, but just not showing:
When I click on the area where the button should be, it responds (and prompts me to enable flash)
When I open the Web Inspector tool, the button appears (you can also see the code for the Flash object here that gets inserted dynamically)
When I simply resize the window, the button appears
I don't use Safari as my regular browser, so it's not like I have a highly customized configuration. Unless I'm missing something, this feels like a bug in Safari (I filed a bug report, but they specifically say they do not respond).
I've tried some javascript tricks to "re-draw" the element (e.g. hide then show) to try and get the button to show up right away, but without any luck. Obviously I can't tell users "resize the window" or "click in the middle where there is supposed to be a button".
Any ideas what could be causing this and how to fix it?
There was a lot of traffic about preventing a link in a standalone web app from opening in mobile Safari, but the iOS versions quoted were much earlier (7-9?). In iOS 11, I'm having the opposite problem: in my standalone web app, I have links to PDF files that need to be displayed. When I click on them, they open inside the web app browser instead of inside Safari, no matter what options I have given. Because of standalone mode, the result is a dead-end in the web app that requires restart of the app. (Android seems to do the right thing and pass off to a pdf viewing app.)
Click handler (javascript/bootstrap/jquery):
function openDocument(docURL) {
window.open(docURL,'_blank');
return false;
}
Alternatively, can one turn on the navigation inside the web app for the new page so that I can avoid the dead end? (I think no from what I'm reading; I've tried some options to window.open to no avail.) Or is it possible somehow put together a (multi-page) pdf viewer and a UI element for dismissal? Suggestions welcome.
EDIT: summarizing discussion below, iOS handles internal vs external links differently in standalone web apps. Making the links appear to be external by remapping on the server side allows the link to force Safari to open.
HHave an iFrame or a DIV in your page and load the PDF inside that component. Have a back button top of the iFrame to avoid dead end.
<iframe src="https://example.com/mypdf.pdf"
width="match your parent element" height="match your parent element" >
You can see one more option here to embed PDF.
Update: If you open the PDF form a different domain or sub-domain, it will be opened in a separate window even in iOS. Say your PWA URL is https://www.example.com/myapp and if you are currently accessing pdf from "https://www.example.com/myapp/pdf/mypdf.pdf", set an alias for this URL like "https://www.pdf.example.com/myapp/mypdf.pdf".
If the domain or sub-domain changes in a PWA, it will be treated as an external link and will always open in a new window and not inside the app leading the the dead end. You can try this if the CSS hacks are not good enough.
I have a customer that wants to launch a certain website from an icon on a tablet that runs Android. He's leasing out the tablets, so we have complete control over the hardware. The idea is that these tablets will only be used for his site (it's a type of slide show), so he wants the tablet home screen to have a single icon, and that icon will always launch his site in complete fullscreen. This works somewhat, but the statusbar does not go away without a user gesture. On Chrome the meta tag mobile-web-app-capable does the trick, but we can also use other browsers if this simplifies things. Is it possible to remove the statusbar without a second user gesture (the first being launching the website)?
And in response to the answers below, how can a WebLauncherActivity be useful when the user is just opening a browser?
On the page, element.requestFullscreen() displays the element in fullscreen mode.
Additional JS API and CSS selectors can provide other fullscreen specification in the following html5 article:
Building an Amazing Fullscreen Mobile Experience
Try using the WebappLauncherActivity that's used by the page shortcuts.
You should be able to launch the activity via adb with:
adb shell am start -n com.android.chrome/.webapps.WebappManager.ACTION_START_WEBAPP "url"
You can also add your own activity inheriting from FullscreenActivity which is the base for WebappActivity like mentioned by #tushar-pandey.
I'm working on an iOS app some people want to link to from their website.
While I've managed to open my app from a webpage using schemes, I wonder if, when I'm done with what I have to do in my app, I can switch back to the original website tab in safari.
To my knowledge : it is pretty straightforward to open a new page in safari from my app but I don't know if it is possible to get back to the actual original page, just like the ios9 back-to-app button would do.
I could open a new page and close it straight away with some javascript, which would probably display the original page because it's the next one in the tab list... but it doesn't feel right (does it?)
I read stuff about ios9 deep linking, still can't find anything interesting.
To achieve this is to open Safari using URLScheme. However, (afaik) Safari App doesn't have a url scheme. If the user came to your app from Chrome, than you can use its url scheme
Google Chrome has the following two URI schemes: googlechrome:// and googlechromes://
iOS 9's back to app button can't be invoked programmatically, so you can't use it as well. However in jailbreaked devices an app can mimic that, maybe that will help you http://theunlockr.com/2015/08/23/enable-back-button-ios-8-video/
I could open a new page and close it straight away with some
javascript, which would probably display the original page because
it's the next one in the tab list... but it doesn't feel right (does
it?)
It doesn't feel right at all. Because the typical behaviour for turning back to previos (or any other) application among iOS users is pressing home button twice, and selecting the app. Maybe you can simply show a message, and ask user to return Safari.
I recently bought an iPod so that I could test my own HTML5 games on iOS, and while looking around I found this HTML5 app:
http://www.apple.com/webapps/games/goldnuggets.html
If you load that page from an iPod or iPhone, you'll be able to play the game.
What I found memorable about this app is that when you try to load it, it forces you to 'install' (save) it to your homepage before you can play. The benefit of this is that the HTML5 app gets the full screen area to work with when launched from the homepage, just like a normal iOS app (as opposed to being covered up with the address bar and that command bar at the bottom).
I was wondering how I can check if the app has been added to the homepage (not the actual "add to homepage" function - which according to this thread is not possible Javascript for "Add to Home Screen" on iPhone?).
I could certainly use an extra 100px, and it would allow me to easily create an iOS version and HTML5 version with matching interfaces, and a better user experience.
Any ideas? Google search turned up nothing for me.
TL;DR window.navigator.standalone
And everything you need at http://www.bennadel.com/blog/1950-Detecting-iPhone-s-App-Mode-Full-Screen-Mode-For-Web-Applications.htm
Good luck!
One thought is to add a bookmark/favorite via JavaScript (called from an onclick event):
window.external.AddFavorite( url + "?somevariablethatsaysitisok=true", "MyGameName");
which I assume would work for iOS Safari as well.
On the URL part of it you can pass an argument that, when set, would allow the game to be played. If not set then only show the book mark link
You can either browser detect serverside or, if I remember correctly use javascript's navigator.userAgent or navigator.appVersion to see if it contains iPhone / iOS. Of course I would do some testing to to make sure you get the exact string, but that's the general idea.