MusicXML で楽譜を出力する

投稿日:2026/3/4

web ページ作成

MusicXML

音楽

メモ

Gemini に聞きながら(というかほぼ丸投げで)MusicXML を用いて web ページ上に楽譜を出力出来るようになったので,少しく書き留めておく.

Open Sheet Music Display というライブラリを用いて MusicXML を出力することが出来る.npm install opensheetmusicdisplay によって osmd をインストールし,次のようなコンポーネントを追加する(内容に関しては私はあまり理解していない).

MusicXmlScore.astro
---
// src/components/MusicXmlScore.astro
const { scoreUrl = "/scores/sample.musicxml", zoom = 0.8} = Astro.props;
---

{/* カスタムタグ(<music-score>)でラップし、必要なデータを data-* 属性で渡します */}
<music-score data-score={scoreUrl} data-zoom={zoom}>
  <div id={scoreUrl} class="score-container" style="width: 100%; height: auto;"></div>
</music-score>

<script>
  // Viteのバンドル対象になるので、npmパッケージのインポートが正常に機能します
  import { OpenSheetMusicDisplay } from "opensheetmusicdisplay";

  class MusicScore extends HTMLElement {
    async connectedCallback() {
      // this.querySelector でこのコンポーネント内の div だけを取得
      const container = this.querySelector(".score-container");
      if (!container) return;

      // data-* 属性から値を取得
      const scoreUrl = this.dataset.score;
      const zoomLevel = parseFloat(this.dataset.zoom || "1.0");

      const osmd = new OpenSheetMusicDisplay(container);

      osmd.setOptions({
        drawTitle: false,
        drawPartNames: false,
        defaultColorMusic: "#FFFFFF",
        defaultColorLabel: "#FFFFFF",
        newSystemFromXML: true,
        drawingParameters: "compacttight",
      });

      await osmd.load(scoreUrl);
      osmd.zoom = zoomLevel;
      osmd.render();
    }
  }

  // カスタム要素としてブラウザに登録
  customElements.define("music-score", MusicScore);
</script>

あとは public/scores/.musicxml ファイルを置き,楽譜を表示したいページで import して(私の場合 import MusicXmlScore from '../../components/MusicXmlScore.astro'; )楽譜を置きたい場所に

<MusicXmlScore scoreUrl="/scores/20260304_2.musicxml"/>

と書けば良い.

.musicxml ファイルは直接書くこともできるが,MuseScore などのソフトウェアで作った楽譜を .musicxml で出力した方が簡便である(それでも面倒ではあるが).

例えば

example.musicxml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE score-partwise PUBLIC "-//Recordare//DTD MusicXML 3.1 Partwise//EN" "http://www.musicxml.org/dtds/partwise.dtd">
<score-partwise version="3.1">
  <identification>
    <encoding>
      <software>MuseScore 3.6.2</software>
      <encoding-date>2026-03-05</encoding-date>
      <supports element="accidental" type="yes"/>
      <supports element="beam" type="yes"/>
      <supports element="print" attribute="new-page" type="no"/>
      <supports element="print" attribute="new-system" type="no"/>
      <supports element="stem" type="yes"/>
      </encoding>
    </identification>
  <part-list>
    <score-part id="P1"></score-part>
    </part-list>
  <part id="P1">
    <measure number="1">
      <attributes>
        <divisions>2</divisions>
        <key>
          <fifths>-3</fifths>
        </key>
        <time symbol="cut">
          <beats>2</beats>
          <beat-type>2</beat-type>
        </time>
        <clef>
          <sign>G</sign>
          <line>2</line>
        </clef>
      </attributes>
      <note>
        <pitch>
          <step>C</step>
          <octave>5</octave>
        </pitch>
        <duration>4</duration>
        <type>half</type>
        <stem>down</stem>
      </note>
      <note>
        <pitch>
          <step>E</step>
          <alter>-1</alter>
          <octave>5</octave>
        </pitch>
        <duration>4</duration>
        <type>half</type>
        <stem>down</stem>
      </note>
    </measure>
    <measure number="2">
      <note>
        <pitch>
          <step>G</step>
          <octave>5</octave>
        </pitch>
        <duration>4</duration>
        <type>half</type>
        <stem>down</stem>
      </note>
      <note>
        <pitch>
          <step>A</step>
          <alter>-1</alter>
          <octave>5</octave>
        </pitch>
        <duration>4</duration>
        <type>half</type>
        <stem>down</stem>
      </note>
    </measure>
    <measure number="3">
      <note>
        <pitch>
          <step>B</step>
          <octave>4</octave>
        </pitch>
        <duration>4</duration>
        <type>half</type>
        <accidental>natural</accidental>
        <stem>down</stem>
      </note>
        <barline location="right">
          <bar-style>none</bar-style>
        </barline>
    </measure>
  </part>
</score-partwise>

というコードによって

が得られる.