（・(ｪ)・）ｾｯｼｮﾝｸﾏｰ（・(ｪ)・）

<blockquote class="twitter-tweet"><p lang="und" dir="ltr">🔔🐻🐻🎤 <a href="https://t.co/W97eP3wr3J">pic.twitter.com/W97eP3wr3J</a></p>&mdash; 🐸 (@_coboco) <a href="https://twitter.com/_coboco/status/1606232913384595456?ref_src=twsrc%5Etfw">December 23, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
※ミュートを解除して再生してください。

# しくみ
サーボモーターを2個、それぞれぬいぐるみの右手と左手の後ろにくっつけてます。
手作りの温もりを感じますね。
![PXL_20221223_102338934.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152304/97ab0661-14d5-7ea1-1c6e-2b95f3be6344.jpeg)
![PXL_20221223_103200138.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152304/ee93e96a-e840-aeb3-b073-0ee8da0436e8.jpeg)

# ソースコード
開発デバイスにはobnizを使用しました。
```javascript
<html>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" />
    <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
    <script src="https://unpkg.com/obniz@3.x/obniz.js" crossorigin="anonymous" ></script>
  </head>
  <body>
    <div id="obniz-debug"></div>
    <script>
      var obniz = new Obniz("OBNIZ_ID_HERE");

      let isPlaying = false;  // 演奏中フラグ
      let idx = 0;            // 角度情報の配列インデックス（上げ下げの状態切替用）

      // called on online
      obniz.onconnect = async function() {
        // 右手
        const handRight = {
            servo: obniz.wired("ServoMotor", { gnd: 0, vcc: 1, signal: 2 }),
            angle: [150 , 80]  // 0:下げる, 1:上げる
        };
        // 左手
        const handLeft = {
            servo: obniz.wired("ServoMotor", { gnd: 3, vcc: 4, signal: 5 }),
            angle: [0, 80]  // 0:下げる, 1:上げる
        };

        // 音声認識用
        const recognition = new window.webkitSpeechRecognition();
        recognition.lang = "ja-JP";

        // 音声を認識した時の処理
        recognition.onresult = async function(event) {
          let inputWord = event.results[0][0].transcript;
          if (inputWord === "クリスマスソングを歌って") {
            await obniz.wait(5000);
            isPlaying = true;
          } else if (inputWord === "演奏を止めて") {
            isPlaying = false;
            // 両手をおろす
            handRight.servo.angle(handRight.angle[0]);
            handLeft.servo.angle(handLeft.angle[0]);
          }
        };

        // 音声認識サービスが切断されたら、再開する
        recognition.onend = async function(event) {
          recognition.start();
        };

        // 音声認識開始
        recognition.start();
        

        // called while online.
        obniz.onloop = async function() {
          if(isPlaying) {
            // 手を交互に上げ下げする
            handRight.servo.angle(handRight.angle[idx]);
            handLeft.servo.angle(handLeft.angle[1-idx]);
            idx = 1-idx;
            await obniz.wait(2000);
          }
        };
      };
      
      // called on offline
      obniz.onclose = async function() {
        
      };
    </script>
  </body>
</html>
```

Clovaに話しかけた言葉でハンドベルクマも同時に動かします。

まず音声認識を開始して待機します。聞き耳を立てるわけですね。
「クリスマスソングを歌って」というフレーズが聞こえたら、2秒おきにサーボの角度を変更し、片方の手が上、もう片方の手が下になるように動かします。
「演奏を止めて」というフレーズが聞こえたら、サーボを動かす繰り返し処理を終了します。

二匹を確実に同期させるにはClovaスキルからハンドベルクマを呼び出すようにしたほうがいいと思いますが、
まあこれはこれで、カラオケで勝手に割り込んで来る人って感じ（？）で良いのではないでしょうか。