Ask iOS for the playback audio session on a page with a video
CI / Typecheck, test, build (pull_request) Successful in 12s
CI / Typecheck, test, build (pull_request) Successful in 12s
A TikTok post played perfectly and said nothing on an iPhone. The file was not the problem: every rendition TikTok offers for it carries a full AAC track, and the page as served measures loud audio in WebKit and Chromium alike, straight through the /m/ proxy. iOS is the problem. A video playing inline gets the "ambient" audio session, which the Ring/Silent switch mutes; only going fullscreen gets the sound back. Claiming "playback" says what is true of this page -- the sound is the point, not decoration -- and the switch stops applying. Declared only where there is a video, so an ordinary text post never claims it, and the session activates when something plays rather than on load, so it interrupts nothing on a page nobody presses play on. Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B3RUMiXa6eAW3okw9nB9NF
This commit is contained in:
@@ -155,6 +155,19 @@ function setupMedia(media) {
|
||||
}
|
||||
}
|
||||
|
||||
// On iOS a video playing inline gets the "ambient" audio session, which the
|
||||
// Ring/Silent switch mutes -- so the post plays perfectly and says nothing,
|
||||
// and the only way to hear it is to go fullscreen. Claiming "playback" says
|
||||
// what is true here: the sound is the point, not decoration. The session is
|
||||
// not activated until something actually plays, so declaring it up front
|
||||
// interrupts nothing; it is declared only on a page that has a video so an
|
||||
// ordinary text post never claims it at all.
|
||||
function setupAudioSession() {
|
||||
if (!('audioSession' in navigator)) return;
|
||||
if (!document.querySelector('video')) return;
|
||||
navigator.audioSession.type = 'playback';
|
||||
}
|
||||
|
||||
// Every comment is a <details open>, so folding one already works with this
|
||||
// file missing. All this adds is doing the whole page at once, which is why
|
||||
// the button ships hidden and is only revealed here.
|
||||
@@ -189,6 +202,7 @@ setupCopy();
|
||||
applyBrowser(storedBrowser());
|
||||
setupBrowserPicker();
|
||||
for (const media of document.querySelectorAll('.media')) setupMedia(media);
|
||||
setupAudioSession();
|
||||
setupComments();
|
||||
|
||||
// --- Verification puzzles -------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user