Función de parada de audio HTML5

147

Estoy reproduciendo un pequeño clip de audio al hacer clic en cada enlace de mi navegación

Código 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>

Código JS:

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

Funciona bien hasta ahora.

El problema es cuando ya se está ejecutando un clip de sonido y hago clic en cualquier enlace, no sucede nada.

Traté de detener el sonido que ya se reproduce al hacer clic en el enlace, pero no hay un evento directo para eso en la API de audio de HTML5

Intenté seguir el código pero no funciona

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

¿Alguna sugerencia por favor?

Alok Jain
fuente

Respuestas:

350

En lugar de que stop()puedas probar con:

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

Esto debería tener el efecto deseado.

kr1
fuente
66
Esto no funciona en Chrome. El elemento de audio sigue cargando audio, que no es lo que debería suceder.
Pieter
3
En Chrome, la <audio>carga continúa también con el preloadatributo forzado noney el <source>src de 's eliminado.
Pioneer Skies
66
Esto funciona, gracias. En una nota al margen, me encantaría saber por qué el w3c decidió no incluir un método de parada en la especificación.
Reahreic
25

primero tienes que configurar una identificación para tu elemento de audio

en tu js:

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

var oldSrc = ply.src;// solo para recordar la antigua fuente

ply.src = "";// para detener el reproductor tienes que reemplazar la fuente con nada

zaki
fuente
44
La mejor solución para la transmisión de audio
Hossein el
1
bueno ... eso hará otra solicitud de red para el archivo fuente de audio
Md. Arafat Al Mahmud
El audio no se reproducirá hasta que se cargue, y esto provocará un retraso no deseado en la reproducción de audio.
Abhi
Una buena solución del problema al reproducir una transmisión como la radio por Internet y Firefox repite el último fragmento cuando se activa la pausa / reproducción. Muchas gracias.
namikiri
14

Aquí está mi forma de hacer el método stop ():

En algún lugar del código:

audioCh1: document.createElement("audio");

y luego en stop ():

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

De esta manera, no producimos solicitudes adicionales, la anterior se cancela y nuestro elemento de audio está en estado limpio (probado en Chrome y FF):>

MrHetii
fuente
10

Estaba teniendo el mismo problema. Una parada debe detener el flujo y onplay ir a vivo si se trata de una radio. Todas las soluciones que vi tenían una desventaja :

  • player.currentTime = 0 sigue descargando la transmisión.
  • player.src = ''elevar errorevento

Mi solución:

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

Y el HTML

