Why Your Phone Screen Goes Dark and the Sound Stops
Short answer: A phone turns its screen off after a short time without a touch. On an iPhone, when the screen locks, the page is paused and the sound stops. The fix is to keep the screen awake while the sound plays: ask for a screen wake lock, keep a fallback for when the phone refuses, and start both in the right order inside the tap.
startButton.addEventListener('click', async () => {
startSilentVideo(); // the fallback first, while the tap still counts
try {
wakeLock = await navigator.wakeLock.request('screen');
} catch (err) {
// refused, for example in low power mode. The fallback is already running.
}
});
// the lock is dropped whenever the tab is hidden, so ask again on return
document.addEventListener('visibilitychange', async () => {
if (wakeLock !== null && document.visibilityState === 'visible') {
wakeLock = await navigator.wakeLock.request('screen');
}
});
What is going on
My app has nothing to tap. You press play and leave it. To a phone that looks like someone who has walked away, so it dims the screen and then locks.
The proper tool
The Screen Wake Lock API lets a visible page ask the phone not to dim or lock the screen. Three things about it matter here:
- The request can be refused, for example in power saving mode or on low battery. It fails as a rejected promise, so wrap it in try and catch.
- The lock is released when the page is no longer visible. Ask again when the user comes back.
- It keeps the screen on. It does not keep sound playing behind a locked screen.
The fallback
A tiny, silent, invisible video that loops. Phones keep the screen on while a video is playing, so this works where the wake lock is missing or refused. It is an old trick and a lot of sites use it.
The order was the whole bug
My first version asked for the wake lock, waited for the answer, and then started the video. On an iPhone the screen went dark anyway.
The reason is that a phone only lets a page start a video while the user's tap is still in progress. Waiting for the wake lock used the tap up. By the time the video tried to start, the phone no longer counted it as something the user had asked for.
Starting the video first, with no waiting before it, fixed it. The wake lock can take its time afterwards.
Test on a real phone
A desktop browser pretending to be a phone never locks its screen, so it never shows this. I only found it by leaving a real iPhone on the desk and waiting.
The cost
The screen stays on, and that uses battery. If you leave it playing on a phone, turn the brightness down.
Sources
- Screen Wake Lock API, MDN: what it does, when it is refused and when it is released
Try it: open Ocean on your phone and leave it on the table. It is free and starts in one tap.
Open Ocean, free