问题
正如标题所说,我看到了一个问题,即浏览器(在通过视频搜索时)不断地请求它应该已经拥有的字节范围。
代码
我提供了一个最小的代码示例;要复制该问题,请绕过视频上的当前时间控制并查看您的网络日志。
window.onload = function() {
var myVideo = document.getElementById('my-video');
myVideo.addEventListener('progress', function() {
var bufferedEnd = myVideo.buffered.end(myVideo.buffered.length - 1);
var duration = myVideo.duration;
if (duration > 0) {
document.getElementById('buffered-amount').style.width = ((bufferedEnd / duration) * 100) + "%";
}
});
myVideo.addEventListener('timeupdate', function() {
var duration = myVideo.duration;
if (duration > 0) {
document.getElementById('progress-amount').style.width = ((myVideo.currentTime / duration) * 100) + "%";
}
});
}
.buffered {
height: 20px;
position: relative;
background: #555;
width: 300px;
}
#buffered-amount {
display: block;
height: 100%;
background-color: #777;
width: 0;
}
.progress {
margin-top: -20px;
height: 20px;
position: relative;
width: 300px;
}
#progress-amount {
display: block;
height: 100%;
background-color: #595;
width: 0;
}
<video id="my-video" controls preload="auto"><source src="https://media-dev.ozone.tech/media/045728df-7431-4548-8353-318357cc2643/video_preview-1655322764.5499873.mp4?Expires=1656287999&Signature=3RnkLu03JreuUZk9bICqqC5IwGiq~tWpBCaUSfyGb9W9VLPfw6Na4zh~tDTxxDjIirhocj7es2T0ONm0L6XsuFxsCx2T9-CANok014Kt6ddHEaUmuOi5uztEWyXpLmI3ussq4dc5lW2Xw5WH6uV-5Z8fIlIQehMxQK-XQ6RpdHhWBQLsmfPBqSSPnDk6KH5fkK-xCwQmxUwAN1nRVH8H6p~43~E6MZa7gSS~i1717~FlHto3depk~AvREjm59T1rNBvaZeb6ZI-pnYAf52wwQs3pWXln7PCtiIOYQCxE10l4nkOvJ--KGmPA0jOeSuv0dCRUi3QLZD5JxsJgBVM4sA__&Key-Pair-Id=K16V0JZ9ZAOTC6" type="video/mp4"></video>
<div class="buffered">
<span id="buffered-amount"></span>
</div>
<div class="progress">
<span id="progress-amount"></span>
</div>
问题
有人可以解释为什么会发生这种情况以及如何防止它吗?似乎这可能是一个错误,但由于所有浏览器都在这样做,我想知道这是否是我的问题;也许我们编码视频的方式?
最佳答案
当我们引用 the specification on TimeRanges我们找到以下定义。
When a TimeRanges object is said to be a normalized TimeRanges object, the ranges it represents must obey the following criteria:
- The start of a range must be greater than the end of all earlier ranges.
- The start of a range must be less than or equal to the end of that same range.
In other words, the ranges in such an object are ordered, don't overlap, and don't touch (adjacent ranges are folded into one bigger range). A range can be empty (referencing just a single moment in time), e.g. to indicate that only one frame is currently buffered in the case that the user agent has discarded the entire media resource except for the current frame, when a media element is paused.
Ranges in a TimeRanges object must be inclusive.
Thus, the end of a range would be equal to the start of a following adjacent (touching but not overlapping) range. Similarly, a range covering a whole timeline anchored at zero would have a start equal to zero and an end equal to the duration of the timeline.
如果我要解释的话,我会想象只有当最小的 TimeRange(索引 0)的结尾等于持续时间时,才能实现 100% 的缓冲,即使在结尾处可能会保留多个范围,情况也并非如此。这与 the Mozilla documentation 相矛盾。 ,这么多的健全性检查。
基本上我们唯一需要推断的是缓冲的进度,安慰自己没有任何保证,甚至提到缓冲意味着已经下载、存储和随时可用的帧(不需要再次获取)。事实上,情况正好相反,存在“范围可以为空(仅引用单个时刻)”的可能性。
由于任何使用的唯一缓冲时间范围总是以当前时间为基础的 future 内容,这可能不一定是最小范围。
基于演绎推理,我们可以安全地假设:
或者用其他更有说服力的话:
function bufferedTotal(buffered, currentTime) {
let total = currentTime;
for (i = 0; i < buffered.length; i++)
if (buffered.end(i) > currentTime)
if (buffered.start(i) < currentTime)
total += buffered.end(i) - currentTime;
else
total += buffered.end(i) - buffered.start(i);
return total;
}
我们所有的鸭子都整齐地排成一排,这可能只是被认为完成了。window.onload = function() {
function bufferedTotal(buffered, currentTime) {
let total = currentTime;
for (i = 0; i < buffered.length; i++)
if (buffered.end(i) > currentTime)
if (buffered.start(i) < currentTime)
total += buffered.end(i) - currentTime;
else
total += buffered.end(i) - buffered.start(i);
return total;
}
var myVideo = document.getElementById('my-video');
myVideo.addEventListener('progress', function() {
var bufferedEnd = bufferedTotal(myVideo.buffered, myVideo.currentTime);
var duration = myVideo.duration;
if (duration > 0) {
document.getElementById('buffered-amount').style.width = ((bufferedEnd / duration) * 100) + "%";
}
});
myVideo.addEventListener('timeupdate', function() {
var duration = myVideo.duration;
if (duration > 0) {
document.getElementById('progress-amount').style.width = ((myVideo.currentTime / duration) * 100) + "%";
}
});
}
.buffered {
height: 20px;
position: relative;
background: #555;
width: 300px;
}
#buffered-amount {
display: block;
height: 100%;
background-color: #777;
width: 0;
}
.progress {
margin-top: -20px;
height: 20px;
position: relative;
width: 300px;
}
#progress-amount {
display: block;
height: 100%;
background-color: #595;
width: 0;
}
<video id="my-video" controls preload="auto"><source src="https://media-dev.ozone.tech/media/045728df-7431-4548-8353-318357cc2643/video_preview-1655322764.5499873.mp4?Expires=1656287999&Signature=3RnkLu03JreuUZk9bICqqC5IwGiq~tWpBCaUSfyGb9W9VLPfw6Na4zh~tDTxxDjIirhocj7es2T0ONm0L6XsuFxsCx2T9-CANok014Kt6ddHEaUmuOi5uztEWyXpLmI3ussq4dc5lW2Xw5WH6uV-5Z8fIlIQehMxQK-XQ6RpdHhWBQLsmfPBqSSPnDk6KH5fkK-xCwQmxUwAN1nRVH8H6p~43~E6MZa7gSS~i1717~FlHto3depk~AvREjm59T1rNBvaZeb6ZI-pnYAf52wwQs3pWXln7PCtiIOYQCxE10l4nkOvJ--KGmPA0jOeSuv0dCRUi3QLZD5JxsJgBVM4sA__&Key-Pair-Id=K16V0JZ9ZAOTC6" type="video/mp4"></video>
<div class="buffered">
<span id="buffered-amount"></span>
</div>
<div class="progress">
<span id="progress-amount"></span>
</div>
关于javascript - 浏览器发送已缓冲视频数据的请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72624500/