The Web MiniDisc App

Bringing back to life the MiniDisc with WebUSB and WASM

If you’ve never heard of the MiniDisc don’t worry, you’re not alone.

If you’re curious, you can catch up by reading the Wikipedia page, or the old community portal minidisc.org, or interact with the reddit community of /r/minidisc.

If you’re not, long story short, it’s a dead music format released by Sony at the beginning of the ‘90s, that was slowly killed by the popularity of the many MP3 players that started coming out in the early 2000s.

Some of the last MiniDisc players, branded as NetMD units, were equipped with a USB port that allowed for recording music onto the device by using the infamously SonicStage software (Windows only, of course). When Sony abandoned the MiniDisc, that software was left unmaintained and, nowadays, it can’t run outside virtual machines or without using dangerously unsigned drivers.

Luckily the OSS community managed to completely reverse engineer the NetMD protocol and, before the death of the MiniDisc, the linux-minidisc project was released.

A few of weeks ago, just before the infamously Coronavirus lockdown here in Italy, I’ve been lucky enough to find my old MZ-N710 in my parents’ basement. Determined to make it work on my Macbook, I brought it home and successfully managed to compile and run the linux-minidisc CLI.

Porting the MiniDisc to Web

The process for uploading the music via the CLI was comprised of 2 steps:

  1. Convert your music
    • Use ffmpeg [1] to create a 16bit 44100Hz pcm wav file (SP quality)
    • Use atrac3denc [2] to create a 132/66 Kbit ATRAC3 file (LP2/LP4 quality)
  2. Use the CLI to send the converted music to the device

Not the most user friendly process for those who’re not fancy to type commands in a terminal.

So, after pondering for a while, I realized these steps could have been encapsulated in a no-install-required progressive web app, for a considerable step up in the ease of the process.

I would just use:

1. Writing a library

I started by porting the code from linux-minidisc to a new JS library that I’ve now published on npm, called netmd-js[3].

This library implements the NetMD protocol and takes care of the USB communication with the device. It will also allow other devs to write their own app, should mine not suit their needs.

It runs either in nodejs and in every browser supporting the WebUSB standard, and uses Worker Threads[4] or Web Workers[5] to speed up the music encryption step required by the protocol. The encryption has been implemented on top of CryptoJS[6].

2. Using emscripten

I was lucky enough to find a project called ffmpeg.js[7] that already ported ffmpeg to WASM. So, the only thing left to do was to configure it properly and recompile, just to trim down the binary size. A full tutorial is available in the GitHub page of ffmpeg.js.

Then, I’ve followed a similar process to cross compile the atracdenc encoder and eventually write a simple JS wrapper around it.

3. The Web MiniDisc Application

After gathering all the bricks together, I’ve shifted my focus to design the app’s user interface and experience.

Web MiniDisc App Wireframe

A dead simple user experience

Then I started off with the classic create react app + TypeScript template, and added redux and material-ui components… a no-frills setup.

How to use a NetMD device in 2020

A couple of nights later I was ready to record the first demo of the the Web MiniDisc Application.

It has been exciting to see the app work seamlessly both on my Macbook and on my Android phone without an if needed.

Public launch

Honestly, there aren’t many places to launch a MiniDisc app in 2020 :)
It’s a pretty tiny niche.

However, I have been lurking for some time in /r/minidisc and decided to start from there. The feedback was great, and people even responded with a few bug reports and feature requests.

If you’re a lucky owner of a NetMD device, you can try the app yourself at

https://stefano.brilli.me/webminidisc/

Or, if you just want to browse the code, everything’s available on GitHub.

https://github.com/cybercase/webminidisc

References

  1. FFmpeg, https://ffmpeg.org/
  2. atracdenc, https://github.com/dcherednik/atracdenc
  3. netmd-js, https://github.com/cybercase/netmd-js
  4. Worker Threads, https://nodejs.org/api/worker_threads.html
  5. Web Workers, https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers
  6. CryptoJS, https://code.google.com/archive/p/crypto-js/
  7. ffmpeg.js, https://github.com/ffmpegjs/ffmpeg.js
  8. WebUSB, https://wicg.github.io/webusb/
  9. emscripten, https://emscripten.org/
  10. React, https://reactjs.org/

– 26/03/2020