HTML5オーディオ停止機能


147

ナビゲーションの各リンクをクリックして小さなオーディオクリップを再生しています

HTMLコード:

<audio tabindex="0" id="beep-one" controls preload="auto" >
    <source src="audio/Output 1-2.mp3">
    <source src="audio/Output 1-2.ogg">
</audio>

JSコード:

$('#links a').click(function(e) {
    e.preventDefault();
    var beepOne = $("#beep-one")[0];
    beepOne.play();
});

これまでのところ問題なく動作しています。

問題は、サウンドクリップが既に実行されていて、リンクをクリックしても何も起こらない場合です。

リンクをクリックしたときに既に再生されているサウンドを停止しようとしましたが、HTML5のオーディオAPIにはその直接のイベントはありません

次のコードを試してみましたが、機能しません

$.each($('audio'), function () {
    $(this).stop();
});

何か提案がありますか?

回答:


350

stop()あなたの代わりに:

sound.pause();
sound.currentTime = 0;

これは望ましい効果をもたらすはずです。


6
これはChromeでは機能しません。オーディオ要素はオーディオをロードし続けますが、これは本来起こるべきことではありません。
Pieter 2014年

3
Chromeでは、属性<audio>preload強制的に読み込まれnone<source>srcが取り除かれます。
Pioneer Skies

6
これでうまくいきます。余談ですが、なぜw3cが仕様にstopメソッドを含めないことにしたのか知りたいです。
Reahreic

25

まず、オーディオ要素のIDを設定する必要があります

あなたのjsで:

var ply = document.getElementById('player');

var oldSrc = ply.src;//古いソースを覚えておくだけ

ply.src = "";//プレーヤーを停止するには、ソースを何も置き換えないでください


4
オーディオストリーミングに最適なソリューション
Hossein

1
それは、オーディオソースファイルに対して別のネットワークリクエストを作成することになります
Al Mahmud

オーディオはロードされるまで再生されないため、オーディオの再生に不要な遅延が発生します。
Abhi、2015年

インターネットラジオやFirefoxなどのストリームを再生するときの問題の良い解決策は、一時停止/再生が切り替えられたときに最後のチャンクを繰り返すことです。本当にありがとうございました。
namikiri 2017

14

これが私のstop()メソッドの実行方法です。

コードのどこかに:

audioCh1: document.createElement("audio");

そしてstop()で:

this.audioCh1.pause()
this.audioCh1.src = 'data:audio/wav;base64,UklGRiQAAABXQVZFZm10IBAAAAABAAEAVFYAAFRWAAABAAgAZGF0YQAAAAA=';

このようにして、追加のリクエストを生成せず、古いリクエストはキャンセルされ、オーディオ要素はクリーンな状態になります(ChromeおよびFFでテスト済み):>


9

私は同じ問題を抱えていました。ラジオの場合、停止するとストリームが停止し、オンプレイがライブになります。私が見たすべてのソリューションには欠点がありました

  • player.currentTime = 0 ストリームをダウンロードし続けます。
  • player.src = ''errorイベントを上げる

私の解決策:

var player = document.getElementById('radio');
player.pause();
player.src = player.src;

そして、HTML

<audio src="http://radio-stream" id="radio" class="hidden" preload="none"></audio>

