Code Monkey home page Code Monkey logo

web-midi-player's Introduction

code triage npm version build status publish status

Event-driven JavaScript library that enables MIDI playback in the browser.

We're looking for contributors! Find an issue on our Kanban board and assign it to yourself.

Install

NPM

This library can be installed via NPM, using the default registry:

npm i web-midi-player

Alternatively, you can set up npm to use GPR to install the library. The dependency can be then installed like this:

npm i @yvesgurcan/web-midi-player

Whichever registry you've used, you can then use ES module syntax to load the dependency.

import MidiPlayer from 'web-midi-player';

Or use the CommonJS module system.

const MidiPlayer = require('web-midi-player');

CDN

Alternatively, you can add this library to your project with a script tag.

<script src="https://cdn.jsdelivr.net/npm/web-midi-player@latest/index.js"></script>

The library will be accessible under window['web-midi-player'].default.

<script>
    const { 'web-midi-player': { default: MidiPlayer } } = window;
</script>

Getting started

This package requires MIDI instrument patches compatible with Timidity (.pat files) in order to play audio.

By default, the player loads instrument patches via the jsDeliver CDN.

const midiPlayer = new MidiPlayer();
midiPlayer.play({ url: 'song.mid' });

Alternatively, you can download instrument patches and add them to your project. Make sure to provide the path to the uncompressed files when instantiating the MIDI player.

const midiPlayer = new MidiPlayer({ patchUrl: 'public/patches/' });
midiPlayer.play({ url: 'song.mid' });

Browser compatibility

This library relies on the Web Audio API and more specifically the AudioContext interface to control MIDI playback. This library will not function as expected with browsers that do not fully support this API.

It is currently not possible to use Web Midi Player with any version of Internet Explorer.

Contributing

Make sure to read our code of conduct first.

Something doesn't work? We want to know! Create a new issue.

Want a new feature? Awesome! Open a pull request.

Setup

Clone the repository.

git clone https://github.com/yvesgurcan/web-midi-player

Install dependencies.

npm i

Start development server.

npm start

Continuous integration / Continuous development

This repository uses GitHub Actions to automate certain tasks such as creating releases, publishing to NPM, and running tests.

Related projects

This library was created with the help of:

web-midi-player's People

Contributors

dependabot-preview[bot] avatar dependabot[bot] avatar hkiiita avatar rehasantiago avatar theopetunde2 avatar yvesgurcan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

web-midi-player's Issues

Document how to create custom events

Environment

  • Version of web-midi-player: 1.0.15

Bug

Describe the issue as specifically as possible.

I don't know how to add custom events to the MIDI player. This would be useful if I extend the capabilities of the library in my own project.

Expected behavior

What did you expect to happen?

See steps to follow in the README to create custom events.

Example

Please provide the smallest code sample possible to reproduce the bug.
We recommend using CodePen or JSbin to provide a live example of the issue.

Add example

Demonstrate how this library works on midi.yvesgurcan.com with a code example.

Readme: Add Frequently Asked Questions

Problem

Describe the problem related to this feature request.

I would like to see answers to frequently asked questions.

Solution

What solution do you suggest to solve this problem?

Create the FAQ in the form of a Markdown file.

Bug: Example should fit screen size on small devices

Environment

  • Version of web-midi-player: 1.0.34
  • Browser: Chrome
  • Device: Pixel 3
  • Operating System: Android

Bug

Describe the issue as specifically as possible.

When viewing the example on my phone, there is a lot of black surrounding the player and it looks tiny.

Expected behavior

What did you expect to happen?

The player should fit the size of my screen. Maybe we should use viewport?

Example

Please provide the smallest code sample possible to reproduce the bug.
We recommend using CodePen, JSbin, or CodeSandbox to provide a live example of the issue.

Screenshot_20191222-122812

Bug: fix size of the player container in the example

Environment

  • Version of web-midi-player: 1.0.34
  • Browser: Chrome
  • Device: Pixel 3

Bug

Describe the issue as specifically as possible.

When browsing the example, the "Readme" link is displayed on the next line.

Expected behavior

