【问题标题】:Javascript play sound after delayJavascript延迟后播放声音
【发布时间】:2018-01-09 17:17:27
【问题描述】:

我在 javascript 中制作了一个秒表,它接受来自 get 参数的开始时间。一切正常,但我想在结束前 3 秒播放声音。到目前为止,我有这个:

HTML:

<form action="timer.php" method="get">
    <select name="hours">
        <?php for($i = 0; $i <= 24; $i++): ?>
            <option value="<?php echo $i; ?>"><?php echo $i; ?></option>
        <?php endfor; ?>
    </select>
    <select name="minutes">
        <?php for($i = 0; $i <= 59; $i++): ?>
            <option value="<?php echo $i; ?>"><?php echo $i; ?></option>
        <?php endfor; ?>
    </select>
    <select name="seconds">
        <?php for($i = 0; $i <= 59; $i++): ?>
            <option value="<?php echo $i; ?>"><?php echo $i; ?></option>
        <?php endfor; ?>
    </select>
    <input type="submit" name="submit" value="submit">
</form>

<div class="stopwatch">
    <a href="javascript:;" class="start-stopwatch">Start stopwatch</a><br>
    <a href="javascript:;" class="stop-stopwatch">Stop stopwatch</a><br>
    <span class="hours"></span>:<span class="minutes"></span>:<span class="seconds"></span>
</div>

Javasciprt:

// GetParams class to parse $_GET[]
    var GetParams = {
        getSearchParameters: function() {
            var prmstr = window.location.search.substr(1);
            return prmstr != null && prmstr != "" ? this.transformToAssocArray(prmstr) : {};
        },

        transformToAssocArray: function( prmstr ) {
            var params = {};
            var prmarr = prmstr.split("&");
            for ( var i = 0; i < prmarr.length; i++) {
                var tmparr = prmarr[i].split("=");
                params[tmparr[0]] = tmparr[1];
            }
            return params;
        }
    };

    var stopWatch = {
        TimerID : null,
        startHours   : parseInt(GetParams.getSearchParameters().hours),
        startMinutes : parseInt(GetParams.getSearchParameters().minutes),
        startSeconds : parseInt(GetParams.getSearchParameters().seconds),
        totalSeconds : parseInt(GetParams.getSearchParameters().seconds) + parseInt(GetParams.getSearchParameters().minutes) * 60 + parseInt(GetParams.getSearchParameters().hours) * 3600,

        changeTimer: function () {
            this.TimerID = setInterval(() => this.timerTick(), 1000);
            $('.start-stopwatch').hide();
        },

        timerTick: function ()
        {
            this.totalSeconds--;
            var hours   = Math.floor(this.totalSeconds / 3600);
            var minutes = Math.floor(this.totalSeconds / 60) - (hours * 60);
            var seconds = this.totalSeconds - (minutes * 60) - (hours * 3600);

            if (hours < 10)
                hours = "0" + hours;

            if (minutes < 10)
                minutes = "0" + minutes;

            if (seconds < 10)
                seconds = "0" + seconds;

            $('.stopwatch .hours').text(hours);
            $('.stopwatch .minutes').text(minutes);
            $('.stopwatch .seconds').text(seconds);

            if (this.totalSeconds === 0)
            {
                clearInterval(this.TimerID);
                new Audio("/sources/sounds/interval.mp3").play();
            }
        },

        isActive: function () {
            return (this.totalSeconds > 0);
        },

        prePopulate: function () {
            var hours   = this.startHours;
            var minutes = this.startMinutes;
            var seconds = this.startSeconds;

            if (hours < 10)
                hours = "0" + hours;

            if (minutes < 10)
                minutes = "0" + minutes;

            if (seconds < 10)
                seconds = "0" + seconds;

            $('.stopwatch .hours').text(hours);
            $('.stopwatch .minutes').text(minutes);
            $('.stopwatch .seconds').text(seconds);
        },

        stopTimer: function () {
            $('.start-stopwatch').show();
            clearInterval(this.TimerID);
        }
    };

