DeadAir: start an episode at once and move to the shortened copy when it is ready #178

Closed
opened 2026-10-09 17:05:44 -07:00 by rays · 2 comments
Owner

Today a DeadAir show's episode only plays shortened once its copy is made, a few minutes after the download. Until then you hear the original, and the page does not move to the copy while you listen.

Plan

  1. When someone presses play on an episode with no copy yet, DeadAir makes that one next, ahead of its queue. A copy takes 7-9s (took_ms on DeadAir copy made: 7304 ms for 520 cuts, 9165 ms for 643).
  2. Meanwhile the original plays straight through, so playback starts at once.
  3. When the copy is ready, the page switches to it at the same place (to_copy). The page already hears when a copy is done (#176).

You hear about 10s of the original, then the shortened version, with no gaps.

To check first:

  • Whether DeadAir's queue can take a "do this one now" request cheaply.
  • Whether the "copy is ready" message reaches a locked iPhone. The test page's fetches went out while locked, but it never listened for a server event.

What was tested, and what was ruled out (2026-10-09/10)

Tested in iOS 18.7 Safari with a page that played beeps with 3s silences between them.

  • Switching to the copy works, even locked. On lock (visibilitychange), the source changed, play() was accepted, and the copy was playing 0.4s later and kept going for the 70s lock. On unlock, it was playing 0.7s after the switch.
  • Scripts keep running while locked. setTimeout fired on time for 2 minutes locked, and fetches reached the server in real time.
  • A skip list that seeks past silences is ruled out. The skips started on time (0-1 ms late, none missed while locked), but each seek left a gap of about 1.3s: after 140s, the player had played only 75s of beeps across 50 skips. With 600+ cuts an episode, that is over 13 minutes of gaps.
  • Web Audio is ruled out. It decodes the whole file to memory, about 1.5 GB for a 72-minute episode.
  • Media Source Extensions (ManagedMediaSource, iOS 17.1+) could play only the parts kept, without gaps. It is the most complex option and gains only the first 10s over the plan.
  • ffmpeg 7.1's silencedetect reports silences as it finds them, at about 1,000x playback speed: all 649 cuts in a 72-minute episode within 4s.

The native player is on hold, so this is for the web page.

Today a DeadAir show's episode only plays shortened once its copy is made, a few minutes after the download. Until then you hear the original, and the page does not move to the copy while you listen. ## Plan 1. When someone presses play on an episode with no copy yet, DeadAir makes that one next, ahead of its queue. A copy takes 7-9s (`took_ms` on `DeadAir copy made`: 7304 ms for 520 cuts, 9165 ms for 643). 2. Meanwhile the original plays straight through, so playback starts at once. 3. When the copy is ready, the page switches to it at the same place (`to_copy`). The page already hears when a copy is done (#176). You hear about 10s of the original, then the shortened version, with no gaps. To check first: - Whether DeadAir's queue can take a "do this one now" request cheaply. - Whether the "copy is ready" message reaches a locked iPhone. The test page's fetches went out while locked, but it never listened for a server event. ## What was tested, and what was ruled out (2026-10-09/10) Tested in iOS 18.7 Safari with a page that played beeps with 3s silences between them. - **Switching to the copy works, even locked.** On lock (visibilitychange), the source changed, play() was accepted, and the copy was playing 0.4s later and kept going for the 70s lock. On unlock, it was playing 0.7s after the switch. - **Scripts keep running while locked.** setTimeout fired on time for 2 minutes locked, and fetches reached the server in real time. - **A skip list that seeks past silences is ruled out.** The skips started on time (0-1 ms late, none missed while locked), but each seek left a gap of about 1.3s: after 140s, the player had played only 75s of beeps across 50 skips. With 600+ cuts an episode, that is over 13 minutes of gaps. - **Web Audio is ruled out.** It decodes the whole file to memory, about 1.5 GB for a 72-minute episode. - **Media Source Extensions** (ManagedMediaSource, iOS 17.1+) could play only the parts kept, without gaps. It is the most complex option and gains only the first 10s over the plan. - ffmpeg 7.1's silencedetect reports silences as it finds them, at about 1,000x playback speed: all 649 cuts in a 72-minute episode within 4s. The native player is on hold, so this is for the web page.
rays added the enhancement label 2026-10-09 17:05:44 -07:00
Author
Owner

The stall is real, not a clock lag. In the unlock test, the original was at 225.00s when the phone was unlocked 140s after the start. Of that, 50 silences of 3s had been skipped, so 75s of beeps had played in 140s of wall time: 65s lost, 1.3s for each skip. A seek by setting currentTime leaves a gap about 1.3s long at every cut, whether Safari stalls or plays on until the seek lands. With 600+ cuts an episode, that is over 13 minutes of gaps, so seeking is not usable for this. Next step if this goes ahead: decode the audio and schedule only the parts kept with Web Audio, which plays them back to back without seeking. Whether Web Audio keeps playing on a locked iPhone needs its own test.

The stall is real, not a clock lag. In the unlock test, the original was at 225.00s when the phone was unlocked 140s after the start. Of that, 50 silences of 3s had been skipped, so 75s of beeps had played in 140s of wall time: 65s lost, 1.3s for each skip. A seek by setting currentTime leaves a gap about 1.3s long at every cut, whether Safari stalls or plays on until the seek lands. With 600+ cuts an episode, that is over 13 minutes of gaps, so seeking is not usable for this. Next step if this goes ahead: decode the audio and schedule only the parts kept with Web Audio, which plays them back to back without seeking. Whether Web Audio keeps playing on a locked iPhone needs its own test.
rays changed title from DeadAir: play at once by skipping silences, and move to the copy when it is ready to DeadAir: start an episode at once and move to the shortened copy when it is ready 2026-10-09 17:21:51 -07:00
Author
Owner

No longer needed: DeadAir no longer makes copies (#181). The playlist is ready a few seconds after the download (2.4s for the first episode in production), so there is nothing to switch to mid-play.

No longer needed: DeadAir no longer makes copies (#181). The playlist is ready a few seconds after the download (2.4s for the first episode in production), so there is nothing to switch to mid-play.
rays closed this issue 2026-10-10 12:49:40 -07:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: rays/ipx#178