oTAPE 1.0 · open specification · release candidate

Press record.
Mean it.

oTAPE is an open file format for digital cassettes. Two sides of continuous tape, a label you write on, a J-card in the case and a record tab you can snap off. All of it in one .otape file that works offline and belongs to you.

Extension
.otape
Container
ZIP + JSON
Licence
All rights reserved
Shell Ferro Black

Drawn live from a few lines of appearance JSON, with the reels wound by the spec's tape-pack model.

01 The idea

Bring back
the ritual.

Making a mixtape used to take an evening. You chose every song, sat through it while it recorded and wrote the titles by hand. oTAPE keeps that ritual and saves it as a file. The cassette's rules are built into the format itself.

  1. 01

    A cassette,
    not a playlist.

    Each side is one continuous take. The silence between songs, the spoken intro, the clunk of the pause button: all of it is part of the recording.

  2. 02

    The physics
    come along.

    A fixed length. Two sides on one tape. You get somewhere by winding, not jumping. Reach the end of side A, flip, and you're at the start of side B.

  3. 03

    The file is
    the object.

    Audio, label, J-card, booklet and history live inside one .otape. It never points back to the MP3s it was recorded from.

  4. 04

    Listening
    leaves no trace.

    Playing never changes the file. Your player remembers where you stopped, the way a real tape stays wound where you left it.

  5. 05

    Open and
    plain.

    A ZIP, one JSON manifest, AAC audio, PNG or JPEG artwork. A developer can write a basic player in an afternoon.

  6. 06

    Every tape
    looks like itself.

    Supply artwork in exact physical proportions, or describe the shell and label in a few lines that any player can draw.

02 Try it

Put a tape
in the deck.

This is a working oTAPE player: about 1,200 lines of plain JavaScript, no libraries. It reads the reference cassette from the specification, or any .otape you drop here. Your file stays in your browser and is never uploaded.

Web cassette deck  OT-W RECTAPE RUN
Insert cassette
or drop a file anywhere on the deck
Counter---
SideAB
Time-:--
Remain-:--
Tape---
NO CASSETTE
Now—
Tape mapclick to wind
0:00

Space play / stop ←→ rewind / fast forward F flip E eject

03 Inside the file

Unzip a
cassette.

An .otape is a ZIP archive with a fixed shape: a mimetype entry first, so tools can recognise it without unzipping, then one manifest, one continuous recording per side and optional paper.

night-drive.otapeZIP
mimetype               application/vnd.otape.cassette
manifest.json          the cassette, sides A and B, the look
audio/
  side-a.m4a           AAC-LC, one continuous take
  side-b.m4a           absent while the side is blank
artwork/               optional, fixed physical sizes
  cassette-face-a.png
  label-a.png
  jcard-front.jpg  jcard-spine.png
  booklet-01.png …
docs/                  booklet.html, notes.md
manifest.json · a blank C60
{
  "format": "oTAPE",
  "format_version": "1.0",
  "cassette": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "title": "Night Drive",
    "type": "C60",
    "side_length_seconds": 1800,
    "created_at": "2026-10-28T22:00:00Z"
  },
  "sides": {
    "A": { "write_protect": "intact", "audio": null },
    "B": { "write_protect": "intact", "audio": null }
  }
}
Media type
application/vnd.otape.cassette
Apple UTI
org.otape.cassette
Audio
AAC-LC in M4A, required. ALAC, FLAC and PCM optional.
Timeline
Integer frames at 44 100 or 48 000 Hz, exact to the sample
Magic
PK\x03\x04 at 0, the media type at byte 38
Versions
MAJOR.MINOR. Minor versions only add, and unknown data is kept.

04 The medium

Fixed length.
Breakable tabs.

A cassette's limits shape what you put on it. oTAPE keeps them: you choose a length before you record, and every side has a record tab you can snap off.

Pick a length

  • C4623 min / side · 65.7 m · 18 µm
  • C6030 min / side · 85.7 m · 18 µm
  • C9045 min / side · 128.5 m · 12 µm
  • C12060 min / side · 171.4 m · 9 µm
  • C74

A custom tape is labelled like a real one: C + its total length in minutes. Tape length and thickness follow Appendix B.3 of the specification.

Snap the tab

AB

Recording allowed:

This is not DRM. It protects a finished tape from accidents, like on a real cassette, and anyone can tape over the hole.

05 The paper

Every tape
comes with a story.

Shell, label, J-card cover, spine and back flap, plus a fold-out booklet, liner notes and a dedication. Every image has a physical size in millimetres, so artwork looks the same in every player.

flap 15.9spine 12.7front 63.5 mm
SlotmmRecommended px
Cassette face A / B100.4 × 63.82410 × 1531
Label A / B89.0 × 42.02136 × 1008
J-card front63.5 × 101.61524 × 2438
J-card spine12.7 × 101.6305 × 2438
J-card back flap15.9 × 101.6382 × 2438
Booklet panel63.5 × 101.61524 × 2438
Thumbnailsquare1024 × 1024

24 px/mm recommended, 12 px/mm minimum, aspect within ±1 %. Shell and label images stay transparent over the window and hub holes, so the player's reels turn through them.

06 The reference deck

oTape Studio.

A two-piece hi-fi for your Mac: the SP-2 CD·MP3 source player patched into the OT-1 cassette deck. Drop in your songs, arm REC, press play on the source and let the tape roll in real time. Pause the source and the deck records silence. When you're done, save it and you have a .otape file.

oTape Studio · soon on GitHub macOS 14+ · build with Xcode
oTape Studio: the SP-2 source player connected by a red and white cable to the OT-1 cassette deck, with a cassette inserted and blank C46, C60, C90 and C120 tapes below
  • Records in real timeThe tape head overwrites in place at 44.1 kHz. Blank tape stays blank, and nothing is copied faster than it plays.
  • Blanks from C46 to C120Pick a length off the shelf. The counter, the reels and the remaining time behave like the real thing.
  • A designer for every tapeEight shells, from Ferro Black to Miami Sunset. Label paper, handwriting, J-card, artwork and record tabs.
  • Careful with your filesAAC at 256 kb/s, re-encoding only the sides you changed. Anything another app wrote into the file is kept.

07 For developers

Write a player
in an afternoon.

The spec is open: anyone may implement it, in free or commercial software, without royalties or permission. A minimal player takes about a page of code.

  1. Open the ZIP and read manifest.json. Check format == "oTAPE" and that the major version is 1.
  2. For each side, decode audio.file and treat it as exactly recorded_frames long. The rest of the side is blank tape.
  3. Play from the head position. Wind with FF and REW instead of jumping. Flipping maps position p to L − p.
  4. Draw the cassette from appearance, or from the artwork images where present.
  5. Remember the head position per cassette.id, locally. Playing never modifies the file.
Validate a cassette
# optional: enables the JSON Schema check
pip install -r tools/requirements.txt
python3 tools/otape_validate.py my-mixtape.otape
VALID   my-mixtape.otape

Implementations

NamePlatformRole
oTape StudiomacOS 14+Reference recorder and player, by Jan Osio. Soon on GitHub.
oTAPE Web DeckAny modern browserPlayer, on this page

Building something with oTAPE? Open a pull request to add it to the list.

Own the tape.
Not the platform.

No feed decides what plays next. No account, server or subscription stands between you and a tape someone made for you. oTAPE is open so that your cassettes can outlive every app that plays them, ours included.

No cloud · no accounts · just tapes

Booklet