HTML5 <audio> 播放淡入淡出

IT技术 javascript html audio volume
2021-03-13 12:30:07

我想在随机位置开始和停止 HTML5 播放,并带有淡入和淡出周期,以平滑收听体验。

为此存在什么样的机制?使用 setTimeout() 手动增大音量?

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#effective-media-volume

编辑:人们正在发布普通的 JavaScript 实现,所以我将发布一个保留 jQuery 摆动动画的普通 TypeScript(如果你想在 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;
}
N00b 问题,但是什么会进入 newVolume 函数?我猜这是一个 5 步的音量增加左右?
2021-04-21 12:30:07
@WesModes 是的,但是如果您希望在淡入淡出完成后发生某些事情,您可以在参数列表的末尾添加一个回调函数。
2021-04-22 12:30:07
这是异步调用吗?
2021-04-24 12:30:07
“newVolume 是一个介于 0 和 1 之间的双精度值”这意味着为其分配一个值,例如newVolume=0.2@mrjedmao
2021-04-25 12:30:07
你刚刚为我节省了大量时间和混乱。谢谢!
2021-05-07 12:30:07

老问题,但如果有人正在寻找一种香草 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。

我使用 setTimeout() 为此创建了一个简单的库。

源代码可在此处获得:

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

这里有几个功能可以淡出当前歌曲和淡入新歌曲。

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);
       };
   };
你能用英语回答以“达到”更大的目标群体吗?
2021-04-28 12:30:07

这是一个用于淡入淡出音频的简单超时函数(在本例中为 0 到 100)。它使用一个全局变量。尽管如此,仍然在为整个包裹而苦苦挣扎。我肯定会检查 sfjedi 的 jQuery 方式。

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

    }
}
我认为你的意思是使用setTimeout而不是setInterval? 在您的情况下,您每次调用时都会创建越来越多的间隔,而这些间隔FadeIn()永远不会被取消。最终他们只是跑在后面,一旦音量达到 什么都不做100
2021-05-06 12:30:07
为什么会有这么高的超时时间?通过减少超时和音量增量,您可以更平滑地淡入淡出。
2021-05-07 12:30:07