有了这段代码,我得到了:

未处理的承诺拒绝:NotAllowedError(DOM 异常 35): 用户代理或平台不允许请求 当前上下文,可能是因为用户拒绝了权限。

我在阅读并发现声音必须与点击等用户交互相关联。用户必须先点击开始秒表,然后开始倒计时。

我还发现了这个:https://www.sitepoint.com/community/t/count-down-and-make-sound-play-on-click/30270/2

但不知道我应该如何在我的代码中实现它。

【问题讨论】:

  • 所以问题是你用代码播放mp3?
  • 你能在你的 URL 中放一个例子吗:window.location.search?
  • 你能更好地解释一下“我想在结束前 3 秒播放声音”吗?

标签: javascript jquery html audio


【解决方案1】:

我知道您可以使用click() 函数自动单击某些内容。

假设你有一个 html

<button id="mybtn"></button>

您可以通过执行以下操作单击带有 JS 的:

var mybtn = document.getElementById('mybtn');
mybtn.click();
Hopefully that helps!!

【讨论】:

    【解决方案2】:

    查看函数 playAudio()

    $(document).ready(function() {
    
      var stopWatch = {
        TimerID: null,
        startHours: 0,
        startMinutes: 0,
        startSeconds: 3,
        totalSeconds: 5,
    
        changeTimer: function() {
          this.TimerID = setInterval(() => this.timerTick(), 1000);
          $('.start-stopwatch').hide();
        },
    
        timerTick: function() {
          this.totalSeconds--;
          var hours = Math.floor(this.totalSeconds / 3600);
          var minutes = Math.floor(this.totalSeconds / 60) - (hours * 60);
          var seconds = this.totalSeconds - (minutes * 60) - (hours * 3600);
    
          if (hours < 10)
            hours = "0" + hours;
    
          if (minutes < 10)
            minutes = "0" + minutes;
    
          if (seconds < 10)
            seconds = "0" + seconds;
    
          $('.stopwatch .hours').text(hours);
          $('.stopwatch .minutes').text(minutes);
          $('.stopwatch .seconds').text(seconds);
          //I PUT 3 FOR TESTING PURPOSE
          if (this.totalSeconds === 3) {
            clearInterval(this.TimerID);
            this.playAudio();
          }
        },
        playAudio: function () { 
        //here you can set START,STOP,FILE
          var startSecond = 20,
          stopSecond = 30,
          src ="https://www.soundhelix.com/examples/mp3/SoundHelix-Song-2.mp3" ;
           
          /* you can use createElement() if you need to append 
              a new tag audio at runtime 
          var audioElement = document.createElement('audio'); */
          var audioElement = document.querySelector('audio');
          audioElement.setAttribute('src', src +  '#t=' + startSecond+','+stopSecond);
          audioElement.play();
        },
        isActive: function() {
          return (this.totalSeconds > 0);
        },
    
        prePopulate: function() {
          var hours = this.startHours;
          var minutes = this.startMinutes;
          var seconds = this.startSeconds;
    
          if (hours < 10)
            hours = "0" + hours;
    
          if (minutes < 10)
            minutes = "0" + minutes;
    
          if (seconds < 10)
            seconds = "0" + seconds;
    
          $('.stopwatch .hours').text(hours);
          $('.stopwatch .minutes').text(minutes);
          $('.stopwatch .seconds').text(seconds);
        },
    
        stopTimer: function() {
          $('.start-stopwatch').show();
          clearInterval(this.TimerID);
        }
      };
      
      $(".start-stopwatch").click(()=> stopWatch.changeTimer());
      $(".stop-stopwatch").click(()=> stopWatch.stopTimer());
      //uncomment if you want to play on load of the page
      //stopWatch.playAudio();
    });
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.2.3/jquery.min.js"></script>
    <form action="timer.php" method="get">
     ........
     <audio src="https://www.soundhelix.com/examples/mp3/SoundHelix-Song-2.mp3"></audio>
    </form>
    
    <div class="stopwatch">
      <a href="javascript:;" class="start-stopwatch">Start stopwatch</a>    <br>
       <a href="javascript:;" class="stop-stopwatch">Stop stopwatch</a><br>
       <span class="hours"></span>:
       <span class="minutes"></span>:
       <span class="seconds"></span>
    </div>

    【讨论】:

    • 在 safari 中它仍然显示:未处理的 Promise Rejection: NotAllowedError (DOM Exception 35): 在当前上下文中,用户代理或平台不允许该请求,可能是因为用户拒绝了权限。试着看看我提到的那个 deferr。如果用户不单击或不执行 JS 可以引用的操作,则 Safari 无法播放音频/视频。 Chrome 也会适应类似的东西
    • 等等,现在我记得我在 iPhone 上遇到过同样的问题,恐怕你不会在 Safari IOS 中解决这个问题。我猜你的目标也是智能设备,如果是这样,我确实找到了任何解决方案
    • 有一个很长的话题,例如。 github.com/aframevr/aframe/issues/1463
    • 是的,我只针对手机/平板电脑。它将是手机的网络应用程序
    • 能不能播放空音,定时器结束时换源?
    【解决方案3】:

    我得到了它的工作:)

      var stopWatch = {
                TimerID : null,
                startHours   : parseInt(GetParams.getSearchParameters().hours),
                startMinutes : parseInt(GetParams.getSearchParameters().minutes),
                startSeconds : parseInt(GetParams.getSearchParameters().seconds),
                totalSeconds : parseInt(GetParams.getSearchParameters().seconds) + parseInt(GetParams.getSearchParameters().minutes) * 60 + parseInt(GetParams.getSearchParameters().hours) * 3600,
                sound        : new Audio("/sources/sounds/interval.mp3"),
    
                changeTimer: function () {
                    this.sound.play();
                    this.sound.pause();
                    this.TimerID = setInterval(() => this.timerTick(), 1000);
                    $('.start-stopwatch').hide();
                },
    
                timerTick: function ()
                {
                    this.totalSeconds--;
                    var hours   = Math.floor(this.totalSeconds / 3600);
                    var minutes = Math.floor(this.totalSeconds / 60) - (hours * 60);
                    var seconds = this.totalSeconds - (minutes * 60) - (hours * 3600);
    
                    if (hours < 10)
                        hours = "0" + hours;
    
                    if (minutes < 10)
                        minutes = "0" + minutes;
    
                    if (seconds < 10)
                        seconds = "0" + seconds;
    
                    $('.stopwatch .hours').text(hours);
                    $('.stopwatch .minutes').text(minutes);
                    $('.stopwatch .seconds').text(seconds);
    
    
                    if (this.totalSeconds === 0)
                    {
                        this.sound.play();
                        clearInterval(this.TimerID);
                    }
                },
    
                isActive: function () {
                    return (this.totalSeconds > 0);
                },
    
                prePopulate: function () {
                    var hours   = this.startHours;
                    var minutes = this.startMinutes;
                    var seconds = this.startSeconds;
    
                    if (hours < 10)
                        hours = "0" + hours;
    
                    if (minutes < 10)
                        minutes = "0" + minutes;
    
                    if (seconds < 10)
                        seconds = "0" + seconds;
    
                    $('.stopwatch .hours').text(hours);
                    $('.stopwatch .minutes').text(minutes);
                    $('.stopwatch .seconds').text(seconds);
                },
    
                stopTimer: function () {
                    $('.start-stopwatch').show();
                    clearInterval(this.TimerID);
                }
            };
    

    【讨论】:

    • cool :) 如果这能解决您的问题,请接受您自己的回答
    猜你喜欢
    • 2012-06-20
    • 2011-05-09
    • 2018-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多