Skip to content


Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?


Failed to load latest commit information.
Latest commit message
Commit time


npm package npm package daily downloads jsDelivr Published on

<midi-player> and <midi-visualizer> HTML elements powered by @magenta/music (Magenta.js), fully stylable and scriptable.

Notable websites that use html-midi-player include, Musical Nexus and demo websites for music generation models: piano infilling, stochastic positional encoding.

If you use html-midi-player on your website, please consider linking back to the repository.

Getting started

  1. Add the necessary scripts to your page:

    <script src=",npm/@magenta/music@1.23.1/es6/core.js,npm/focus-visible@5,npm/html-midi-player@1.5.0"></script>
  2. Add a player and a visualizer:

      sound-font visualizer="#myVisualizer">
    <midi-visualizer type="piano-roll" id="myVisualizer"></midi-visualizer>

That's it!

Besides jsDelivr, the bundle is also available from cdnjs.

Installing from NPM

You can also add the package to your project from NPM, e.g. npm install --save html-midi-player or yarn add html-midi-player. Then you can either:

  • import 'html-midi-player' in your JavaScript code (as an ES Module), or
  • add the node_modules/html-midi-player/dist/midi-player.min.js bundle directly to your page, along with the dependencies (node_modules/tone/build/Tone.js, node_modules/@magenta/music/es6/core.js; note that these need to go before html-midi-player).

In both cases, you should also add the focus-visible polyfill to enable outlines on keyboard focus.

API basics

See also the API reference for both elements: midi-player, midi-visualizer.

src and noteSequence

Both midi-player and midi-visualizer support two different ways of specifying the input file:

  • By setting the src attribute to a MIDI file URL, e.g.:
    <midi-player src="twinkle-twinkle.mid"></midi-player>
    player.src = "twinkle-twinkle.mid";
  • By assigning a Magenta NoteSequence to the noteSequence property, e.g.:
    player.noteSequence = TWINKLE_TWINKLE;


By default, the player will use a simple oscillator synth. To use a SoundFont, add the sound-font attribute:

<midi-player sound-font></midi-player>  <!-- default SoundFont (same as below) -->
<midi-player sound-font=""></midi-player>
player.soundFont = null;  // no SoundFont
player.soundFont = '';    // default SoundFont (same as below)
player.soundFont = '';

See the Magenta.js docs for a list of available SoundFonts.


To make the player loop, use the loop attribute:

<midi-player loop></midi-player>
player.loop = true;

Visualizer settings

The visualizer type is specified via the type attribute. Three visualizer types are supported: piano-roll, waterfall and staff.

Each visualizer type has a set of settings that can be specified using the config attribute, e.g.:

visualizer.config = {
  noteHeight: 4,
  pixelsPerTimeStep: 60,
  minPitch: 30

The settings are documented in the Magenta.js docs.

Binding visualizers

A player supports binding one or more visualizers to it using the visualizer attribute (a selector) or the addVisualizer method:

<midi-player visualizer="#myVisualizer, #myOtherVisualizer"></midi-player>

The visualizer only gets updated while the player is playing, which allows a single visualizer to be bound to multiple players.


  • Only one player can play at a time. Starting a player will stop any other player which is currently playing. (#1) This can actually be a benefit in many cases.
  • Playback position only gets updated on note onsets. This may cause the player to appear stuck.