4 Commits
Author SHA1 Message Date
thatguygriff 05455a86da Merge pull request 'Ask iOS for the playback audio session on a page with a video' (#14) from video-audio-session-on-ios into main
CI / Typecheck, test, build (push) Successful in 46s
Publish / Build and push (push) Successful in 28s
Publish / Move the working version on (push) Successful in 4s
Reviewed-on: #14
2026-09-03 00:56:04 +00:00
thatguygriffandClaude Opus 5 4c78ce8a27 Ask iOS for the playback audio session on a page with a video
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
2026-09-02 21:06:12 -03:00
thatguygriff d9fa2f5768 Merge pull request 'Set the working version to 1.2.4' (#12) from release/bump-1.2.4 into main
CI / Typecheck, test, build (push) Successful in 17s
Publish / Build and push (push) Successful in 35s
Publish / Move the working version on (push) Skipped
Reviewed-on: #12
2026-08-31 02:44:07 +00:00
Release bot dfabfc18d6 Set the working version to 1.2.4 2026-08-31 02:42:23 +00:00
5 changed files with 26 additions and 3 deletions
+5
View File
@@ -100,6 +100,11 @@ Things worth knowing before editing:
`<video>` with no data has a natural size of 300x150, and WebKit sizes it from that —
so one with no poster of its own gets an empty SVG of the right shape as a stand-in,
without which a portrait video sits in a squat landscape box until you press play.
- **A page with a video claims the `playback` audio session** (`public/app.js`). iOS
hands inline video the ambient session, which the Ring/Silent switch mutes, so
without this the video plays and says nothing until it goes fullscreen — and the
report that arrives is "this one platform has no sound". The session only activates
once something plays, so declaring it costs nothing on a page nobody presses play on.
- **Never a bare error page.** A failed resolve renders a card carrying the platform, the
original URL and the copy button. A broken adapter must still leave the link one tap
away.
+4
View File
@@ -171,6 +171,10 @@ The one exception is Bluesky video, which is an HLS playlist — proxying it wou
rewriting the manifest and every segment, so it is linked directly. Safari plays HLS
natively; other browsers show a note.
A page carrying a video asks iOS for the playback audio session. Without it a video
playing inline is treated as ambience and the Ring/Silent switch mutes it, so the post
plays perfectly and says nothing unless you go fullscreen.
Resolved posts are cached in memory for an hour, so a reload or a back button doesn't
drive the browser again.
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "antisocial",
"version": "1.2.3",
"version": "1.2.4",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "antisocial",
"version": "1.2.3",
"version": "1.2.4",
"license": "UNLICENSED",
"dependencies": {
"@fastify/static": "10.1.3",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "antisocial",
"version": "1.2.3",
"version": "1.2.4",
"private": true,
"description": "Reads social posts back to you without the app.",
"license": "UNLICENSED",
+14
View File
@@ -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 -------------------------------------------------