質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.74%

  • JavaScript

    15234questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • HTML

    8282questions

    HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

formから取得してきた文字列を利用して複数のmp3を連続して再生したい

受付中

回答 0

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 132

imohori708

score 2

ボタンを押すことで音楽を再生できるホームページを作成しています。
以下のプログラムを使って、音声ファイル1.mp3,音声ファイル2.mp3,音声ファイル3.mp3を再生する仕組みです。

<button type="button" class="sounds" data-file="./sound/音声ファイル1">音声ファイル1</button>
// グローバル変数
var syncerSounds = {
    flag: {} ,
    currentTime: null ,
} ;
// 即時関数
(function()
{
    // 設定
    var setClass = 'sounds' ;        // ボタン要素のクラス名
    var setDir = './' ;            // 音声ファイルがあるフォルダ(最後は[/])
    var setStopButtonId = 'stop-button' ;    // 停止ボタンに付けるID

    // クラス名が付いた要素を取得する
    var sounds = document.getElementsByClassName( setClass ) ;

    // 全ての要素にクリックイベントを設定する
    for( var i=0,l=sounds.length ; l>i ; i++ )
    {
        // クリックイベントの設定
        sounds[i].onclick = function()
        {
            // ファイル名の取得(getAttributeはtype,value,maxlengthの値を取得)
            var file = this.getAttribute( 'data-file' ) ;

            // 一度生成したエレメントは生成しない
            if( typeof( syncerSounds.flag[ file ] )=="undefined" || syncerSounds.flag[ file ] != 1 )
            {
                // 生成するエレメントの調整
                var audio = document.createElement( 'audio' ) ;

                // エレメントのIDを指定
                audio.id = file ;
                audio.src = setDir + file + '.mp3' ;

                // [audio]を生成する
                document.body.appendChild( audio ) ;
            }

            // 初回再生以外だったら音声ファイルを巻き戻す
            stopCurrentSound() ;
            // 音声ファイルを再生[play()]する
            document.getElementById( file ).play() ;
            // 最近再生した音声としてセット
            syncerSounds.currentTime = file ;
            // 初回再生が終わった判定用に[syncerSounds.flag]の値を0から1に変更する
            // エレメントを何度も生成しないようにするため
            syncerSounds.flag[ file ] = 1 ;
            // 終了
            return false ;
        }
    }
    // 前回の音声を停止する関数
    function stopCurrentSound()
    {
        var currentSound = document.getElementById( syncerSounds.currentTime ) ;
        if( currentSound != null )
        {
            currentSound.pause() ;
            currentSound.currentTime = 0 ;
        }
    }
    // 停止ボタンをクリックした時のイベント
    document.getElementById( setStopButtonId ).onclick = function()
    {
        stopCurrentSound() ;
        return false ;
    }
})() ;


上記のコードを改造し、
①formへ文字列を入力
②文字列をリストに分割
③リストの第一要素から順に再生クラスへ再生したいmp3名を受け渡す
④再生が最後まで終わるのを待って、第二要素、第三要素…とリストの最後の要素まで順に渡し、mp3を順番に再生する
といった処理を作りたいのですが、2曲目まで上手く動くにも関わらず、三曲以上連続で再生しようとすると、下記エラーが出て1曲目と最後の曲だけ再生されてしまいます。
Uncaught (in promise) DOMException: The play() request was interrupted by a call to pause()

こちら(https://foolean.net/p/679)のHPを参考に、再生が終了していることを判断してループを回すような処理を組みましたが、同様の結果でした。

//フォームへの文字列入力コード
<form name="voiceForm" id="id_voiceform" value="">
<input type="text" id="id_textBox1" name="voiceText" value=""><br>
<button type="button" onClick="getStr()">連続再生</button>
<input type="button"  name="addButton" src="add.jpg" value="&quot;音声ファイル1&quot;" class="btn" onClick="addStr(this.value)" ></button>
<input type="button"  name="addButton" src="add.jpg" value="&quot;音声ファイル2&quot;" class="btn" onClick="addStr(this.value)" ></button>
<input type="button"  name="addButton" src="add.jpg" value="&quot;音声ファイル3&quot;" class="btn" onClick="addStr(this.value)" ></button>
var voice;
var playingVoice;
//フォームへ文字を入力するクラス
function addStr(str)
{
    document.voiceForm.voiceText.value += str;
}
//取得した文字列を整形し、mp3を再生するクラス
function getStr(){
    var voiceListString = document.forms.id_voiceform.id_textBox1.value;
    var voiceList = [];            //ボイスを連続再生する際に使うリストの初期化

    voiceList = voiceListString.split('""');

    var listLength = voiceList.length;

    // 先頭から1文字を削除
    voiceList[0]= voiceList[0].slice(1);
    // 末尾から1文字を削除
    voiceList[listLength-1]= voiceList[listLength-1].slice( 0, -1 );

    for(var i = 0; i < listLength; i++){
    playingVoice=voiceList[i];
        if(i>0){
        voice.addEventListener("ended",function(e){
        ContinuityVoice();
        });
        }else{
        ContinuityVoice();
        }
        //voiceList[i].addEventListener("ended", function(e))
    }
}
//複数のmp3を連続で再生するクラス
function ContinuityVoice(){
    // 設定
    var setClass = 'sounds' ;        // ボタン要素のクラス名
    var setDir = './' ;            // 音声ファイルがあるフォルダ(最後は[/])
    var setStopButtonId = 'stop-button' ;    // 停止ボタンに付けるID
    var soundFile = "./sound/"+playingVoice;

    // ファイル名の取得(getAttributeはtype,value,maxlengthの値を取得)
    var file = soundFile;

    // 一度生成したエレメントは生成しない
    if( typeof( syncerSounds.flag[ file ] )=="undefined" || syncerSounds.flag[ file ] != 1 ){
        // 生成するエレメントの調整
        var audio = document.createElement( 'audio' ) ;

        // エレメントのIDを指定
        audio.id = file ;
        audio.src = setDir + file + '.mp3' ;

        // [audio]を生成する
        document.body.appendChild( audio ) ;
    }

    // 初回再生以外だったら音声ファイルを巻き戻す
    stopCurrentSound();

    voice = document.getElementById( file );

    // 音声ファイルを再生[play()]する
    voice.play() ;
    // 最近再生した音声としてセット
    syncerSounds.currentTime = file ;
    // 初回再生が終わった判定用に[syncerSounds.flag]の値を0から1に変更する
    // エレメントを何度も生成しないようにするため
    syncerSounds.flag[ file ] = 1 ;

    // 終了
    return false ;
}
// 前回の音声を停止する関数
function stopCurrentSound(){
    var currentSound = document.getElementById( syncerSounds.currentTime ) ;

    if( currentSound != null )
    {
        currentSound.pause() ;
        currentSound.currentTime = 0 ;
    }
    // 停止ボタンをクリックした時のイベント
    document.getElementById( setStopButtonId ).onclick = function()
    {
        stopCurrentSound() ;
        return false ;
    }
}


現在発生しているエラーを取り除き、正しく複数のmp3を連続して再生するにはどのような修正をすればよろしいでしょうか。
よろしくお願いします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

まだ回答がついていません

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.74%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • JavaScript

    15234questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • HTML

    8282questions

    HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。