twtjudy1128
@twtjudy1128 (Juri Tawata)

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

Javascriptで条件つきでmp3を再生できるようにしたい

質問したいこと

ある条件のときだけ、mp3ファイルを再生できるようにしたいです。

作品の全体像としては、サイトを開くとカメラが起動し、
手を挙げていない場合のみ音が鳴るようなものを作ろうと思っています。

Teachable Machineで、画像モデルを作成していて、
「hands up」(手を挙げている状態)か「none」(手を挙げていない状態)かを検出するところまではできています。

出ているエラーなど

コンソールには特にエラーは出ていないです。。。

ソースコード

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Hands Up!!!</title>
  </head>
  <body>
    <h1>Freeze!! Hands Up!!</h1>
    <video id="video" width="640" height="480" autoplay></video>
    <audio id="sound-file" preload="auto">
        <source src="sniperrifle--firing1.mp3" type="audio/mp3" controls>
    </audio>
    <script src="https://unpkg.com/ml5@latest/dist/ml5.min.js"></script>
    <script>
      // Model URL
      const imageModelURL = 'https://teachablemachine.withgoogle.com/models/id9DYiz3Y/';

      async function main() {
        // カメラからの映像取得
        const stream = await navigator.mediaDevices.getUserMedia({
          audio: false,
          video: true,
        });
        // html内のidがvideoのdomを取得
        const video = document.getElementById('video');
        // videoにカメラ映像を適用
        video.srcObject = stream;

        // 自作モデルのロード
        classifier = ml5.imageClassifier(
          imageModelURL + 'model.json',
          video,
          modelLoaded
        );
        // モデルのロード完了時に実行される
        function modelLoaded() {
          console.log('Model Loaded!');
        }
        // 繰り返し検出処理
        classifier.classify(onDetect);
        function onDetect(err, results) {
          console.log(results);
          if (results[0]) {
            console.log(results[0].label);
          }

          classifier.classify(onDetect);
        }
        //手を挙げてないときに音を出す
        if(results[0].label==='none'){
            function sound(){
            // 初回以外は音声ファイルを巻き戻す(再生位置[秒]を0に設定する)
            if( typeof( document.getElementById('sound-file').currentTime ) != 'undefined' ){
                document.getElementById('sound-file').currentTime = 0;
            }
            //音声ファイルを再生する
            document.getElementById('sound-file').play();
            }
        }

      }
      main();
    </script>
  </body>
</html>

試したこと

mp3ファイルがおかしいのかなと思ったのですが、同じフォルダ内に格納はできています。
https://syncer.jp/html5-javascript-hello-button
こちらのサイトを参考にしました。

デバックが苦手で申し訳ないのですが、どこがおかしいのか気づいた方いたら教えていただけると幸いです。

宜しくお願い致します。

0

1Answer

ログに埋もれているだけで、エラー出ますね。

test.html:51 Uncaught (in promise) ReferenceError: results is not defined
    at main (test.html:51)
  • 音声再生判定コードの位置がおかしい (上記エラー)
  • sound 関数が書かれているだけで呼び出されていない
  • 他、変数宣言などの抜け

を修正すると以下のように。

<script>タグ内
// Model URL
const imageModelURL = 'https://teachablemachine.withgoogle.com/models/id9DYiz3Y/';

async function main() {
    // カメラからの映像取得
    const stream = await navigator.mediaDevices.getUserMedia({
        audio: false,
        video: true,
    });
    // html内のidがvideoのdomを取得
    const video = document.getElementById('video');
    // videoにカメラ映像を適用
    video.srcObject = stream;

    // 自作モデルのロード
    // [FIX] classifier の変数宣言が無いので const 追加
    const classifier = ml5.imageClassifier(
        imageModelURL + 'model.json',
        video,
        modelLoaded
    );

    // モデルのロード完了時に実行される
    function modelLoaded() {
        console.log('Model Loaded!');
    }

    // 繰り返し検出処理
    classifier.classify(onDetect);
    function onDetect(err, results) {
        console.log(results);
        if (results[0]) {
            console.log(results[0].label);

            // [FIX] 音声再生判定の位置がおかしいので
            //       正しい位置(onDetect 内)に

            //手を挙げてないときに音を出す
            if (results[0].label === 'none') {
                // [FIX] sound 関数実行
                sound();
            }
        }

        classifier.classify(onDetect);
    }


    function sound() {
        // 初回以外は音声ファイルを巻き戻す(再生位置[秒]を0に設定する)
        if (typeof (document.getElementById('sound-file').currentTime) != 'undefined') {
            document.getElementById('sound-file').currentTime = 0;
        }
        //音声ファイルを再生する
        document.getElementById('sound-file').play();
    }
}
main();

適当な音声ファイル用意すれば、
こちらではこれで実行できています(判定の頻度や精度はさておき)。

1Like

Comments

  1. @twtjudy1128

    Questioner

    ありがとうございます、無事動きました><
    エラーも出ていましたね、失礼いたしました…。

    関数がまだきちんと理解できていなかったので、教えていただいたコードを再度見直して理解に努めようと思います。

    本当にありがとうございました!

Your answer might help someone💌