web-dev-qa-db-fra.com

Comment puis-je obtenir la durée audio html5

J'ai un tag html5 <audio> dans la page, mais comment puis-je connaître sa durée?

<audio controls="">
    <source src="p4.2.mp3">
</audio>
23
hh54188

Sur quel navigateur essayez-vous cela? Sur certains navigateurs, duration ne fonctionne pas correctement, renvoyer NaN comme vous l'avez mentionné.

Assurez-vous également que le fichier audio a été chargé avant de tenter de récupérer la durée?

16
Ian Devlin
var au = document.createElement('audio');
au.addEventListener('loadedmetadata',function(){
    au.setAttribute('data-time',au.duration);
},false);
9
Fábio Zangirolami

Dans un commentaire ci-dessus, il a été mentionné que la solution consiste à lier un descripteur d'événement à l'événement loadingmetadata. Voici comment j'ai fait ça - 

audio.onloadedmetadata = function() {
  alert(audio.duration);
};
7
ThisClark

Solution 2018:

Vous obtiendrez undefined ou NaN (pas un nombre) lorsque les métadonnées audio ne sont pas encore chargées. C'est pourquoi certaines personnes ont suggéré d'utiliser onloadedmetadata pour s'assurer que les métadonnées du fichier audio sont extraites en premier. De plus, ce que la plupart des gens n'ont pas mentionné, c'est que vous devez cibler le premier index de l'élément audio DOM avec [0] comme ceci:

- Vanille Javascript:

var audio = $("#audio-1")[0];
audio.onloadedmetadata = function() {
  alert(audio.duration);
};

Si cela ne fonctionne pas, essayez ceci, mais pas si fiable et dépend de la connexion des utilisateurs:

setTimeout(function () {
    var audio = $("#audio-1")[0];
    console.log("audio", audio.duration);
}, 100);

- JQuery:

$(document).ready(function() {
   var audio = $("#audio-1")[0];
   $("#audio-1").on("loadedmetadata", function() {
       alert(audio.duration);
   }); 
});
5
AlexioVay
2
Mossawi

J'ai utilisé l'événement "canplaythrough" pour obtenir la durée de la piste. J'ai un cas où j'ai deux joueurs et je veux arrêter le deuxième joueur 2 secondes avant la fin du premier. 

$('#' + _currentPlayerID).on("canplaythrough", function (e) {   
    var seconds = e.currentTarget.duration;    
    var trackmills = seconds * 1000;
    var subTimeout = trackmills - 2000; //2 seconds before end

    //console.log('seconds ' + seconds);
    //console.log('trackmills ' + trackmills);
    //console.log('subTimeout ' + subTimeout);

    //Stop playing before the end of thet track
    //clear this event in the Pause Event
    _player2TimeoutEvent = setTimeout(function () { pausePlayer2(); }, subTimeout);

});
1
Patrick

Je me débattais avec le chargement de la durée dans un composant React donc, après la solution de @ AlexioVay, voici une réponse si vous utilisez React:

Cela suppose que vous utilisez une ref pour votre classe de composants audio dont vous aurez besoin pour cibler les éléments audio pour vos gestionnaires de lecture/pause.

<audio /> élément:

<audio ref={audio => { this.audio = audio }} src={this.props.src} preload="auto" />

Puis dans votre componentDidMount():

componentDidMount() {

    const audio = this.audio

    audio.onloadedmetadata = () => {
        console.log(audio.duration)
        this.setState({
           duration: this.formatTime(audio.duration.toFixed(0))
        })
    }
}

Et enfin la fonction formatTime():

formatTime(seconds) {
    const h = Math.floor(seconds / 3600)
    const m = Math.floor((seconds % 3600) / 60)
    const s = seconds % 60
    return [h, m > 9 ? m : h ? '0' + m : m || '0', s > 9 ? s : '0' + s]
        .filter(a => a)
        .join(':')
}

Avec cela, la durée au format h:mm:ss s'affichera dès que les données audio src seront chargées. Douceur.

0
joshuaiz

Pour obtenir la fin de la lecture, il faut que 'loop = false' avec l'événement 'onended'. Si loop = true, onended ne fonctionne pas;)

Pour créer une liste de lecture, vous devez définir loop = false pour utiliser l'événement 'onended' afin de lire la chanson suivante.

pour la durée si votre script est correctement exécuté, vous pouvez récupérer la durée n’importe où. Si la valeur de 'duration' est NaN, le navigateur ne trouve pas le fichier. Si la valeur est 'Infinity' 'INF' c'est un streaming, dans ce cas, ajoute 1 mn par rapport au temps de lecture 'currentime' . Pour * I.E c'est de la merde. L’heure actuelle peut être supérieure à la durée, auquel cas vous faites: Var duration = (this.currentime> this.duration)? this.currenttime: this.duration;

C'est (O_ °)

0
Cherif