これはChromeとFirefoxで動作します。ただし、Firefoxでは次のエラーが発生します(コンソール内)[ Security Error: Content at https://localhost/url.html may not load data from blob:https://localhost/cac32534-78b0-4a62-8355-cc8f1e708d64.](キャッチされない例外とは異なり)この後もコードが実行され続けるため、悪影響はないようです。
BReddy

6

この方法は機能します:

audio.pause();
audio.currentTime = 0;

しかし、オーディオを停止するたびにこの2行のコードを記述したくない場合は、次の2つのいずれかを実行できます。2つ目は、より適切な方法だと思います。「JavaScript標準の神々」がこの標準を作成しなかった理由がわかりません。

最初の方法:関数を作成してオーディオを渡す

function stopAudio(audio) {
    audio.pause();
    audio.currentTime = 0;
}

//then using it:
stopAudio(audio);

2番目の方法(推奨):Audioクラスを拡張します。

Audio.prototype.stop = function() {
    this.pause();
    this.currentTime = 0;
};

これは、「AudioPlus.js」と呼ばれるjavascriptファイルにあり、オーディオを処理するスクリプトの前にhtmlに含めます。

次に、オーディオオブジェクトの停止関数を呼び出すことができます。

audio.stop();

「canplaythrough」を使用した最後のChromeの問題:

これをすべてのブラウザでテストしたわけではありませんが、これはChromeで発生した問題です。「canplaythrough」イベントリスナーが接続されているオーディオにcurrentTimeを設定しようとすると、望ましくない結果につながる可能性があるそのイベントを再度トリガーします。

したがって、本当にトリガーされないようにするために本当にイベントリスナーをアタッチしたすべての場合と同様に、解決策は、最初の呼び出しの後にイベントリスナーを削除することです。このようなもの:

//note using jquery to attach the event. You can use plain javascript as well of course.
$(audio).on("canplaythrough", function() {
    $(this).off("canplaythrough");

    // rest of the code ...
});

ボーナス:

Audioクラス(さらに言えばネイティブJavaScriptクラス)にさらに多くのカスタムメソッドを追加できることに注意してください。

たとえば、オーディオを再開する「再開」メソッドが必要な場合は、次のようになります。

Audio.prototype.restart= function() {
    this.pause();
    this.currentTime = 0;
    this.play();
};

function stopAudio(audio) { audio.pause(); this.audioStream.src = ""; } これを行うと、私にとってはうまくいき、ページでオーディオが再生されているときに表示されるChromeブラウザのスピーカーアイコンが削除されました。Chromeバージョン59.0.3071.109でテスト
lasec0203

一般的に、このようなプロトタイプを拡張することはお勧めしません。オーディオ重いアプリケーションが異なるケースごとに異なるストップ機能を持っているとプロトタイプをいじりはおそらく長期的な私見のバグにつながることがあるかもしれ
milesaron

5

自分のJavaScript関数から再生/一時停止を切り替える-ラジオストリームを処理しているので、リスナーがラジオステーションと同期しなくなることのないように、バッファをクリアする必要がありました。

function playStream() {

        var player = document.getElementById('player');

        (player.paused == true) ? toggle(0) : toggle(1);

}

function toggle(state) {

        var player = document.getElementById('player');
        var link = document.getElementById('radio-link');
        var src = "http://192.81.248.91:8159/;";

        switch(state) {
                case 0:
                        player.src = src;
                        player.load();
                        player.play();
                        link.innerHTML = 'Pause';
                        player_state = 1;
                        break;
                case 1:
                        player.pause();
                        player.currentTime = 0;
                        player.src = '';
                        link.innerHTML = 'Play';
                        player_state = 0;
                        break;
        }
}

結局のところ、currentTimeをクリアするだけではChromeの下ではカットされず、ソースもクリアして再度読み込む必要がありました。これが役に立てば幸いです。


4

余談ですが、このリンクによると、私は最近、受け入れられた回答で提供されている停止方法を使用していたため、

https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Media_events

currentTimeを手動で設定すると、オーディオ要素で「canplaythrough」イベントを発生させることができます。リンクではFirefoxについて言及していますが、ChromeでcurrentTimeを手動で設定した後にこのイベントが発生しました。したがって、このイベントに動作が関連付けられている場合、オーディオループになる可能性があります。


3

それは時々クロムでは機能しません、

sound.pause();
sound.currentTime = 0;

ちょうどそのように変更し、

sound.currentTime = 0;
sound.pause();

2

shamangeorgeが書いた:

currentTimeを手動で設定すると、オーディオ要素で「canplaythrough」イベントを発生させることができます。

これは実際に何が起こるかであり、一時停止するとpauseイベントもトリガーされます。どちらの場合も、この手法は「停止」メソッドとしての使用には適していません。さらに、がsrc提案するようにをautoplay設定srcするnullと、有効になっている場合、プレーヤーは現在のページのURLをメディアファイルとしてロードしようとします(そして失敗します)-への設定は許可されません。常にURLとして扱われます。プレーヤーオブジェクトを破棄しないと、「停止」メソッドを提供する良い方法はないようです。そのため、専用の停止ボタンをドロップし、代わりに一時停止ボタンとスキップボタンを提供することをお勧めします。停止ボタンは実際には機能を追加しません。 。


1

このアプローチは「ブルートフォース」ですが、jQueryの使用が「許可」されていることを前提として機能します。「プレーヤー」<audio></audio>タグをdivで囲みます(ここでは「plHolder」のIDを使用)。

<div id="plHolder">
     <audio controls id="player">
     ...
     </audio>
<div>

次に、このJavaScriptが機能するはずです。

function stopAudio() {
    var savePlayer = $('#plHolder').html(); // Save player code
    $('#player').remove(); // Remove player from DOM
    $('#FlHolder').html(savePlayer); // Restore it
}

同じことは、jqueryを使用せずに上記の回答でzakiによって説明されています。
Alok Jain

実験はしませんでしたが、<source>タグが複数ある場合に彼のメソッドが機能するかどうかはわかりませんでした。
user3062615 2015年

#FlHolderタイプミスのようです#plHolder
Pioneer Skyes

1
@ alok-jainコメントへの返信:この回答は@zakiの回答とは完全に異なると思います。ここでは、DOM内の要素を再レンダリングしています。他の回答では、彼は単にsrcプレーヤーの属性を「ブランク」にしています。
Pioneer Skies

0

オーディオが再生状態かどうかを確認し、currentTimeプロパティをリセットするとよいと思います。

if (sound.currentTime !== 0 && (sound.currentTime > 0 && sound.currentTime < sound.duration) {
    sound.currentTime = 0;
}
sound.play();

0

私にとって、そのコードは正常に動作しています。(IE10 +)

var Wmp = document.getElementById("MediaPlayer");                
    Wmp.controls.stop();

<object classid="clsid:6BF52A52-394A-11D3-B153-00C04F79FAA6"
    standby="Loading áudio..." style="width: 100%; height: 170px" id="MediaPlayer">...

この助けを願っています。


0

私がやりたいのは、Angular2を使用してコントロールを完全に削除し、次の曲にオーディオパスがあるときに再ロードすることです。

<audio id="audioplayer" *ngIf="song?.audio_path">

次に、コードでそれをアンロードしたいとき、私はこれを行います:

this.song = Object.assign({},this.song,{audio_path: null});

次の曲が割り当てられると、コントロールは完全に最初から再作成されます。

this.song = this.songOnDeck;

0

このエラーを回避する簡単な方法は、エラーをキャッチすることです。

audioElement.play()はpromiseを返すため、.catch()を含む次のコードでこの問題を十分に管理できます。

function playSound(sound) {
  sfx.pause();
  sfx.currentTime = 0;
  sfx.src = sound;
  sfx.play().catch(e => e);
}

注:下位互換性のために、矢印関数を無名関数に置き換えることができます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.