【问题标题】:HTML5 <audio> playback with fade in and fade outHTML5 <audio> 播放淡入淡出
【发布时间】:2011-11-19 01:44:59
【问题描述】:

我想在带有淡入淡出周期的随机位置开始和停止 HTML5 播放,以使聆听体验更加流畅。

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

【问题讨论】:

    标签: javascript html audio volume


    【解决方案1】:

    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 实现,所以我将发布一个原版 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;
    }
    

    【讨论】:

    • 你刚刚为我节省了很多时间和困惑。谢谢!
    • N00b 问题,但是 newVolume 函数会包含什么?我猜这是一个 5 步音量增加左右?
    • "newVolume is a double between 0 and 1" 这意味着给它赋值newVolume=0.2? @mrjedmao
    • 这是异步调用吗?
    • @WesModes 是的,但是如果您希望在淡入淡出完成后发生某些事情,您可以在参数列表的末尾添加一个回调函数。
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

      这里有源代码:

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

      【讨论】:

        【解决方案4】:

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

        HTML:

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

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

        【讨论】:

        • 您能否用英语回答以“接触”更大的目标群体?
        【解决方案5】:

        这是一个用于淡化音频的简单超时函数(在本例中从 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,什么都不做。
        猜你喜欢
        • 2012-08-07
        • 2014-06-12
        • 2017-01-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-01-19
        • 1970-01-01
        相关资源
        最近更新 更多