Воспроизведение HTML5 ‹аудио› с нарастанием и затуханием

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

Какие механизмы существуют для этого? Вручную увеличить громкость с помощью setTimeout()?


person Mikko Ohtamaa    schedule 17.09.2011    source источник


Ответы (5)


Путь jQuery...

$audio.animate({volume: newVolume}, 1000);

Редактировать: где $audio — аудиоэлемент, заключенный в jQuery, а newVolume — двойное значение между 0 и 1.

Редактировать: эффективная громкость мультимедиа элемента — это громкость, интерпретируемая относительно диапазона от 0,0 до 1,0, где 0,0 — это тишина, а 1,0 — самая громкая настройка, промежуточные значения увеличивают громкость. Диапазон не обязательно должен быть линейным. http://www.w3.org/html/wg/drafts/html/master/embedded-content.html#efficient-media-volume

Редактировать: люди публикуют ванильные реализации JavaScript, поэтому я опубликую ванильный TypeScript, который сохраняет анимацию колебания jQuery (просто удалите информацию о типе, если вы хотите запустить это в JavaScript). Отказ от ответственности, это полностью не проверено:

export async function adjustVolume(
    element: HTMLMediaElement,
    newVolume: number,
    {
        duration = 1000,
        easing = swing,
        interval = 13,
    }: {
        duration?: number,
        easing?: typeof swing,
        interval?: number,
    } = {},
): Promise<void> {
    const originalVolume = element.volume;
    const delta = newVolume - originalVolume;

    if (!delta || !duration || !easing || !interval) {
        element.volume = newVolume;
        return Promise.resolve();
    }

    const ticks = Math.floor(duration / interval);
    let tick = 1;

    return new Promise(resolve => {
        const timer = setInterval(() => {
            element.volume = originalVolume + (
                easing(tick / ticks) * delta
            );

            if (++tick === ticks + 1) {
                clearInterval(timer);
                resolve();
            }
        }, interval);
    });
}

export function swing(p: number) {
    return 0.5 - Math.cos(p * Math.PI) / 2;
}
person jedmao    schedule 31.10.2012
comment
И вы только что сэкономили мне кучу времени и путаницу. Спасибо! - person Sofox; 15.02.2013
comment
N00b вопрос, а что войдет в функцию newVolume? Я предполагаю, что это 5-ступенчатое увеличение громкости или около того? - person Kanishka Ganguly; 09.03.2014
comment
@KanishkaGanguly это двойное число между 0 и 1 html5doctor.com/html5-audio- состояние игры - person jedmao; 10.03.2014
comment
Тот, кто проголосовал против этого, возможно, захочет уточнить, почему вам не нравится этот трюк. - person jedmao; 23.09.2014
comment
newVolume - это двойное значение между 0 и 1. Это означает, что ему нужно присвоить значение, подобное newVolume=0.2? @mrjedmao - person Faisal Ashfaq; 12.10.2014
comment
@FaisalAshfaq все это указано в спецификации HTML5. Эффективная громкость мультимедиа элемента — это громкость, интерпретируемая относительно диапазона от 0,0 до 1,0, где 0,0 — это тишина, а 1,0 — самая громкая настройка, значения между ними увеличиваются по громкости. Диапазон не обязательно должен быть линейным. w3.org/html/ wg/drafts/html/мастер/ - person jedmao; 13.10.2014
comment
вау, после многих лет использования Jquery он до сих пор удивляет меня своей полнотой. Никогда бы не подумал, что это действительно работает. Я использовал Jplayer для этих целей, и это совершенно не нужно, если вы на самом деле не заботитесь об отступлении Adobe Flash от динозавров. - person Abram; 05.04.2015
comment
Это асинхронный вызов? - person Wes Modes; 18.04.2015
comment
@WesModes Да, но вы можете добавить функцию обратного вызова в конец списка аргументов, если хотите, чтобы что-то произошло после завершения затухания. - person Inkling; 03.12.2015
comment
что значит обернуть аудио элемент в jquery ($ audio)? это относится к чему-то вроде идентификатора ползунка диапазона? или переменная, которая идентифицирует объект HTMLaudioelement? - person mrtunes; 20.07.2020
comment
const $audio = $(audioElement); делает $audio звуковым элементом, обернутым в jQuery. Только после этого вы можете вызвать для него метод .animate(). - person jedmao; 11.09.2020
comment
@jedmao Почему вы выбрали 13 для интервала? - person ffxsam; 01.11.2020
comment
@ffxsam просто добавьте линейный в качестве третьего аргумента к animate. api.jquery.com/animate jqueryui.com/easing - person jedmao; 05.12.2020
comment
Исправлена ​​небольшая ошибка. Сравнение тиков должно быть tick === ticks + 1, иначе я заметил, что целевой объем так и не был достигнут. - person ffxsam; 28.01.2021

