0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

html-midi-playerのmidiファイル読み込み処理のソースコードを追ってみる

Posted at

ブラウザ上でmidiファイルを再生する手段の1つとしてhtml-midi-playerがあり、以下のページに沿ってmidiファイルのURLをsrcに指定するとmidiファイルが再生されます。

html-midi-player
https://cifkao.github.io/html-midi-player/

上記ページではsrcがhttpsで始まるURLとなっていますが、これをjavascriptでメモリ上に作成した任意のmidiデータにできないか?と思ったので処理を追ってみました。

html-midi-playerのsrcで指定したmidiファイルの取得方法を追ってみる

html-midi-playerのgithub上のソースコードを読んでみると、srcで指定したmidiファイルは以下の箇所で urlToNoteSequence なる関数に this.src として渡されています。

src/player.ts
    try {
      let ns: INoteSequence = null;
      if (initNs) {
        if (this.src) {
          this.ns = null;
          this.ns = await mm.urlToNoteSequence(this.src);
        }

この urlToNoteSequence は上記 src/player.ts に書かれている @magenta/music/esm/core.js ですが、これはローカルで npm i -S @magenta/music@1.23.1 を実行してnode_modulesの中身を確認してみると見れます。

※ネット上で似たようなファイルが出てきますし、core.jsのgithubのリポジトリのコードを読んでも midi_io.ts 内の urlToBlob を呼び出していることに変わりありませんでした。

※冒頭のhtml-midi-playerのページではscriptタグのsrcに npm/@magenta/music@1.23.1/es6/core.js と書いてありますが、 urlToBlob を呼び出しているのは同じでした。

@magenta/music/esm/core/midi_io.js
export function urlToNoteSequence(url) {
    return urlToBlob(url).then(blobToNoteSequence);
}

関数内で呼ばれている urlToBlob は同ファイル内のもので、引数のURLに指定されたものをfetchで取得しています。

@magenta/music/esm/core/midi_io.js
export function urlToBlob(url) {
    return new Promise((resolve, reject) => {
        fetch(url)
            .then((response) => {
            return response.blob();
        })
            .then((blob) => {
            resolve(blob);
        })
            .catch((error) => reject(error));
    });
}

fetchした結果をresponse.blob()しており、レスポンスのblob()の結果が同じであれば、httpsで始まるもの以外がurlToBlobの引数urlに渡ってきても問題ないことになります

httpsで始まるもの以外をmidiとしてsrcに渡す方法

上記よりレスポンスをblob()した結果が同じであれば良いので、これはjavascriptで独自に作ったメモリ上のデータをbase64エンコードして渡したものでもOKということになります

例えば以下のライブラリの writeMidi 関数を使って生成されるデータをbase64エンコードしてhtml-midi-playerのsrcに渡すとmidiが再生されます。

長くなるので詳細は別記事に書きますが、writeMidiした結果をArrayBufferに変換し、それをbase64にエンコードして data:audio/midi;base64, の後にくっつけてURLとして渡せば正常に再生されます。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?