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

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

新規登録して質問してみよう
ただいま回答率
85.50%
HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

JavaScript

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

Q&A

解決済

4回答

15536閲覧

JavaScript/HTML5での音のループ再生の遅延

wakka0014

総合スコア15

HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

JavaScript

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

1グッド

3クリップ

投稿2018/01/12 01:45

編集2018/01/12 01:46

HTML5/JSを用いてMP3ファイルをループして再生しようとしています。
ループ再生はできるのですが、音が円滑にループ再生できません。

意図としては、曲の最初と最後が合うようになっている無限再生用のBGMをループ再生したいです。
実装したものは最後まで曲が再生されると0.5秒ほど空いてから再生されます。

HTMLの仕様上、仕方ないのでしょうか。
円滑にループ再生する方法をご教授願います。

以下JavaScripのソースコードになります。

//audioを作成 var audio = new Audio(); //【関数】HTML起動時に事前に呼ばれる function loadAudio() { //プリロード audio.preload = "auto"; //音のバスを指定 audio.src = "/audio/audio.mp3"; //読み込む audio.load(); } //【関数】音をループ再生 function playAudioLoop() { //ループ再生ON audio.loop = true; //再生 audio.play(); }
defghi1977👍を押しています

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

ベストアンサー

私も質問文と似たことを感じてBGMのループに関して研究してました。
BGMをループ再生させるWebアプリ

私のブログが役立てるかと思ったら、
全くそうでもない単なるチラ裏程度のものしか残ってませんでした。。。


Web Sounder
HTML5の音楽系の仕様はこのサイトが一番詳細です。

ざっくり説明しますと、
HTML5が用意している音楽系APIは2パターン存在し、互換性はほぼありません。
つまり自由に行き来することが出来ません。

HTMLMediaElementWeb Audio APIの2系統があり、
質問文はauduoタグなので前者であり、後者のAPIの恩恵はほぼ受けることが出来ません。

HTMLMediaElement
これがaudioタグでJavaScript側から出来ることの全てです。
翻訳があまり進んでなくて読みづらいですが、これに目を通さないと話にならないので是非。

★video要素、audio要素をJavaScriptから操作する
こちらの方が読みやすいので、先にこっちに目を通しても良いかもしれません。


今回の要件ですとループに必要なのは、audio.loop = trueではなく、
曲が終わる直前の時刻になったらaudio.currentTime = 0と代入してあげることです。

どうやって曲の終了を見分けましょうか?
audioにはtimeupdateというイベントが設定されており、曲の再生中時刻が上書きされるのでポンポンtimeupdateが呼ばれますが、1秒に一桁回数程度の頻度でしか呼ばれません。

私はLoopBGMというサイトの制作を通じて何度も曲のつながりを確認しましたが、
10ms以上ずれるとほぼ確実に耳に違和感が残ります。
最低でも1秒間に60回程度の頻度で確認する必要があり、曲の部分ループの実装に苦労しました。
まぁ、最終的にはaudioタグはすっぱり諦めてWeb Audio APIの仕様にガッツリ寄せて頑張りました。

今回は音楽ファイルの最初と最後ということなので、audio.loopを切りましょう
そうすればaudioのendedイベントで曲の終了を確認することが可能となります。
こんな感じでどうでしょう?確認してみてください。

JavaScript

1audio.addEventListener("ended", function() { 2 audio.currentTime = 0; 3 audio.play(); 4}, false);

投稿2018/01/12 02:48

miyabi-sun

総合スコア21158

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

miyabi-sun

2018/01/12 03:36

