HTML 5 Audio Player оставшееся время показа задержки - PullRequest
0 голосов
/ 17 сентября 2018

У меня проблема с аудиоплеером, когда пользователи нажимают кнопку воспроизведения, таймер start-time отображается мгновенно, но таймер remaining-time показывает с задержкой.Я относительно новичок в JS, поэтому не могу самостоятельно определить проблему.

Может ли кто-нибудь помочь мне с синхронизацией таймеров (запуска и оставшихся) на игровом событии?

CodePen

var isSeeking = false;
var seek = document.getElementById("seekObj");
var player = document.getElementById("player");
SetSeekColor();
function calculateTotalValue(length) {
  var minutes = Math.floor(length / 60),
    seconds_int = length - minutes * 60,
    seconds_str = seconds_int.toString(),
    seconds = seconds_str.split(".")[0],
    temp_min = minutes.toString().length === 1 ? "0" + minutes : minutes,
    temp_sec = seconds.toString().length === 1 ? "0" + seconds : seconds;
  return temp_min + ":" + temp_sec;
}

function calculateCurrentValue(_seconds) {
  function padTime(t) {
    return t < 10 ? "0" + t : t;
  }

  if (typeof _seconds !== "number") return "";
  if (_seconds < 0) {
    _seconds = Math.abs(_seconds);
    //console.log(_seconds);
  }
  var hours = Math.floor(_seconds / 3600),
    minutes = Math.floor((_seconds % 3600) / 60),
    seconds = Math.floor(_seconds % 60);
  var hour = hours > 0 ? padTime(hours) + ":" : "";
  return hour + padTime(minutes) + ":" + padTime(seconds);
}
function setupSeek() {
  seek.max = player.duration;
}
function seekAudio() {
  isSeeking = true;
  player.currentTime = seek.value;
  isSeeking = false;
}
var prevcurrentime = 0;
function initProgressBar() {
  if (!isSeeking) {
    seek.value = player.currentTime;
  }
  var length = player.duration;
  var current_time = player.currentTime;

  // calculate total length of value
  var totalLength = calculateTotalValue(length);


  // calculate current value time
  var currentTime = calculateCurrentValue(current_time);
  if (player.readyState === 4) {
      jQuery(".end-time").html(totalLength);
    jQuery(".start-time").html(currentTime);
  }
  //checking if the current time is bigger than the previous or else there will be sync different between remaining and current
  if (currentTime > prevcurrentime) {
    //calculate the remaining time
    var rem_time = length - current_time;
    jQuery(".rem-time").html(calculateCurrentValue(rem_time));
  }
  //setting the previouscurrent time to this current time
  prevcurrentime = currentTime;

  if (player.currentTime == player.duration) {
    $("#play-btn").removeClass("pause");
  }
}

function initPlayers(num) {
  // pass num in if there are multiple audio players e.g 'player' + i

  for (var i = 0; i < num; i++) {
    (function() {
      // Variables
      // ----------------------------------------------------------
      // audio embed object
      var playerContainer = document.getElementById("player-container"),
        player = document.getElementById("player"),
        isPlaying = false,
        playBtn = document.getElementById("play-btn");

      // Controls Listeners
      // ----------------------------------------------------------
      if (playBtn != null) {
        playBtn.addEventListener("click", function() {
          togglePlay();
        });
      }

      // Controls & Sounds Methods
      // ----------------------------------------------------------
      function togglePlay() {
        if (player.paused === false) {
          player.pause();
          isPlaying = false;
          $("#play-btn").removeClass("pause");
        } else {
          $(".start-time").html("");
          player.play();
          $("#play-btn").addClass("pause");
          isPlaying = true;
        }
      }
    })();
  }
}

Ответы [ 2 ]

0 голосов
/ 17 сентября 2018

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

  1. У вас есть функция padTime, поэтому используйте ее (см. Пункт 2)!

    function padTime(t) {
        return t < 10 ? "0" + t : t;
    }
    
  2. нет ненужного или раннего преобразования в строки:

    function calculateTotalValue(length) {
        var minutes = Math.floor(length / 60);
        var seconds = Math.floor(length - minutes * 60);
    
        // use the padTime function here with numbers
        return padTime(minutes) + ":" + padTime(seconds); 
    }
    
  3. не запрашивать элементы снова и снова:

    if (player.readyState === 4) {
        jQuery(".end-time").html(totalLength);
        jQuery(".start-time").html(currentTime);
    }
    

    Здесь вместо того, чтобы каждый раз запрашивать элементы (jQuery(".end-time")) в вашем обратном вызове ontimeupdate, сохраняйте ссылки в переменных вне функции обратного вызова.

  4. ограничить обновления цвета.

    setInterval(function() {
        SetSeekColor();
    }, 34);
    

    Обновление цвета каждую миллисекунду просто излишне. 34 миллисекунды должны равняться примерно 30 кадрам в секунду.


Я заметил, что у вас есть несколько игроков на одной странице (initPlayers(num)). Вот несколько мыслей:

  • Когда вы инициализируете игроков, сохраняйте каждого игрока с его элементами пользовательского интерфейса в объекте
  • initPlayers(jQuery("#player-container").length);: идентификаторы (должны быть) уникальны во всем HTML-документе. Это не сработает, измените его на класс.
0 голосов
/ 17 сентября 2018

выглядит хорошо, это ошибка в HTML.В этом фрагменте кода просто замените класс rem-time на end-time.

<small style="float: right; position: relative; right: 21px;" class="end-time" onclick="showhideRemaining(this)"></small>
...