What did you expect to happen?

When browsing the example, the "Package", "Repository", "Documentation", and "Readme" links should all be on the same line.

Screenshot

Screenshot_20191222-122939

Add section about audio controls in README

Explampify with code how to use pause, resume, and stop in the "Getting started" section of the README and also in the documentation thanks to JSDoc.

/**
* Pauses playback of MIDI input.
* @param {undefined}
* @return {boolean} Whether playback was successfully paused or not.
* @example
* midiPlayer.pause();
*/
pause() {

/**
* Resumes playback of MIDI input.
* @param {undefined}
* @return {boolean} Whether playback was successfully ressumed or not.
* @example
* midiPlayer.resume();
*/
resume() {

* Stops playback of MIDI input.
* @param {undefined}
* @return {boolean} Whether playback was successfully stopped or not.
* @example
* midiPlayer.stop();
*/
stop() {

Bug:

Environment

  • Version of web-midi-player: 1.X.X
  • Browser:

Bug

Describe the issue as specifically as possible.

Expected behavior

What did you expect to happen?

Example

Please provide the smallest code sample possible to reproduce the bug.
We recommend using CodePen, JSbin, or CodeSandbox to provide a live example of the issue.

Replace createScriptProcessor with AudioWorkletNode

Problem

The library uses audioContext.createScriptProcessor. Unfortunately, this feature is getting deprecated: https://developer.mozilla.org/en-US/docs/Web/API/BaseAudioContext/createScriptProcessor#Browser_compatibility.

Solution

We should use AudioWorkletNode instead (https://developer.mozilla.org/en-US/docs/Web/API/AudioWorkletNode). This API uses a separate thread (like WebWorkers) to processor audio, thus improving the user experience when dealing with audio buffer (avoid stuttering and unwanted pauses).

Warning: AudioWorklet is still experimental and only partially supported by browsers. See https://caniuse.com/#search=audioworklet.

Bug:

Environment

  • Version of web-midi-player: 1.X.X
  • Browser:

Bug

Describe the issue as specifically as possible.

Expected behavior

What did you expect to happen?

Example

Please provide the smallest code sample possible to reproduce the bug.
We recommend using CodePen, JSbin, or CodeSandbox to provide a live example of the issue.

Bug:

Environment

  • Version of web-midi-player: 1.X.X
  • Browser:

Bug

Describe the issue as specifically as possible.

Expected behavior

What did you expect to happen?

Example

Please provide the smallest code sample possible to reproduce the bug.
We recommend using CodePen, JSbin, or CodeSandbox to provide a live example of the issue.

Feature: Control the volume of the audio output with `setVolume()`

Problem

Describe the problem related to this feature request.

Playback plays the MIDI at a fixed volume.

Solution

What solution do you suggest to solve this problem?

Offer a way to change the volume. Two methods should be added to the library:

  • midiPlayer.getVolume()
  • midiPlayer.setVolume({ volume: 0.87 })

Feature: Document all event names

Problem

Describe the problem related to this feature request.

It isn't clear from the documentation what the name of the events that are emitted is or when they get emitted.

Solution

What solution do you suggest to solve this problem?

Add these event names (such as MIDI_PLAY and MIDI_ERROR) to the documentation, using JSDoc.

In the documentation, the name of the events should be found in what the relevant methods of the EventHandler return.

For example, for the emitInit method, we could document what it returns with something like that:

 /*
     * Emits an event that indicates that the MIDI player is initialized.
     * @function
     * @param {undefined}
     * @return {object} payload
     * @return {string} payload.event `'MIDI_INIT'`
     * @return {string} payload.message `'MIDI player initialized.'`
  */

emitInit() {
this.emitEvent({
event: MIDI_INIT,
message: 'MIDI player initialized.'
});
}

Feature: Add GitHub actions for GitHub Package Registry

Problem

Describe the problem related to this feature request.

GitHub Actions publish to NPM but not to GitHub Package Registry.

Solution

What solution do you suggest to solve this problem?

Use the release script to publish to GitHub Package Registry.

Create multiple issue templates

Environment

  • Version of web-midi-player: 1.0.15

Bug

Describe the issue as specifically as possible.

The issue template is not formatted to write feature requests or ask questions.

Expected behavior

What did you expect to happen?

  • The issue templates should be found in the docs folder.
  • Templates should use YAML front matter. Issues should be automatically added to the "Library improvements" project.

Example

Please provide the smallest code sample possible to reproduce the bug.
We recommend using CodePen or JSbin to provide a live example of the issue.

Automate version bumps

Problem

It would be great if version bumps could be handled when creating the build in GitHub instead of having to do version bumps manually with npm.

Solution

Create a custom GitHub Action forked from paulhatch/semantic-version (https://github.com/marketplace/actions/git-semantic-version) that takes a github_token.

            - name: Version bump
              uses: paulhatch/semantic-version@v2
              with:
                branch: ${{ github.head_ref }}
                # A string which, if present in a git commit, indicates that a change represents a major change
                major_pattern: "(MAJOR)"
                # Same as above except indicating a minor change
                minor_pattern: "(MINOR)"
                # A string to determine the format of the version output
                format: "${major}.${minor}.${patch}"
                github_token: ${{ secrets.GITHUB_TOKEN }}

Feature: Make all event names exportable

Problem

Describe the problem related to this feature request.

Right now, the logic to process which events are sent by the player requires comparisons of the event names with a string or variables created by the user.

See the React example into this repository:

const MIDI_PLAY = 'MIDI_PLAY';
const MIDI_PAUSE = 'MIDI_PAUSE';
const MIDI_END = 'MIDI_END';
const MIDI_ERROR = 'MIDI_ERROR';

if (payload.event === MIDI_ERROR) {

Strings like 'MIDI_PLAY' or 'MIDI_ERROR' have to be typed or created by the user instead of imported as variables from web-midi-player.

Solution

What solution do you suggest to solve this problem?

Export all event names so that comparing which events are being fired is easier. Something like this:

import MidiPlayer, { EVENTS } from 'web-midi-player';
const { MIDI_PLAY, MIDI_PAUSE, MIDI_STOP, MIDI_ERROR } = EVENTS;

const eventLogger = (payload) => {
  if (payload.event === MIDI_PLAY) {
    console.log('playing');
  }
};

const midiPlayer = new MidiPlayer({ eventLogger });
midiPlayer.play({ url: 'some_file.mid' });

Feature: Make library work with WebKit browsers (Safari)

Problem

Describe the problem related to this feature request.

The library does not work on WebKit-based browsers (such as Safari).

Solution

What solution do you suggest to solve this problem?

Use an HTML object instead of AudioContext.

Feature: Provide duration of MIDI file by calling `getDuration`

Problem

I would like to be able to know how long in seconds is a MIDI file.

I would like to be able to do something like const durationData = midiPlayer.getDuration({ url, arrayBuffer }) to get the duration of the file at url or the duration of the MIDI input in the form of arrayBuffer.

Nice to have: The duration could also be an output of the MIDI_PLAY event.

Add unit tests

  • Implement unit tests using a library such as Jest.
  • Give the option to provide an existing AudioContext to new instances of MidiPlayer for stubbing the Web Audio API and allow users to control the audio context themselves.

Allow users to add their own MIDI files to the React example by storing them in localStorage

Acceptance criteria:

  • Once the code is in production, the changes will be visible at https://midi.yvesgurcan.com/example/react/.
  • A simple form should be visible at the bottom of the list of MIDI files preloaded in the example. The form will have 3 components:
    • A text input field with a placeholder that reads "Enter the URL of a MIDI file." This field only accepts valid URLs such as "https://adomain.com/thefile.mid".
    • Another text input field with a placeholder that reads "Enter a name for your MIDI." This field does not accept more than 60 characters.
    • A button labeled "Add MIDI".
  • When clicking "Add MIDI", the application will store the file in localStorage. If the operation was successful, the name of the MIDI will appear in the list of MIDI files that can be played. If an error occurred, the name of the MIDI will not appear in the list and a message reading "Could not add MIDI file." displays.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.