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
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.
-
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.
-
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.
-
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. -
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.
-
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.
-
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.
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.
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
{
"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\x04at 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
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.
| Slot | mm | Recommended px |
|---|---|---|
| Cassette face A / B | 100.4 × 63.8 | 2410 × 1531 |
| Label A / B | 89.0 × 42.0 | 2136 × 1008 |
| J-card front | 63.5 × 101.6 | 1524 × 2438 |
| J-card spine | 12.7 × 101.6 | 305 × 2438 |
| J-card back flap | 15.9 × 101.6 | 382 × 2438 |
| Booklet panel | 63.5 × 101.6 | 1524 × 2438 |
| Thumbnail | square | 1024 × 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.
- 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.
- Open the ZIP and read
manifest.json. Checkformat == "oTAPE"and that the major version is 1. - For each side, decode
audio.fileand treat it as exactlyrecorded_frameslong. The rest of the side is blank tape. - Play from the head position. Wind with FF and REW instead of jumping. Flipping maps position p to L − p.
- Draw the cassette from
appearance, or from theartworkimages where present. - Remember the head position per
cassette.id, locally. Playing never modifies the file.
# 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
| Name | Platform | Role |
|---|---|---|
| oTape Studio | macOS 14+ | Reference recorder and player, by Jan Osio. Soon on GitHub. |
| oTAPE Web Deck | Any modern browser | Player, 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