Test whether an iPhone plays DeadAir's cuts as an HLS playlist over the original file #180

Closed
opened 2026-10-09 19:46:32 -07:00 by rays · 1 comment
Owner

Instead of making a DeadAir copy, ipx could hand the player an HLS playlist (.m3u8) whose pieces are byte ranges of the original (#EXT-X-BYTERANGE), one for each stretch between two silences. No copy on disk, and it is ready as soon as the silences are found (4s for a 72-minute episode). HLS is built into Safari on iOS and plays locked.

Test before building (implementation in the next issue):

  • Build the playlist for a real episode (techpod-358, 649 cuts) from silencedetect's cuts and ffprobe's packet byte positions, serve it and the file from Tower, and play it in Safari on the iPhone.
  • Apple's HLS rules want each packed-audio piece (MP3, AAC) to start with an ID3 PRIV timestamp tag (com.apple.streaming.transportStreamTimestamp). A raw byte range has none. Find out whether Safari plays it anyway, refuses it, or drifts. If it needs the tag, try serving each piece with the tag in front.
  • Listen for gaps or blips at the cuts. An MP3 frame can borrow bits from the one before it (the bit reservoir); today's ffmpeg copies cut the same way.
  • Check it keeps playing locked, and that seeking lands where expected.
  • Note what Chrome and Firefox on a computer do. They have no native HLS and would need hls.js.
Instead of making a DeadAir copy, ipx could hand the player an HLS playlist (.m3u8) whose pieces are byte ranges of the original (`#EXT-X-BYTERANGE`), one for each stretch between two silences. No copy on disk, and it is ready as soon as the silences are found (4s for a 72-minute episode). HLS is built into Safari on iOS and plays locked. Test before building (implementation in the next issue): - Build the playlist for a real episode (techpod-358, 649 cuts) from silencedetect's cuts and ffprobe's packet byte positions, serve it and the file from Tower, and play it in Safari on the iPhone. - Apple's HLS rules want each packed-audio piece (MP3, AAC) to start with an ID3 PRIV timestamp tag (`com.apple.streaming.transportStreamTimestamp`). A raw byte range has none. Find out whether Safari plays it anyway, refuses it, or drifts. If it needs the tag, try serving each piece with the tag in front. - Listen for gaps or blips at the cuts. An MP3 frame can borrow bits from the one before it (the bit reservoir); today's ffmpeg copies cut the same way. - Check it keeps playing locked, and that seeking lands where expected. - Note what Chrome and Firefox on a computer do. They have no native HLS and would need hls.js.
rays added the enhancement label 2026-10-09 19:46:32 -07:00
Author
Owner

Tested 2026-10-10 on iOS 18.7 Safari with techpod-358: 649 silences, 790 pieces, the playlist 4116.3s against the original's 4348.0s.

Both versions worked: plain byte ranges of the original, and pieces with an ID3 transportStreamTimestamp in front.

  • Safari reported the length correctly (4116.3s) for both.
  • No stall at the cuts: in every 10s of wall time exactly 10.00s of audio played, across about 50 cuts, with the screen on and locked. The skip list, by comparison, lost 1.3s per cut.
  • Played straight through while locked (2m16s on plain ranges).
  • Seeking worked: Jump to 30:00 landed at exactly 1800.0s, and scrubbing worked too.
  • No clipped words heard. The pauses left feel too short (0.2s, from KEEP = 0.1 on each side); that is filed separately.

So the timestamp tags are not needed: #181 can be a playlist of plain byte ranges into the file ipx already has. The stalled event a few seconds in is Safari pausing its download once it has buffered enough; playback continued through it.

Not tested: Chrome and Firefox on a computer, which have no native HLS.

Tested 2026-10-10 on iOS 18.7 Safari with techpod-358: 649 silences, 790 pieces, the playlist 4116.3s against the original's 4348.0s. Both versions worked: plain byte ranges of the original, and pieces with an ID3 transportStreamTimestamp in front. - Safari reported the length correctly (4116.3s) for both. - No stall at the cuts: in every 10s of wall time exactly 10.00s of audio played, across about 50 cuts, with the screen on and locked. The skip list, by comparison, lost 1.3s per cut. - Played straight through while locked (2m16s on plain ranges). - Seeking worked: Jump to 30:00 landed at exactly 1800.0s, and scrubbing worked too. - No clipped words heard. The pauses left feel too short (0.2s, from KEEP = 0.1 on each side); that is filed separately. So the timestamp tags are not needed: #181 can be a playlist of plain byte ranges into the file ipx already has. The `stalled` event a few seconds in is Safari pausing its download once it has buffered enough; playback continued through it. Not tested: Chrome and Firefox on a computer, which have no native HLS.
rays closed this issue 2026-10-10 12:24:00 -07:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: rays/ipx#180