HTML5 Audio stop function

我的梦境 提交于 2019-11-26 11:16:48

instead of stop() you could try with:

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

this should have the desired effect

first you have to set an id for your audio element

in your js :

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

var oldSrc = ply.src;// just to remember the old source

ply.src = "";// to stop the player you have to replace the source with nothing

Here is my way of doing stop() method:

Somewhere in code:

audioCh1: document.createElement("audio");

and then in stop():

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

In this way we don`t produce additional request, the old one is cancelled and our audio element is in clean state (tested in Chrome and FF) :>

From my own javascript function to toggle Play/Pause - since I'm handling a radio stream, I wanted it to clear the buffer so that the listener does not end up coming out of sync with the radio station.

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;
        }
}

Turns out, just clearing the currentTime doesn't cut it under Chrome, needed to clear the source too and load it back in. Hope this helps.

This method works:

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

But if you don't want to have to write these two lines of code every time you stop an audio you could do one of two things. The second I think is the more appropriate one and I'm not sure why the "gods of javascript standards" have not made this standard.

First method: create a function and pass the audio

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

//then using it:
stopAudio(audio);

Second method (favoured): extend the Audio class:

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

I have this in a javascript file I called "AudioPlus.js" which I include in my html before any script that will be dealing with audio.

Then you can call the stop function on audio objects:

audio.stop();

FINALLY CHROME ISSUE WITH "canplaythrough":

I have not tested this in all browsers but this is a problem I came across in Chrome. If you try to set currentTime on an audio that has a "canplaythrough" event listener attached to it then you will trigger that event again which can lead to undesirable results.

So the solution, similar to all cases when you have attached an event listener that you really want to make sure it is not triggered again, is to remove the event listener after the first call. Something like this:

//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 ...
});

BONUS:

Note that you can add even more custom methods to the Audio class (or any native javascript class for that matter).

For example if you wanted a "restart" method that restarted the audio it could look something like:

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

As a side note and because I was recently using the stop method provided in the accepted answer, according to this link:

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

by setting currentTime manually one may fire the 'canplaythrough' event on the audio element. In the link it mentions Firefox, but I encountered this event firing after setting currentTime manually on Chrome. So if you have behavior attached to this event you might end up in an audio loop.

I was having same issue. A stop should stop the stream and onplay go to live if it is a radio. All solutions I saw had a disadvantage:

  • player.currentTime = 0 keeps downloading the stream.
  • player.src = '' raise error event

My solution:

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

And the HTML

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

shamangeorge wrote:

by setting currentTime manually one may fire the 'canplaythrough' event on the audio element.

This is indeed what will happen, and pausing will also trigger the pause event, both of which make this technique unsuitable for use as a "stop" method. Moreover, setting the src as suggested by zaki will make the player try to load the current page's URL as a media file (and fail) if autoplay is enabled - setting src to null is not allowed; it will always be treated as a URL. Short of destroying the player object there seems to be no good way of providing a "stop" method, so I would suggest just dropping the dedicated stop button and providing pause and skip back buttons instead - a stop button wouldn't really add any functionality.

user3062615

This approach is "brute force", but it works assuming using jQuery is "allowed". Surround your "player" <audio></audio> tags with a div (here with an id of "plHolder").

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

Then this javascript should work:

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

It don't work sometimes in chrome,

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

just change like that,

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

I believe it would be good to check if the audio is playing state and reset the currentTime property.

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

for me that code working fine. (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">...

Hope this help.

What I like to do is completely remove the control using Angular2 then it's reloaded when the next song has an audio path:

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

Then when I want to unload it in code I do this:

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

When the next song is assigned, the control gets completely recreated from scratch:

this.song = this.songOnDeck;

The simple way to get around this error is to catch the error.

audioElement.play() returns a promise, so the following code with a .catch() should suffice manage this issue:

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

Note: You may want to replace the arrow function with an anonymous function for backward compatibility.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!