web-dev-qa-db-fra.com

Lecture <audio> HTML5 avec ouverture et fermeture en fondu

J'aimerais commencer et arrêter la lecture HTML5 dans une position aléatoire avec des périodes de fondu en entrée et en sortie afin de fluidifier l'expérience d'écoute.

Quel type de mécanismes existe pour cela? Augmentez manuellement le volume avec setTimeout ()?

27
Mikko Ohtamaa

La manière jQuery ...

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

Edit: où $ audio est un élément audio enveloppé dans jQuery et newVolume est un double entre 0 et 1.

Éditer: le volume de média effectif de l'élément est le volume, interprété par rapport à l'intervalle compris entre 0.0 et 1.0, 0.0 étant muet et 1.0 le réglage le plus fort. Les valeurs comprises entre une augmentation du volume. La plage ne doit pas nécessairement être linéaire. http://www.w3.org/html/wg/drafts/html/master/embedded-content.html#effective-media-volume

Edit: Les gens postent des implémentations JavaScript Vanilla, je vais donc poster un modèle Vanilla TypeScript qui préserve l’animation swing de jQuery (supprimez simplement les informations de type si vous voulez l’exécuter en JavaScript). Déni de responsabilité, ceci est complètement non testé:

export async function adjustVolume(
    element: HTMLMediaElement,
    newVolume: number,
    {
        duration = 1000,
        easing = swing,
        interval = 13,
    }: {
        duration?: number,
        easing?: typeof swing,
        interval?: number,
    } = {},
) {
    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<void>((resolve) => {
        const timer = setInterval(() => {
            element.volume = originalVolume + (
                easing(tick / ticks) * delta
            );
            if (++tick === ticks) {
                clearInterval(timer);
                resolve();
            }
        }, interval);
    });
}

export function swing(p: number) {
    return 0.5 - Math.cos(p * Math.PI) / 2;
}
87
jedmao

Vieille question, mais si quelqu'un cherche une façon de le faire avec Vanilla JS, je viens d'écrire quelque chose pour le projet et je pensais le poster ici car ma recherche d'une solution était vaine. Si vous travaillez déjà avec un élément vidéo ou audio, il y a de fortes chances que vous n'ayez pas vraiment besoin d'utiliser jQuery pour contrôler l'objet de toute façon.

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

}

Cette version ne permet pas de modifier le temps de fondu (défini sur 2 secondes), mais vous pouvez l'argumenter assez facilement. Pour généraliser complètement cela, une logique supplémentaire serait nécessaire pour vérifier également en premier le réglage du volume afin de connaître le facteur permettant de le réduire en fondu. Dans notre cas, nous avons déjà préréglé le volume à 1 et le contrôle du volume du navigateur est hors de la portée de l'utilisateur car il s'agit d'un diaporama, il n'était donc pas nécessaire.

Pour accéder à une partie spécifique de l'audio, vous devez vérifier la plage de temps recherchée et définir simplement le moment actuel de manière aléatoire en fonction des éléments disponibles.

19
user801985

J'ai créé une bibliothèque simple pour cela en utilisant setTimeout ().

Le code source est disponible ici:

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

3
Mikko Ohtamaa

Voici quelques fonctions permettant de fondre la chanson en cours et d’en insérer une nouvelle.

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);
       };
   };
1
user3126867

Il s’agit d’une simple fonction de temporisation pour l’affaiblissement de l’audio (de 0 à 100 dans ce cas). Il utilise une variable globale. Toujours aux prises avec tout un paquet cependant. Je vais certainement vérifier le style jQuery de 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);
        }

    }
}
0
jibbon