{
  "apiVersion": 1,
  "id": "voicevox",
  "name": "VOICEVOX で読み上げ",
  "version": "1.0.0",
  "minAppVersion": "1.1.0",
  "description": "この Mac（127.0.0.1）で動いている VOICEVOX にコメントを渡して読み上げます。音はこのアプリが鳴らします。VOICEVOX を先に起動しておいてください。",
  "hosts": [
    "127.0.0.1",
    "localhost"
  ],
  "windows": [
    "question",
    "moderator",
    "paid"
  ],
  "settings": [
    {
      "key": "port",
      "label": "VOICEVOX のポート",
      "type": "number",
      "default": 50021,
      "min": 1024,
      "max": 65535,
      "help": "VOICEVOX の設定＞エンジンで確かめられます（既定は 50021）"
    },
    {
      "key": "speaker",
      "label": "話者の ID",
      "type": "number",
      "default": 3,
      "min": 0,
      "max": 999,
      "help": "VOICEVOX の話者（スタイル）の番号。例: 3 = ずんだもん（ノーマル）・2 = 四国めたん（ノーマル）・8 = 春日部つむぎ。一覧は http://127.0.0.1:50021/speakers"
    },
    {
      "key": "speed",
      "label": "話す速さ（1 が標準）",
      "type": "number",
      "default": 1.2,
      "min": 0.5,
      "max": 2
    },
    {
      "key": "readName",
      "label": "名前も読む",
      "type": "bool",
      "default": true
    },
    {
      "key": "readAmount",
      "label": "スパチャ・ステッカーの金額を読む",
      "type": "bool",
      "default": true
    },
    {
      "key": "maxLength",
      "label": "読む長さの上限（文字）",
      "type": "number",
      "default": 60,
      "min": 10,
      "max": 300,
      "help": "長いコメントはここで切り、「以下略」と読みます"
    }
  ],
  "script": "// VOICEVOX で読み上げる連携プラグイン（GDR-APP-009 / GDR-INFRA-010）。\n// 本体から onComment(event, settings) でコメントが 1 件ずつ届く。VOICEVOX の audio_query → synthesis で WAV を作り、host.play で本体に鳴らしてもらう。\n\n/** 読み上げる文（名前・金額・本文）を作る。読むものがなければ空文字。 */\nfunction buildText(event, settings) {\n  var body = cleanText(event.text || \"\");\n  var max = Math.max(10, Math.floor(settings.maxLength || 60));\n  if (body.length > max) body = body.slice(0, max) + \"、以下略\";\n  var parts = [];\n  if (settings.readName && event.author) parts.push(cleanName(event.author) + \"さん\");\n  if (settings.readAmount && event.amount) parts.push(event.amount);\n  if (event.kind === \"newMember\") parts.push(\"メンバー加入\");\n  if (event.kind === \"membershipGifting\") parts.push(\"メンバーシップのギフト\");\n  if (body) parts.push(body);\n  // 名前だけ（本文のないテキスト）は読まない\n  if (!body && (event.kind === \"text\" || !event.kind)) return \"\";\n  return parts.join(\"、\");\n}\n\n/** カスタム絵文字のショートコード・URL を除き、「www」を「わら」にする。 */\nfunction cleanText(text) {\n  return text\n    .replace(/https?:\\/\\/\\S+/g, \"\")\n    .replace(/:[^:\\s]+:/g, \"\")\n    .replace(/[wｗ]{3,}/g, \"わら\")\n    .replace(/\\s+/g, \" \")\n    .trim();\n}\n\n/** 名前の先頭の @ と末尾の「-xxx」（ハンドルの数字・記号）を除く。 */\nfunction cleanName(name) {\n  return name.replace(/^@/, \"\").replace(/-[0-9a-z]{2,}$/i, \"\");\n}\n\nasync function onComment(event, settings) {\n  var text = buildText(event, settings);\n  if (!text) return;\n  var base = \"http://127.0.0.1:\" + Math.floor(settings.port || 50021);\n  var speaker = Math.floor(settings.speaker || 0);\n  var query = await host.fetch(base + \"/audio_query?speaker=\" + speaker + \"&text=\" + encodeURIComponent(text), { method: \"POST\" });\n  if (query.status !== 200) throw new Error(\"VOICEVOX の audio_query が \" + query.status + \" を返しました（VOICEVOX は起動していますか？）\");\n  var audioQuery = JSON.parse(query.text);\n  audioQuery.speedScale = settings.speed || 1;\n  var wav = await host.fetch(base + \"/synthesis?speaker=\" + speaker, {\n    method: \"POST\",\n    headers: { \"Content-Type\": \"application/json\" },\n    body: JSON.stringify(audioQuery),\n    as: \"base64\",\n  });\n  if (wav.status !== 200) throw new Error(\"VOICEVOX の synthesis が \" + wav.status + \" を返しました\");\n  // 再生の待ち行列に積んだら戻る（鳴らすのは本体が順に行う）\n  await host.play({ data: wav.base64, type: \"audio/wav\" });\n}\n\nif (typeof module !== \"undefined\") module.exports = { buildText, cleanText, cleanName };\n",
  "readme": "# VOICEVOX で読み上げ\n\nこの Mac で動いている [VOICEVOX](https://voicevox.hiroshiba.jp/) に、選んだ窓のコメントを渡して読み上げます。音はこのアプリが鳴らします。\n\n## はじめに\n\n1. VOICEVOX を起動しておきます（エンジンが `http://127.0.0.1:50021` で動きます）\n2. 「詳しい設定」で、渡す窓・話者・速さを選びます\n3. 「試しに送る」で鳴るか確かめます\n\n## 設定\n\n- **話者の ID**: VOICEVOX の話者（スタイル）の番号。例: 3 = ずんだもん（ノーマル）・2 = 四国めたん（ノーマル）・8 = 春日部つむぎ。一覧は VOICEVOX を起動した状態で `http://127.0.0.1:50021/speakers` を開くと見られます\n- **窓ごとに声を変える**: 「連携先を足す」で連携先を窓ごとに作り、それぞれで話者を選びます\n- **読む長さの上限**: 長いコメントはここで切り、「以下略」と読みます\n\n## 困ったとき\n\n- 鳴らない: VOICEVOX が起動しているか、「詳しい設定」の最後の誤りを見ます。音の出力先は Mac の既定の出力です\n- 読み上げが遅れる: 渡す窓からメインを外すか、「待てる件数」を減らします（待ちが上限を超えると古いものから捨てます）\n- iPad: iPad の中で VOICEVOX は動かないので、このプラグインは iPad では使えません\n"
}
