rempei
@rempei

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

音声データが上手く渡せない

解決したいこと

デフォルトではゴーリキーの鳴き声が鳴るようにしています。
ボタンを押すとライチュウの鳴き声が鳴るようにしたはずなのですが何回押してもゴーリキーしか鳴きません。

console.log(data.cryURL)
をしてみるとしっかりとライチュウの方が取得できているのですが
鳴き声はゴーリキーです。

どなたかライチュウにして下さい。

data.yml
Pokemon():
    name:                   ライチュウ
    level:                  15
    partner:                サトシ
    cryURL:                 http://games255.512.jp/pokewav/026.wav

fetch(url)
.then((res) => res.json())
.then((data) => {
    const cry = document.querySelector(".nakigoe")
    cry.src = data.cryURL
}
<button class="cry-btn" >鳴き声</button>
        <audio class="poke-cry">
          <source class="nakigoe" src="http://games255.512.jp/pokewav/067.wav">
        </audio>
        <script>
          const inputElement = document.querySelector(".cry-btn");
          const audioElement = document.querySelector(".poke-cry");
          inputElement.addEventListener("click", () => {
            audioElement.play();
          });
        </script>
0

3Answer

ファイルに書かれたライチュウのcryURLはhttp://games255.512.jp/pokewav/026.wavですが、オーディオタグのsrc属性の値はhttp://games255.512.jp/pokewav/067.wavです。

const button = document.querySelector(".cry-btn");
const audioElement = document.querySelector(".poke-cry");

button.addEventListener("click", () => {
  // source要素のsrc属性を変更する
  audioElement.querySelector(".nakigoe").src = "http://games255.512.jp/pokewav/026.wav";

  // オーディオファイルを再生する
  audioElement.play();
});
1Like

Comments

  1. @rempei

    Questioner

    ご回答ありがとうございます。
    オーディオタグのsrcはちゃんとデータを取得、代入できているかを確かめるためにデフォルトをゴーリキーにしています。
    直接urlを代入するのではなくdata.ymlからとってきたデータを代入したいです。(→よってsrcの変更はthen()の中で)
    というかしているしデータもちゃんと取得できているのに、代入が上手くできていないようなんです。
    この現象の原因に心当たりはありますでしょうか?

  2. 以下のように、dataを別の変数名に格納してからcry.srcに代入することで、正しい鳴き声が再生されるはずです:

    fetch(url)
    .then((res) => res.json())
    .then((data) => {
        const cry = document.querySelector(".nakigoe");
        const cryURL = data.cryURL; // データを別の変数に格納
        cry.src = cryURL; // 正しい鳴き声のURLを設定
    });
    

    ボタンを押すとライチュウの鳴き声が鳴るようにした.このボタンはオーディオ再生のリスナーを登録するだけだと思っていたので、デフォルトの src が再生されることになります。ボタンをクリックしたときに audio タグの src 属性のログを追加してください。

  3. @rempei

    Questioner

    残念ながらまだゴーリキーでした。

  4. 「audioElement」を取得するタイミングを変更すれば機能するはずです。 audioElement クエリをイベント リスナー内に移動することで、ボタンがクリックされるたびに audioElement が確実に再取得されるようになります。こうすることで、audioElement にはフェッチされたデータに基づいた正しい src 属性が設定され、ボタンがクリックされたときに正しいサウンドが再生されます。

    更新されたコードは次のとおりです。

    <button class="cry-btn">鳴き声</button>
    <audio class="ポケクライ">
      <source class="泣き声" src="http://games255.512.jp/pokewav/067.wav">
    </オーディオ>
    <スクリプト>
      const inputElement = document.querySelector(".cry-btn");
      inputElement.addEventListener("クリック", () => {
        const audioElement = document.querySelector(".poke-cry");
        audioElement.play();
      });
    </script>
    「」
    
    この変更により、`cry-btn`クラスのボタンをクリックすると、再度`audioElement`が取得され、音声が再生されるようになります。正しいサウンドは、audio 要素の `src` 属性を設定する `fetch` 呼び出しでフェッチされたデータに基づいて再生される必要があります。
    
  5. @rempei

    Questioner

    これは試しましたがなおりませんでした。

<audio><source></audio>のネストを止めるとちゃんと鳴くことが確認できました。
具体的には、以下のとおりです。

fetch(url)
.then((res) => res.json())
.then((data) => {
    const cry = document.querySelector(".poke-cry")
    cry.src = data.cryURL
}
<button class="cry-btn" >鳴き声</button>
        <audio class="poke-cry" src="http://games255.512.jp/pokewav/067.wav">
        </audio>
        <script>
          const inputElement = document.querySelector(".cry-btn");
          inputElement.addEventListener("click", () => {
            const audioElement = document.querySelector(".poke-cry");
            audioElement.play();
          });
        </script>
1Like

Comments

  1. @rempei

    Questioner

    ついにライチュウの声を聴くことが出来ました!
    ありがとうございました!

ライチュウの方が取得できているのですが
鳴き声はゴーリキーです。

cry.src = data.cryURLよりaudioElement.play()が先に実行されているのでは?

0Like

Comments

  1. @rempei

    Questioner

    ご回答ありがとうございます。
    説明を端折っているのですが、画面の構成として左側にゴーリキー、ライチュウなどのポケモンのリスト
    右側に鳴き声ボタンがあり、ポケモンのリストのどれかを押すとfetch()でdataを取得し、
    同時にthen(data)の中でcry.src = data.cryURLを実行しています。
    その後、鳴き声ボタンを押しているのでcry.src = data.cryURLが先だとは思うのですが違うのでしょうか?

  2. リスナー登録時の情報で固定されているのだとしたら、
    audioElementの取得タイミングを変えると、どうでしょうか?

    <button class="cry-btn" >鳴き声</button>
            <audio class="poke-cry">
              <source class="nakigoe" src="http://games255.512.jp/pokewav/067.wav">
            </audio>
            <script>
              const inputElement = document.querySelector(".cry-btn");
    -         const audioElement = document.querySelector(".poke-cry");
              inputElement.addEventListener("click", () => {
    +         const audioElement = document.querySelector(".poke-cry");
                audioElement.play();
              });
            </script>
    
  3. @rempei

    Questioner

    試してみましたが変化はありませんでした。
    ちなみに画像で同じようにデフォルトはゴーリキーの画像、取得した画像データを
    const pokoImage = document.querySelector(".poko-image");
    pokoImage.src = data.image;
    のようにしてみましたがこちらは画像がちゃんと挿し変わりました。

  4. なんか変ですね。下記のようにplay直前のsrc(URL)を見てもらえませんか?

    <button class="cry-btn" >鳴き声</button>
            <audio class="poke-cry">
              <source class="nakigoe" src="http://games255.512.jp/pokewav/067.wav">
            </audio>
            <script>
              const inputElement = document.querySelector(".cry-btn");
              inputElement.addEventListener("click", () => {
                const audioElement = document.querySelector(".poke-cry");
    +           console.log(document.querySelector(".nakigoe").src)
                audioElement.play();
              });
            </script>
    
  5. @rempei

    Questioner

    inputElement.addEventListener("click", () => {
      const audioElement = document.querySelector(".poko-cry");
      console.log("今のsrcは" + audioElement.querySelector(".nakigoe").src);
      audioElement.play();
    });
    

    結果は
    今のsrcはhttp://games255.512.jp/pokewav/026.wav
    でちゃんと026に変わっていますね

  6. 下の回答を参照ください。

Your answer might help someone💌