Node For Max ③ ~MongoDBと接続する~
引き続き Node For Max 触ってます。
前回・前々回と HTTP で別サービスと連携する記事を書きました。
今回はローカルに立ち上げたデータベースに接続して、データを取得するプログラムを書いてみます。
データベースの種類は何でもいいのですが、オブジェクト構造をそのまま扱える方が嬉しいので、MongoDB を利用します。
MongoDB とは
NoSQL のドキュメント指向データベースの一種です。表形式で表現できないようなデータを柔軟に扱えます。
オープンソースとして提供されていて、Docker Hub に公式のイメージも用意されています。
今回はこちらのイメージを使って、MongoDB のコンテナを立ち上げようと思います。
docker の話は今回できないので、興味ある方は調べてみてください。
MongoDB をローカル PC に直インストールでも問題ありません!
ゴール
MongoDB に保存した音源ファイル名を取得して、指定した音源を再生するプログラムを作成する。
音源とメタデータには、GDC Game Audio Bundles が無償で提供しているバンドルを利用しようと思います。
成果物はこちらです。
開発
MongoDBの用意
ローカルに直接インストールした方は、ここは無視してください。
node-for-max データベースとユーザーの作成だけしてください。
公式の docker イメージからビルドして、27017 ポートでアクセスできるようにします。docker-compose ファイルは下記の通りです。
version: "3.1"
services:
mongo:
image: mongo:6.0.8
environment:
MONGO_INITDB_DATABASE: node-for-max
MONGO_INITDB_ROOT_USERNAME: node-for-max
MONGO_INITDB_ROOT_PASSWORD: n4m
ports:
- 27017:27017
docker コンテナを立ち上げる
docker compose -p node-for-max-mongodb up -d
データの用意
GDCが音源リストをSpreadSheetで公開しているので、これをCSVで出力して、そのままMongoDBにインポートします。
fileName / libraryName / supplier のプロパティがありますね。
データ取得プロセス部分の開発
MongoDB の公式が Node.js 用のドライバーを提供してくれているので、こちらをインストールします。
npm i --save mongodb
npm i --save-dev @types/mongodb
以下 2 つの機能を開発します。
①supplierの一覧取得
②指定したsupplierを条件に、ファイル名をMongoDBから取得
const main = async () => {
// MongoDB と接続
const manager = new MongoDBClientManager();
const db = await manager.getDb();
// gdcarchive コレクションから、supplier の一覧を取得
const supplierList = await db.collection('gdcArchive').distinct('supplier', {});
// Max の outlet から結果を出力
MaxAPI.outlet(supplierList);
// MongoDB 切断
await manager.close();
}
const main = async () => {
// MongoDB と接続
const manager = new MongoDBClientManager();
// Max の inlet から supplier 情報を取得して検索条件作成
MaxAPI.addHandler(MaxAPIStatic.MESSAGE_TYPES.DICT, async (...args: {[key: string]: string | number | boolean}[]) => {
const filter: Partial<Filter> = {};
const filterSet = new Set(dataProperties);
for (const [key, value] of Object.entries(args[0])) {
if(filterSet.has(key)) Object.assign(filter, {[key]: value});
}
// gdcarchive コレクションから、指定した supplier の音源ファイル名を取得
const db = await manager.getDb();
const soundFiles = await db.collection('gdcArchive').fid(filter).toArray();
const soundFilePathList: string[] = [];
soundFiles.forEach(soundFile => {
soundFilePathList.push(soundFile.fileName);
});
// 取得したファイル名を出力
MaxAPI.outlet(soundFilePathList);
await manager.close();
});
}
Max の開発
Max の開発script start 後に、①のプロセスが supplier を取得してくれます。それをリスト形式表示しておきます。
リストからsupplierを選択すると②が実行されて、マッチするファイル名のリストが出力されます。
ファイル名リストから選択すると、指定した音源が読み込まれて再生されます。
※ 起動時に音源ファイルのパスを指定するウィンドウが開くので、ダウンロードしたディレクトリを選択してください。
おわりに
巨大なデータを読み込ませると OOM の危険性が上がるので、データは一旦データベースに持たせて、必要な分だけ読み込むといったことができますね。
Max も一応、配列だったり辞書型を扱えるけど、そういったオブジェクト操作はかなり苦手です。
UI のオブジェクトも充実しているところが Max のいいところですが、適材適所で責任分離したいです。
そのうち、音源リストの表示や選択部分を別アプリケーションに任せたバージョンを作ってみようと思います。
この記事が気に入ったらサポートをしてみませんか?