単なる補足なのでこのコメントにぶら下げます。 Web Audio APIには音楽ソースの部分ループを宣言的(132.16秒目になったら11.35秒目に戻す)に書けるので、確実で綺麗な部分ループを表現することが可能です。 しかし、Web Audio APIを利用すると音楽ファイルが単なる楽譜の一つの音符記号的な扱いをされるので、再生時刻との整合性が取れなくなります。 要するにWeb Audio APIの世界で1000秒経過したのだから、音楽ファイル(120秒)は9回目の40秒経過後に違いないという決め打ちになります。 音楽ファイルが0秒で切れるというのはまずなく、小数点以下の誤差があるので…100回ほどループすれば数秒は平気でずれるでしょう。 こんな感じでループ音楽をWeb Audio APIで表現した後に、audioタグ的なUIを表現することは死ぬほど大変です。 ちなみに私は諦めてaudioタグとWeb Audio APIの長所を別々に利用する作りにしました。
guest

0

試せる環境にないのですが、同様の質問がありました。Web Audio APIを使うといいようです。
https://stackoverflow.com/questions/46926033/create-seamless-loop-of-audio-web

Web Audio API
https://developer.mozilla.org/ja/docs/Web/API/Web_Audio_API

IE不可
https://caniuse.com/#feat=audio-api

なお、ogg形式にすると改善するという情報もあります。
http://www.kevssite.com/seamless-audio-looping/

投稿2018/01/12 02:43

x_x

総合スコア13749

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

Audio要素を二つ用意して、交互に再生してみるとどうでしょうか?

以下全くテストしていないコードですが、こんなイメージという意味で載せます。

javascript

1//audioを作成 2var audios = [new Audio(),new Audio()]; 3 4//【関数】HTML起動時に事前に呼ばれる スマホ等ではloadやplayにはタッチイベントやクリックイベントが必要らしいです。 5 6function loadAudio() { 7 audios.forEach((a) => { 8 9 //プリロード loadするならいらないのでは…?一応残しときます。 10 a.preload = "auto"; 11 12 //音のパスを指定 これもnew Audio();の引数に渡すだけでいいはず 13 a.src = "/audio/audio.mp3"; 14 15 //読み込む 16 a.load(); 17 18 }); 19} 20 21var timer_id; 22 23//【関数】音をループ再生 スマホ等ではloadやplayにはタッチイベントやクリックイベントが必要らしいです。 24 25function playAudioLoop() { 26 //再生 27 audios[0].play(); 28 var i = 1; 29 timer_id = setInterval(function(){ 30 audios[i].play(); 31 i = i==0 ? 1 : 0; 32 },/* 曲の終了時間(ミリ秒)*/); 33}

質問解決後にすみません…凡ミスがありましたので修正しました。

setTimeout -> setInterval

ついでに止める用にtimer_idに代入した形にしておきました。

やっぱりデバッグなしって危ないですね…以後気をつけようと思います。m(_ _)m

投稿2018/01/12 02:35

編集2018/01/13 15:22
namnium1125

総合スコア2043

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

皆様、ご回答ありがとうございました。
情報共有のため、私の試した方法を記入します。

・ogg形式に変換してloopさせる
⇒ラグが変わらず発生

・endedで曲の再生完了を検知して再生させる
⇒ラグが変わらず発生

・setTimeoutで指定秒数ごとに曲を再生
⇒ラグがなくループさせることができた

結果としてX秒ごとに曲の再生を回す方式でできました。
プログラム的に指定秒数ごとにやるのもしこりが残りますが。。

コードは以下になります。

//audioを作成
var audio = new Audio();

//【関数】HTML起動時に事前に呼ばれる
function loadAudio() {
audio.forEach((a) => {

//音のパスを指定 audio.src = "/audio/audio.mp3"; //読み込む audio.load(); });

}

//【関数】音をループ再生

function playAudioLoop() {
//ループさせる
var loopPlay = function(){
audio.play();
audio.currentTime = 0;
setTimeout(loopPlay, 10000/* 10秒 */);
};
loopPlay();
}

投稿2018/01/13 14:17

編集2018/01/15 04:10
wakka0014

総合スコア15

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

namnium1125

2018/01/13 15:25

なるほど、複数の回答を組み合わせたのですね! ただこの方法の場合おそらく配列は意味を成していないかと思います。
wakka0014

2018/01/15 04:10

リプライありがとうございます。 配列を使わない方法に修正しました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問