Skip to content

feat(etco): support multi-byte event types via 0xFF escape prefix#1

Open
joust wants to merge 11 commits into
mainfrom
feat/etco-extended-events
Open

feat(etco): support multi-byte event types via 0xFF escape prefix#1
joust wants to merge 11 commits into
mainfrom
feat/etco-extended-events

Conversation

@joust
Copy link
Copy Markdown
Owner

@joust joust commented Apr 14, 2026

Summary

Brings ETCO frame handling in line with ID3v2.4 §4.5, which specifies that an event type may span multiple bytes: any number of leading 0xFF escape bytes followed by a single terminating byte (0x000xFE). The previous parser/writer assumed a fixed 5-byte stride (1-byte event + 4-byte timestamp), leaving the extended-event range unrepresentable.

Event types are now either:

  • a number (0x000xFE) for single-byte events (unchanged), or
  • an Array<number> of bytes for extended events, e.g. [0xFF, 0x12]

Fully backward compatible — existing callers using { event: number, time } keep working.

Changes

  • src/id3v2/parse.mjs — consume leading 0xFF escape bytes, then the terminator
  • src/id3v2/write.mjs — serialize array-form event types correctly
  • src/id3v2/validate.mjs — strict-mode rejects bare 0xFF as a single-byte event, non-0xFF prefix bytes, and arrays whose terminator is itself 0xFF
  • types/id3v2/frames.d.ts — event type widened to number | number[]
  • test/id3v2/index.cjs — coverage for single-byte, extended, and invalid cases

Test plan

  • Existing ETCO tests still pass
  • New tests cover multi-byte event types (parse + write round-trip)
  • Strict-mode validation rejects malformed event types

eidoriantan and others added 11 commits February 18, 2026 15:09
Closes eidoriantan#648

- Adds `MP3Tag.readBlob(blob, options)` — a static async method that reads tags
  from a Blob/File without loading the entire file into memory
- Uses blob.slice() for zero-copy partial reads; walks AIFF chunk headers and
  MP4 box headers to locate tags at any offset
- Supports all existing formats: MP3 (ID3v2 + ID3v1), AIFF, MP4, and AAC

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Bumps [rollup](https://github.com/rollup/rollup) from 2.79.2 to 2.80.0.
- [Release notes](https://github.com/rollup/rollup/releases)
- [Changelog](https://github.com/rollup/rollup/blob/v2.80.0/CHANGELOG.md)
- [Commits](rollup/rollup@v2.79.2...v2.80.0)

---
updated-dependencies:
- dependency-name: rollup
  dependency-version: 2.80.0
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps  and [minimatch](https://github.com/isaacs/minimatch). These dependencies needed to be updated together.

Updates `minimatch` from 5.1.0 to 5.1.9
- [Changelog](https://github.com/isaacs/minimatch/blob/main/changelog.md)
- [Commits](isaacs/minimatch@v5.1.0...v5.1.9)

Updates `minimatch` from 5.1.6 to 5.1.9
- [Changelog](https://github.com/isaacs/minimatch/blob/main/changelog.md)
- [Commits](isaacs/minimatch@v5.1.0...v5.1.9)

Updates `minimatch` from 3.1.2 to 3.1.5
- [Changelog](https://github.com/isaacs/minimatch/blob/main/changelog.md)
- [Commits](isaacs/minimatch@v5.1.0...v5.1.9)

---
updated-dependencies:
- dependency-name: minimatch
  dependency-version: 5.1.9
  dependency-type: indirect
- dependency-name: minimatch
  dependency-version: 5.1.9
  dependency-type: indirect
- dependency-name: minimatch
  dependency-version: 3.1.5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
ID3v2.4 §4.5 specifies that an ETCO event type may span multiple
bytes: any number of leading 0xFF escape bytes followed by a single
terminating byte (0x00–0xFE). Previously the parser/writer assumed
a fixed 5-byte stride (1 byte event + 4 byte timestamp), which made
the extended-event range unrepresentable.

Event types are now either:
- a number (0x00–0xFE) for single-byte events (unchanged)
- an Array<number> of bytes for extended events, e.g. [0xFF, 0x12]

This is fully backward compatible: existing callers that use
{ event: number, time } continue to work unchanged.

Strict-mode validation rejects 0xFF as a bare single-byte event,
non-0xFF prefix bytes, and arrays whose terminator is itself 0xFF.
@joust joust force-pushed the feat/etco-extended-events branch from a2fb9c4 to 152580d Compare April 15, 2026 10:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants