HTML 5 音频播放器剩余时间显示延迟
HTML 5 Audio Player remaining time show delay
我的音频播放器有问题,当用户按下播放键时,start-time
计时器会立即显示,但 remaining-time
计时器会延迟显示。我对 JS 比较陌生,所以我不能自己找出问题。
有人可以帮我同步计时器(开始和剩余)显示播放事件吗?
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;
}
}
})();
}
}
看起来不错,这个是错误的html。在这段代码中,只需将 class rem-time
替换为 end-time
.
<small style="float: right; position: relative; right: 21px;" class="end-time" onclick="showhideRemaining(this)"></small>
我认为问题的根源在于代码的性能。我看不出两个计数器之间有很大的时间差异,但这里有一些改进建议:
你有padTime功能,就用它吧(见第2点)!
function padTime(t) {
return t < 10 ? "0" + t : t;
}
没有不必要的或过早的字符串转换:
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);
}
不要反复查询元素:
if (player.readyState === 4) {
jQuery(".end-time").html(totalLength);
jQuery(".start-time").html(currentTime);
}
在这里,不是每次在 ontimeupdate
回调中查询元素 (jQuery(".end-time")
),而是将引用保存在回调函数之外的变量中。
限制颜色更新。
setInterval(function() {
SetSeekColor();
}, 34);
每毫秒更新一次颜色太过分了。 34 毫秒应该等于 30fps 左右。
我注意到您计划在一个页面上显示多个播放器 (initPlayers(num)
)。这里有一些想法:
- 初始化玩家时,将每个玩家及其 UI 元素保存在对象
中
initPlayers(jQuery("#player-container").length);
:ID 在整个 HTML 文档中(必须)是唯一的。这行不通,将其更改为 class.
我的音频播放器有问题,当用户按下播放键时,start-time
计时器会立即显示,但 remaining-time
计时器会延迟显示。我对 JS 比较陌生,所以我不能自己找出问题。
有人可以帮我同步计时器(开始和剩余)显示播放事件吗?
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;
}
}
})();
}
}
看起来不错,这个是错误的html。在这段代码中,只需将 class rem-time
替换为 end-time
.
<small style="float: right; position: relative; right: 21px;" class="end-time" onclick="showhideRemaining(this)"></small>
我认为问题的根源在于代码的性能。我看不出两个计数器之间有很大的时间差异,但这里有一些改进建议:
你有padTime功能,就用它吧(见第2点)!
function padTime(t) { return t < 10 ? "0" + t : t; }
没有不必要的或过早的字符串转换:
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); }
不要反复查询元素:
if (player.readyState === 4) { jQuery(".end-time").html(totalLength); jQuery(".start-time").html(currentTime); }
在这里,不是每次在
ontimeupdate
回调中查询元素 (jQuery(".end-time")
),而是将引用保存在回调函数之外的变量中。限制颜色更新。
setInterval(function() { SetSeekColor(); }, 34);
每毫秒更新一次颜色太过分了。 34 毫秒应该等于 30fps 左右。
我注意到您计划在一个页面上显示多个播放器 (initPlayers(num)
)。这里有一些想法:
- 初始化玩家时,将每个玩家及其 UI 元素保存在对象 中
initPlayers(jQuery("#player-container").length);
:ID 在整个 HTML 文档中(必须)是唯一的。这行不通,将其更改为 class.