@onjmin/dtm 0.1.80 → 0.1.82

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -77,6 +77,31 @@ chordPlayer.setVolume(65);
77
77
 
78
78
  ---
79
79
 
80
+ ## 録音・動画エンコード用音声ストリームの取得 (`MediaStream`)
81
+
82
+ 動画ファイル(MP4 / WebM)としてのエクスポートや録音(`MediaRecorder`)を行う場合、`studio` から音声トラックや `MediaStream` を直感的に取得できます。
83
+
84
+ ```ts
85
+ const studio = await createDtmStudio();
86
+
87
+ // 1. 録音・録画用 Audio MediaStreamTrack の取得
88
+ const audioTrack = studio.getAudioStreamTrack();
89
+
90
+ // 2. Canvas 映像トラックと合成して MediaRecorder へ渡す
91
+ const canvasStream = canvas.captureStream(30);
92
+ const combinedStream = new MediaStream([
93
+ ...canvasStream.getVideoTracks(),
94
+ audioTrack,
95
+ ]);
96
+
97
+ const recorder = new MediaRecorder(combinedStream, { mimeType: "video/mp4" });
98
+ recorder.start();
99
+ ```
100
+
101
+ また、`createDtmStudio({ destination })` に `MediaStreamAudioDestinationNode` や自前の `GainNode` を直接渡すことも可能です。`studio.masterGain` を参照して自作の Web Audio エフェクトやミキサーにルーティングすることもできます。
102
+
103
+ ---
104
+
80
105
  ## 再生機能・API 一覧
81
106
 
82
107
  用途や UI の有無、歌声対応の有無に応じた各種再生関数が用意されています。