Старый вопрос, но если кто-то ищет ванильный JS-способ сделать это, я просто написал кое-что для проекта и подумал, что опубликую его здесь, так как мои поиски решения были напрасными. Если вы уже работаете с видео- или аудиоэлементом, есть большая вероятность, что вам все равно не нужно использовать jQuery для управления объектом.

function getSoundAndFadeAudio (audiosnippetId) {

    var sound = document.getElementById(audiosnippetId);

    // Set the point in playback that fadeout begins. This is for a 2 second fade out.
    var fadePoint = sound.duration - 2; 

    var fadeAudio = setInterval(function () {

        // Only fade if past the fade out point or not at zero already
        if ((sound.currentTime >= fadePoint) && (sound.volume != 0.0)) {
            sound.volume -= 0.1;
        }
        // When volume at zero stop all the intervalling
        if (sound.volume === 0.0) {
            clearInterval(fadeAudio);
        }
    }, 200);

}

Эта версия не позволяет редактировать время затухания (установлено на 2 секунды), но вы можете довольно легко аргументировать это. Чтобы полностью обобщить это, потребуется дополнительная логика, чтобы также сначала проверить, какая громкость была установлена, чтобы узнать фактор, с помощью которого она исчезнет. В нашем случае мы уже установили громкость на 1, а регулятор громкости в браузере не находится в руках пользователей, поскольку он предназначен для слайд-шоу, поэтому в нем не было необходимости.

Чтобы перейти к определенной части аудио, вам нужно проверить доступный временной диапазон и просто установить currentTime случайным образом в зависимости от того, что доступно.

person user801985    schedule 11.11.2014

Я создал для этого простую библиотеку, используя setTimeout().

Исходный код доступен здесь:

https://github.com/miohtama/Krusovice/blob/master/src/tools/fade.js

person Mikko Ohtamaa    schedule 24.10.2011

Вот несколько функций для затухания текущей песни и появления новой песни.

HTML:

<audio loop autoplay="1" onPlay="audioVolumeIn(this);"><br>
    <source src="/test/new/imgs/audio_bg.ogg" type="audio/ogg; codecs=vorbis"><br>
    <source src="/test/new/imgs/audio_bg.wav" type="audio/wav"><br>
<source src="/test/new/imgs/audio_bg.mp3" type="audio/mpeg"><br>

Javascript:

    function audioVolumeIn(q){
       if(q.volume){
          var InT = 0;
          var setVolume = 0.2; // Target volume level for new song
          var speed = 0.005; // Rate of increase
          q.volume = InT;
          var eAudio = setInterval(function(){
              InT += speed;
              q.volume = InT.toFixed(1);
              if(InT.toFixed(1) >= setVolume){
                 clearInterval(eAudio);
                 //alert('clearInterval eAudio'+ InT.toFixed(1));
              };
          },50);
       };
   };

   function audioVolumeOut(q){
       if(q.volume){
          var InT = 0.4;
          var setVolume = 0;  // Target volume level for old song 
          var speed = 0.005;  // Rate of volume decrease
          q.volume = InT;
          var fAudio = setInterval(function(){
              InT -= speed;
              q.volume = InT.toFixed(1);
              if(InT.toFixed(1) <= setVolume){
                 clearInterval(fAudio);
                 //alert('clearInterval fAudio'+ InT.toFixed(1));
              };
          },50);
       };
   };
person user3126867    schedule 27.04.2016
comment
Не могли бы вы ответить на английском языке, чтобы «охватить» более широкую целевую группу? - person Mario; 10.09.2018

Это простая функция тайм-аута для затухания звука (в данном случае от 0 до 100). Он использует глобальную переменную. Тем не менее, все еще борюсь со всем пакетом. Я обязательно проверю способ jQuery от sfjedi.

function FadeIn() {

    var sound = document.getElementById('audiosnippet');

    var vol = $.global.volume;

    if ( vol < 100 )
        {
            sound.volume = (vol / 100);
            $.global.volume = $.global.volume + 10;
            setInterval(function() { FadeIn() }, 1200);
        }

    }
}
person jibbon    schedule 22.11.2012
comment
Почему такой большой тайм-аут? вы могли бы добиться более плавного затухания, уменьшив как тайм-аут, так и дельту громкости. - person andrewrk; 28.07.2013
comment
Я думаю, вы хотите использовать setTimeout вместо setInterval? В вашем случае вы создаете все больше и больше интервалов каждый раз, когда вызываете FadeIn(), которые никогда не отменяются. В конце концов, они просто бегут сзади и ничего не делают, как только громкость достигает 100. - person Mathias; 20.08.2013