Как я могу получить продолжительность аудио html5

У меня есть тег html5 <audio> на странице, но как узнать время его действия?

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

person hh54188    schedule 26.06.2012    source источник


Ответы (7)


Решение 2020:

Вы получите undefined или NaN (не число), если метаданные аудио еще не загружены. Поэтому некоторые люди предлагали использовать onloadedmetadata, чтобы сначала получить метаданные аудиофайла. Кроме того, большинство людей не упомянули, что вы должны настроить таргетинг на первый индекс элемента audio DOM с помощью [0], например:

- Ванильный Javascript:

var audio = document.getElementById('audio-1');
audio.onloadedmetadata = function() {
  alert(audio.duration);
};

Если это не сработает, попробуйте это, но не так надежно и зависит от подключения пользователей:

setTimeout(function () {
    var audio = document.getElementById('audio-1');
    console.log("audio", audio.duration);
}, 100);

- JQuery:

$(document).ready(function() {
   var audio = $("#audio-1")[0];
   $("#audio-1").on("loadedmetadata", function() {
       alert(audio.duration);
   }); 
});
person AlexioVay    schedule 17.12.2017
comment
С каких пор было $ (# audio-1) [0]; Ванильный JavaScript? Оба ваших примера относятся к jQuery - не уверен, что вы понимаете разницу. Ваниль будет document.getElementById ('audio-1'); вместо этого здесь. - person Richard Edwards; 05.08.2020
comment
@RichardEdwards Спасибо, что указали на это. В то время, когда я писал этот ответ, я в основном использовал JQuery, прежде чем полностью переключился на Vanilla JS и не заметил этой опечатки. - person AlexioVay; 07.08.2020

В приведенном выше комментарии упоминалось, что решение состоит в том, чтобы привязать дескриптор события к загруженным метаданным события. Вот как я это сделал -

audio.onloadedmetadata = function() {
  alert(audio.duration);
};
person ThisClark    schedule 30.01.2016

Я боролся с загрузкой продолжительности в компоненте React, поэтому, следуя решению @ AlexioVay, вот ответ, если вы используете React:

Предполагается, что вы используете ref для своего класса аудиокомпонентов, который вам нужно будет нацелить на audio элементы для вашего обработчика (ов) воспроизведения / паузы.

<audio /> элемент:

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

Тогда в вашем componentDidMount():

componentDidMount() {

    const audio = this.audio

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

И, наконец, функция 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(':')
}

При этом продолжительность в формате h:mm:ss будет отображаться, как только будут загружены данные источника звука. Сладость.

person joshuaiz    schedule 28.08.2018
comment
Спасибо, что упомянули меня. Можете ли вы также предоставить свое решение для хуков React? - person AlexioVay; 25.03.2020

Я использовал событие canplaythrough, чтобы получить продолжительность трека. У меня есть случай, когда у меня есть два игрока, и я хочу остановить второго игрока за 2 секунды до завершения первого.

$('#' + _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);

});
person Patrick    schedule 09.02.2016

Просто используйте audioElement.duration

person Dave Hogan    schedule 26.06.2012
comment
Нет, не работает, пробовал: var audio = $('#audio')[0]; console.log('audio', audio.duration); но результат NaN - person hh54188; 26.06.2012
comment
Это дает правильную продолжительность (проверено в Firefox), но только после того, как произошло событие loadedmetadata. - person Michael Franzl; 14.05.2017
comment
Кажется, работает, когда вы используете setTimeout(function () { ... }, 10); вместо того, чтобы запускать его сразу. - person AlexioVay; 17.12.2017
comment
@AlexioVay прав насчет тайм-аута, у файла должен быть момент для загрузки, прежде чем его можно будет протестировать - person Jeff Clayton; 09.04.2021

Чтобы получить конец чтения, необходимо, чтобы 'loop = false' с событием 'onended'. Если loop = true, onended не работает;)

Чтобы создать список для воспроизведения, вы должны установить loop = false, чтобы использовать событие onended для воспроизведения следующей песни.

для продолжительности, если ваш сценарий выполнен правильно, вы можете восстановить продолжительность где угодно. Если значение «duration» равно NaN, файл не найден браузером. Если значение «Infinity» «INF», это потоковая передача, в этом случае добавляется 1 мин по сравнению со временем чтения «currentime». Для * I.E это лажа. Текущее время может быть больше, чем продолжительность, и в этом случае вы делаете: var duration = (this.currentime> this.duration)? this.currenttime: this.duration;

Это (O_ °)

person Cherif    schedule 02.03.2019

лучше использовать событие вот так ...

ObjectAudio.onprogress  =function(){
    if(this.buffered.length){
    var itimeend = (this.buffered.length>1)? this.buffered.end(this.buffered.length-1):this.buffered.end(0);
    ....
        Your code here.......
    }
}
person Cherif    schedule 13.03.2019