<audio src="http://radio-stream" id="radio" class="hidden" preload="none"></audio>
Mikel
fuente
Esto funciona en Chrome y Firefox. Sin embargo, en Firefox produce el siguiente error (en la consola) [ Security Error: Content at https://localhost/url.html may not load data from blob:https://localhost/cac32534-78b0-4a62-8355-cc8f1e708d64.] Parece que no tiene ningún efecto negativo ya que el código continúa ejecutándose después de esto (a diferencia de una excepción no detectada).
BReddy
6

Este método funciona:

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

Pero si no desea tener que escribir estas dos líneas de código cada vez que detiene un audio, puede hacer una de dos cosas. El segundo creo que es el más apropiado y no estoy seguro de por qué los "dioses de los estándares de JavaScript" no han hecho este estándar.

Primer método: crear una función y pasar el audio

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

//then using it:
stopAudio(audio);

Segundo método (preferido): ampliar la clase de audio:

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

Tengo esto en un archivo javascript que llamé "AudioPlus.js" que incluyo en mi html antes de cualquier script que se ocupe del audio.

Luego puede llamar a la función de parada en objetos de audio:

audio.stop();

FINALMENTE CROMO PROBLEMA CON "canplaythrough":

No he probado esto en todos los navegadores, pero este es un problema que encontré en Chrome. Si intenta establecer currentTime en un audio que tiene un detector de eventos "canplaythrough" adjunto, activará ese evento nuevamente, lo que puede generar resultados no deseados.

Entonces, la solución, similar a todos los casos en los que ha adjuntado un detector de eventos que realmente desea asegurarse de que no se vuelva a activar, es eliminar el detector de eventos después de la primera llamada. Algo como esto:

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

PRIMA:

Tenga en cuenta que puede agregar aún más métodos personalizados a la clase de audio (o cualquier clase nativa de JavaScript para el caso).

Por ejemplo, si deseaba un método de "reinicio" que reiniciara el audio, podría verse así:

Audio.prototype.restart= function() {
    this.pause();
    this.currentTime = 0;
    this.play();
};
Zuks
fuente
function stopAudio(audio) { audio.pause(); this.audioStream.src = ""; } Hacer esto terminó funcionando para mí y eliminó el ícono del altavoz en el navegador Chrome que aparece cuando se reproduce audio en la página. probado en Chrome versión 59.0.3071.109
lasec0203
En general, no recomendaría extender prototipos como este. Una aplicación de gran
volumen de
5

Desde mi propia función de JavaScript para alternar Reproducir / Pausa: dado que estoy manejando una transmisión de radio, quería que borrara el búfer para que el oyente no termine fuera de sincronización con la estación de radio.

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

Resulta que simplemente borrar el CurrentTime no lo corta en Chrome, también es necesario borrar la fuente y volver a cargarla. Espero que esto ayude.

James Groves
fuente
4

Como nota al margen y porque recientemente estaba usando el método de detención proporcionado en la respuesta aceptada, de acuerdo con este enlace:

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

configurando currentTime manualmente, se puede activar el evento 'canplaythrough' en el elemento de audio. En el enlace menciona Firefox, pero encontré este evento disparando después de configurar currentTime manualmente en Chrome. Entonces, si tiene un comportamiento asociado a este evento, puede terminar en un bucle de audio.

Shamangeorge
fuente
3

A veces no funciona en cromo,

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

solo cambia así,

sound.currentTime = 0;
sound.pause();
gogog
fuente
2

Shamangeorge escribió:

configurando currentTime manualmente, se puede activar el evento 'canplaythrough' en el elemento de audio.

De hecho, esto es lo que sucederá, y la pausa también desencadenará el pauseevento, lo que hace que esta técnica no sea adecuada para su uso como método de "detención". Por otra parte, si configura la srcopción sugerida por zaki, el jugador intentará cargar la URL de la página actual como un archivo multimedia (y fallará) si autoplayestá habilitada; la configuración srca nullno está permitida; siempre se tratará como una URL. A falta de destruir el objeto del jugador, parece que no hay una buena manera de proporcionar un método de "detención", por lo que sugeriría simplemente soltar el botón de detención dedicado y proporcionar en su lugar botones de pausa y saltar hacia atrás: un botón de detención realmente no agregaría ninguna funcionalidad .

Ola Tuvesson
fuente
1

Este enfoque es "fuerza bruta", pero funciona suponiendo que el uso de jQuery está "permitido". Rodea tus <audio></audio>etiquetas de "jugador" con un div (aquí con una identificación de "plHolder").

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

Entonces este javascript debería funcionar:

function stopAudio() {
    var savePlayer = $('#plHolder').html(); // Save player code
    $('#player').remove(); // Remove player from DOM
    $('#FlHolder').html(savePlayer); // Restore it
}
usuario3062615
fuente
Lo mismo se explica por zaki en su respuesta anterior, sin el uso de jquery.
Alok Jain
No experimenté con él, pero no estaba seguro de que su método funcionaría si hubiera múltiples etiquetas <source>.
user3062615
#FlHolderParece un error tipográfico para#plHolder
Pioneer cielos
1
En respuesta al comentario de @ alok-jain: Creo que esta respuesta es completamente diferente de la de @zaki. Aquí estamos volviendo a representar un elemento en el DOM, en la otra respuesta, solo está "borrando" el srcatributo del jugador.
Pioneer Skies
0

Creo que sería bueno verificar si el audio se está reproduciendo y restablecer la propiedad currentTime.

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

para mí ese código funciona bien. (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">...

Espero que esto ayude.

Ricardo G Saraiva
fuente
0

Lo que me gusta hacer es eliminar completamente el control usando Angular2 y luego se vuelve a cargar cuando la siguiente canción tiene una ruta de audio:

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

Luego, cuando quiero descargarlo en el código, hago esto:

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

Cuando se asigna la siguiente canción, el control se recrea completamente desde cero:

this.song = this.songOnDeck;
Helzgate
fuente
0

La forma simple de evitar este error es detectar el error.

audioElement.play () devuelve una promesa, por lo que el siguiente código con un .catch () debería ser suficiente para manejar este problema:

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

Nota: es posible que desee reemplazar la función de flecha con una función anónima para la compatibilidad con versiones anteriores.

James Marks
fuente