MENU

    HTTPステータスコード百人一首の読み上げスクリプト

    HTTPステータスコード百人一首の自動音声読み上げスクリプトを作る

    当サイトでは実際に購入した商品のみをレビューし、アフェリエイトリンク付きでご紹介しています

     

    2人でも、HTTPステータスコード百人一首で遊びたい!

     「HTTPステータスコード百人一首」は、HTTPのステータスの説明文を読み上げて、取り札をとる素敵なカードゲームです。2名以下でも遊べるように、読み上げツールを自作します。

    この記事でわかること
    • HTTPステータスコード百人一首の遊び方
    • 音声合成(読み上げ)の実現方法
    • 実装時に困ったことと、回避方法
    目次

    HTTPステータスコード百人一首とは?

    取り札と読み札

     揚げピーナッツさんが作成した新しいカードゲームです。

     お馴染みの HTTPステータスコードで、百人一首ができるというオシャレな作品です。

     本来の推奨人数は「札の読み手:1名、札の取り手:2〜4名」ですが、「札の読み手:0名」で遊べるように読み上げツールを作りました。

    音声読み上げツール【完成品】

     

    できました!

    HTTPステータスコードの読み上げ



    速度:
    遊び方
    1. 取り札を表向きに並べます。
    2. お好みの設定を選んで、「読み上げ」ボタンをクリック!
    3. 読み上げられた札を、探して取ります。
    4. 表示されているダイアログの「OK」ボタンをクリックすると、読み上げた札の正答が表示されます。
    5. もう一度、「OK」ボタンを押すと、次の札を読み上げます。
    6. 3〜5の手順を、最後の札まで繰り返します。

    ※ キャンセルを押した場合、途中から再開はできません。お気をつけください。
    ※ ChromeまたはSafariでお使いください。

     

    自主トレにもお使いください。

    スクリプトの作成ついて

    ソースコード

    <div id="message">
      <p id="tool-title">HTTPステータスコードの読み上げ</p>
      <input type="checkbox" id="status-select" name="status-select" checked="checked">
      <label for="status-select">ステータスを読み上げる</label><br>
      <input type="checkbox" id="code-select" name="code-select" checked="checked">
      <label for="code-select">コードを読み上げる</label><br>
      速度:
      <select id="speed-select">
        <option value="0.5">ゆっくり</option>
        <option value="0.8" selected="selected">ふつう</option>
        <option value="1.2">はやい</option>
      </select><br>
      <button id="speak-btn">読み上げ</button>
    </div>
    <script>
      const speedSelect = document.querySelector('#speed-select')
      const statusSelect = document.querySelector('#status-select')
      const codeSelect = document.querySelector('#code-select')
      const speakBtn    = document.querySelector('#speak-btn')
      
      speakBtn.addEventListener('click', function() {
      
    	let card = [{"code":"504","status":"Gateway Time out","reading":"ゲイトウェイ タイム アウト ","description":"ゲートウェイが時間内にレスポンスを返す事ができませんでした。"},{"code":"503","status":"Service Unavailable","reading":"サービス アナヴェイラブル ","description":"リクエストを受け付ける準備ができていません。"},{"code":"502","status":"Bad Gateway","reading":"バッド ゲイトウェイ ","description":"リクエストの処理に必要なレスポンスを受け取るゲートウェイが、無効なレスポンスを受け取りました。"},{"code":"501","status":"Not Implemented","reading":"ノット イムプリメンティド ","description":"サーバーが対応していないメソッドをリクエストしました。"},{"code":"500","status":"Internal Server Error","reading":"インターナル サーバー エラー","description":"サーバーで異常が発生して正しく返答できませんでした。"},{"code":"451","status":"Unavailable For Legal Reasons","reading":"アナヴェイラブル フォー リーガル リーズンズ ","description":"リクエストされたリソースは、政府の検閲によってレスポンスを拒否しました。"},{"code":"429","status":"Too Many Requests","reading":"トゥー メニー リクエスツ","description":"一定の時間内に大量のリクエストを行ったため、サーバーが受付を拒否しました。"},{"code":"425","status":"Too Early","reading":"トゥー アーリー","description":"リプレイ攻撃される可能性があるため、リクエストを受け付けませんでした。"},{"code":"418","status":"I'm a teapot","reading":"アイム ア ティーポット ","description":"ティーポットにコーヒーをいれさせようとして、拒否された場合に返します。これはジョークのコードです。"},{"code":"416","status":"Range Not Satisfiable","reading":"レンジ ノット サティスフィアブル ","description":"実際のリソースサイズと異なるサイズのリクエストをしました。"},{"code":"414","status":"URI Too Long","reading":"ユー-アール-アイ トゥー ロング ","description":"リクエストしたURLが長過ぎて、サーバーは受け付ける事ができませんでした。"},{"code":"413","status":"Payload Too Large","reading":"ペイロード トゥー ラージ ","description":"リクエストの内容が大きく、サーバーで定めている上限を超えました。"},{"code":"412","status":"Precondition Failed","reading":"プリコンディション フェイルド ","description":"リクエストヘッダーに指定された前提条件が適合しませんでした。"},{"code":"411","status":"Length Required","reading":"レングス リクヮイアード ","description":"リクエストにContent-Lengthヘッダーがありません。"},{"code":"410","status":"Gone","reading":"ゴーン ","description":"リクエストされたリソースは永久に消滅しました。"},{"code":"409","status":"Conflict","reading":"コンフリクト ","description":"リクエストが現在のリソースと競合しているため処理が完了できません。"},{"code":"408","status":"Request Time out","reading":"リクエスト タイム アウト","description":"リクエストが時間内に完了しませんでした。"},{"code":"407","status":"Proxy Authentication Required","reading":"プロキシ オーセンティケイション リクヮイアード ","description":"プロキシの認証が必要です。"},{"code":"406","status":"Not Acceptable","reading":"ノット アクセプタブル ","description":"クライアントが受理できないデータがレスポンスに含まれています。"},{"code":"405","status":"Method Not Allowed","reading":"メソッド ノット アロウド","description":"リクエストされたメソッドは許可されていません。"},{"code":"404","status":"Not Found","reading":"ノット ファウンド ","description":"リクエストされたリソースが見つかりませんでした。存在しないページを表示しようとした時などに返されます。"},{"code":"403","status":"Forbidden","reading":"フォービドゥン","description":"リクエストされたリソースへのアクセスが禁止されています。アクセス権がないページを表示しようとした時などに返されます。"},{"code":"401","status":"Unauthorized","reading":"アンオーサライズド ","description":"クライアントに有効な認証資格がありません。"},{"code":"400","status":"Bad Request","reading":"バッド リクエスト","description":"クライアントのエラーによりリクエストが処理できません。リクエストの構文が正しくない場合などに返されます。"},{"code":"308","status":"Permanent Redirect","reading":"パーマネント リダイレクト","description":"リクエストされたURLが変更されています。新しいURLを返します。これは301と同じ意味を持ちますが、HTTPメソッドを変更してはいけない点が異なります。"},{"code":"307","status":"Temporary Redirect","reading":"テンポラリ リダイレクト","description":"リクエストされたURLが一時的に存在しないため、別のURLに転送します。これは302と同じ意味を持ちますが、HTTPメソッドを変更してはいけない点が異なります。"},{"code":"304","status":"Not Modified","reading":"ノット モディファイド ","description":"リクエストされたリソースは更新されていません。"},{"code":"303","status":"See Other","reading":"シー アザー","description":"リクエストに対するレスポンスが他のURLに存在します。"},{"code":"302","status":"Found","reading":"ファウンド ","description":"リクエストされたURLが一時的に存在しないため、別のURLに転送します。"},{"code":"301","status":"Moved Permanently","reading":"ムーヴド パーマネントリー","description":"リクエストされたURLが変更されています。新しいURLを返します。"},{"code":"300","status":"Multiple Choice","reading":"マルチプル チョイス","description":"リクエストに対して複数のレスポンスがあります。"},{"code":"206","status":"Partial Content","reading":"パーシャル コンテント ","description":"リクエストは成功し、リクエストのRangeヘッダーで要求された範囲のコンテンツを返しました。"},{"code":"205","status":"Reset Content","reading":"リセット コンテント","description":"リクエストは成功しましたが、クライアントにコンテンツをリセットするように要求しています。フォームの送信後に画面をリセットする場合などに返されます。"},{"code":"204","status":"No Content","reading":"ノー コンテント ","description":"リクエストは成功しましたが、返すコンテンツがありません。"},{"code":"203","status":"Non-Authoritative Information","reading":"ノン オーソリテイティブ  インフォメーション","description":"リクエストの内容がオリジナルと異なり、ローカルやプロキシ等の情報なので信頼できません。"},{"code":"202","status":"Accepted","reading":"アクセプティッド","description":"リクエストは受理されましたが、まだ実行されていません。"},{"code":"201","status":"Created","reading":"クリエイテッド","description":"リクエストは成功し、新たなリソースのURLが作成されました。"},{"code":"200","status":"OK","reading":"オーケイ ","description":"リクエストは成功しました。"},{"code":"101","status":"Switching Protocol","reading":"スイッチング プロトコル","description":"リクエストを理解できているが、正しい処理を行うため、プロトコルの切り替えを要求しています。"},{"code":"100","status":"Continue","reading":"コンティニュー","description":"リクエストの最初の部分を受け取り、まだ拒否されていません。継続してリクエストすることが可能です。"}]
      
      card = shuffle(card)
     
      let talk = new SpeechSynthesisUtterance()
      talk.rate = speedSelect.value
      talk.lang = "ja-JP"
      talk.pitch = 0.8;
      let msg = "OKを押すと、次の札を読み上げます"
    
      for(let i in card) {
        talk.text = card[i].description
        if( statusSelect.checked )
          talk.text += card[i].reading
        if( codeSelect.checked )
          talk.text += "。" + card[i].code
          
        speechSynthesis.speak(talk)
    
        if(! confirm( "OKを押すと、この札の情報を表示します" ) )
        	break
         
        speechSynthesis.cancel()
    
        if( i == card.length -1 ) 
          msg = "お疲れ様でした!"
        if( ! confirm(card[i].code + ":" + card[i].status + "\n\n" + msg) )
        	break
      }
      speechSynthesis.cancel()
    })
    const shuffle = (array) => {
      for(i = array.length - 1; i > 0; i--) {
          const j = Math.floor(Math.random() * (i + 1))
          const tmp = array[i]
          array[i] = array[j]
          array[j] = tmp
      }
      return array
    }
    </script>
     

    中身はとてもシンプルなJavaScriptです。

    Web Speech API

     今回は、Web Speech API をJavaScriptから実行し、読み上げを実現しました。

     Web Speech APIを選んだ理由は以下の通りです。

    1. シンプル
    2. ブラウザだけで動き、動作環境が多い
    3. 無償で実現できる
    4. 追加ライブラリすら要らない
     

    高品質な読み上げとは、言えないかもしれません。
    しかし、ブラウザだけで動く手軽さは魅力です。

    コーディング中に困ったこと

     コーディング中に困ったこと・回避方法を、メモとして書き残しておきます。

    1. ループ2周目から、読み上げられなかった。
      →ループの中で、speechSynthesis.cancel()を呼んだらうまくいった。
    2. 札の読み上げ前に効果音を入れたかった。しかし、読み上げとタイミングが合わない。
      →これは諦めた。
    3. 日本語APIは、英単語の読み上げが不自然だった。URIをユリと読んでしまう。
      →カタカナ英語のデータを作り、これを読み上げることにした。

    参考サイト

     コーディングの際に、参考にさせていただいたサイトは以下の通りです。

    まとめ

     HTTPステータスコード百人一首は、揚げピーナッツさんのサイトに各種ストアへのリンクがあります。素敵なゲームですので、是非お買い求めください。

     またツールおよびコードの公開について、揚げピーナッツさんにご快諾いただきました。
     誠にありがとうございます。

     最後まで読んでいただき、ありがとうございました。
     みなさまの暮らしがより良くなりますように。

    お役に立てたら幸いです
    • URLをコピーしました!
    • URLをコピーしました!
    目次