package/dist/index.d.mts CHANGED
@@ -1686,6 +1686,11 @@ type DtmStudioOptions = {
1686
1686
  masterVolume?: number;
1687
1687
  /** ドラム音量 0-1。既定 1。 */
1688
1688
  drumVolume?: number;
1689
+ /**
1690
+ * 最終出力先の AudioNode。未指定時は audioCtx.destination(スピーカー)。
1691
+ * MediaStreamAudioDestinationNode や GainNode を指定できます。
1692
+ */
1693
+ destination?: AudioNode;
1689
1694
  /**
1690
1695
  * 歌声合成ワーカー(voice-worker.js)のURL。
1691
1696
  * 既定はパッケージ同梱の dist/voice-worker.js。
@@ -1821,6 +1826,18 @@ type ModeSwitchInstance = {
1821
1826
  type DtmStudio = {
1822
1827
  /** 内部で使用している AudioContext。 */
1823
1828
  audioContext: AudioContext;
1829
+ /** マスターゲインノード(全音色の最終出力先)。 */
1830
+ masterGain: GainNode;
1831
+ /**
1832
+ * 録画・録音用の MediaStreamAudioDestinationNode を生成/取得する。
1833
+ * masterGain が接続され、その stream から音声トラックを取得できます。
1834
+ */
1835
+ createMediaStreamDestination: () => MediaStreamAudioDestinationNode;
1836
+ /**
1837
+ * 録画・録音用の Audio MediaStreamTrack を取得する。
1838
+ * MediaRecorder のストリーム合成(canvas + audio)に使えます。
1839
+ */
1840
+ getAudioStreamTrack: () => MediaStreamTrack;
1824
1841
  /** 歌声合成ヘルパ(klatt + koe音源)。 */
1825
1842
  singingVoices: SingingVoices;
1826
1843
  /** 編集UI(mountDAW)を音・歌声込みでマウントする。 */
package/dist/index.d.ts CHANGED
@@ -1686,6 +1686,11 @@ type DtmStudioOptions = {
1686
1686
  masterVolume?: number;
1687
1687
  /** ドラム音量 0-1。既定 1。 */
1688
1688
  drumVolume?: number;
1689
+ /**
1690
+ * 最終出力先の AudioNode。未指定時は audioCtx.destination(スピーカー)。
1691
+ * MediaStreamAudioDestinationNode や GainNode を指定できます。
1692
+ */
1693
+ destination?: AudioNode;
1689
1694
  /**
1690
1695
  * 歌声合成ワーカー(voice-worker.js)のURL。
1691
1696
  * 既定はパッケージ同梱の dist/voice-worker.js。
@@ -1821,6 +1826,18 @@ type ModeSwitchInstance = {
1821
1826
  type DtmStudio = {
1822
1827
  /** 内部で使用している AudioContext。 */
1823
1828
  audioContext: AudioContext;
1829
+ /** マスターゲインノード(全音色の最終出力先)。 */
1830
+ masterGain: GainNode;
1831
+ /**
1832
+ * 録画・録音用の MediaStreamAudioDestinationNode を生成/取得する。
1833
+ * masterGain が接続され、その stream から音声トラックを取得できます。
1834
+ */
1835
+ createMediaStreamDestination: () => MediaStreamAudioDestinationNode;
1836
+ /**
1837
+ * 録画・録音用の Audio MediaStreamTrack を取得する。
1838
+ * MediaRecorder のストリーム合成(canvas + audio)に使えます。
1839
+ */
1840
+ getAudioStreamTrack: () => MediaStreamTrack;
1824
1841
  /** 歌声合成ヘルパ(klatt + koe音源)。 */
1825
1842
  singingVoices: SingingVoices;
1826
1843
  /** 編集UI(mountDAW)を音・歌声込みでマウントする。 */
package/dist/index.js CHANGED
@@ -7062,9 +7062,10 @@ var loadDrumFont = (ctx, pitch) => {
7062
7062
  return p;
7063
7063
  };
7064
7064
  var BAR_SEP = /[|ll→]/;
7065
+ var toHalfWidth = (str) => str.replace(/[!-~]/g, (ch) => String.fromCharCode(ch.charCodeAt(0) - 65248)).replace(/ /g, " ");
7065
7066
  var NON_EVENT_RE = /^[=_]$|^N\.C\.$|^N$/i;
7066
7067
  var buildDisplayLines = (chords, eventsCount) => {
7067
- const rawLines = chords.split("\n").map((l) => l.trim()).filter((l) => l);
7068
+ const rawLines = toHalfWidth(chords).split("\n").map((l) => l.trim()).filter((l) => l);
7068
7069
  const displayLines = [];
7069
7070
  let eventCounter = 0;
7070
7071
  let colorIdx = 0;
@@ -14797,8 +14798,22 @@ var createDtmStudio = async (options = {}) => {
14797
14798
  const g = Math.max(0, Math.min(100, volume)) / 100;
14798
14799
  masterGain.gain.setValueAtTime(g, audioCtx.currentTime);
14799
14800
  };
14801
+ let recordDestNode = null;
14802
+ const createMediaStreamDestination = () => {
14803
+ if (!recordDestNode) {
14804
+ recordDestNode = audioCtx.createMediaStreamDestination();
14805
+ masterGain.connect(recordDestNode);
14806
+ }
14807
+ return recordDestNode;
14808
+ };
14809
+ const getAudioStreamTrack = () => {
14810
+ return createMediaStreamDestination().stream.getAudioTracks()[0];
14811
+ };
14800
14812
  return {
14801
14813
  audioContext: audioCtx,
14814
+ masterGain,
14815
+ createMediaStreamDestination,
14816
+ getAudioStreamTrack,
14802
14817
  singingVoices,
14803
14818
  mountEditor,
14804
14819
  mountPlayer,
package/dist/index.mjs CHANGED
@@ -6939,9 +6939,10 @@ var loadDrumFont = (ctx, pitch) => {
6939
6939
  return p;
6940
6940
  };
6941
6941
  var BAR_SEP = /[|ll→]/;
6942
+ var toHalfWidth = (str) => str.replace(/[!-~]/g, (ch) => String.fromCharCode(ch.charCodeAt(0) - 65248)).replace(/ /g, " ");
6942
6943
  var NON_EVENT_RE = /^[=_]$|^N\.C\.$|^N$/i;
6943
6944
  var buildDisplayLines = (chords, eventsCount) => {
6944
- const rawLines = chords.split("\n").map((l) => l.trim()).filter((l) => l);
6945
+ const rawLines = toHalfWidth(chords).split("\n").map((l) => l.trim()).filter((l) => l);
6945
6946
  const displayLines = [];
6946
6947
  let eventCounter = 0;
6947
6948
  let colorIdx = 0;
@@ -14673,8 +14674,22 @@ var createDtmStudio = async (options = {}) => {
14673
14674
  const g = Math.max(0, Math.min(100, volume)) / 100;
14674
14675
  masterGain.gain.setValueAtTime(g, audioCtx.currentTime);
14675
14676
  };
14677
+ let recordDestNode = null;
14678
+ const createMediaStreamDestination = () => {
14679
+ if (!recordDestNode) {
14680
+ recordDestNode = audioCtx.createMediaStreamDestination();
14681
+ masterGain.connect(recordDestNode);
14682
+ }
14683
+ return recordDestNode;
14684
+ };
14685
+ const getAudioStreamTrack = () => {
14686
+ return createMediaStreamDestination().stream.getAudioTracks()[0];
14687
+ };
14676
14688
  return {
14677
14689
  audioContext: audioCtx,
14690
+ masterGain,
14691
+ createMediaStreamDestination,
14692
+ getAudioStreamTrack,
14678
14693
  singingVoices,
14679
14694
  mountEditor,
14680
14695
  mountPlayer,
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "author": "onjmin",
3
3
  "license": "MIT",
4
4
  "name": "@onjmin/dtm",
5
- "version": "0.1.80",
5
+ "version": "0.1.82",
6
6
  "description": "MMLを中間言語に用いた、モバイルファーストなDAW / ピアノロール打ち込みコンポーネント",
7
7
  "homepage": "https://onjmin.github.io/dtm",
8
8
  "repository": {