|
@@ -290,181 +290,192 @@ export default defineComponent({
|
|
|
return res;
|
|
|
};
|
|
|
|
|
|
- element.addEventListener('loadedmetadata', () => {
|
|
|
- // 获取视频总时长
|
|
|
+ // 获取视频总时长
|
|
|
+ let noData = false;
|
|
|
+
|
|
|
+ const onProgress = () => {
|
|
|
const duration = element.duration;
|
|
|
- let noData = false;
|
|
|
-
|
|
|
- element.addEventListener('progress', () => {
|
|
|
- const currentTime = Date.now();
|
|
|
- const buffered = element.buffered;
|
|
|
- let currentBytesLoaded = 0;
|
|
|
- let currentLength = 0;
|
|
|
-
|
|
|
- // 计算视频已缓存的总时长
|
|
|
- let cachedDuration = 0;
|
|
|
- if (buffered.length > 0) {
|
|
|
- for (let i = 0; i < buffered.length; i++) {
|
|
|
- currentBytesLoaded += buffered.end(i) - buffered.start(i);
|
|
|
+ const currentTime = Date.now();
|
|
|
+ const buffered = element.buffered;
|
|
|
+ let currentBytesLoaded = 0;
|
|
|
+ let currentLength = 0;
|
|
|
+
|
|
|
+ // 计算视频已缓存的总时长
|
|
|
+ let cachedDuration = 0;
|
|
|
+ if (buffered.length > 0) {
|
|
|
+ for (let i = 0; i < buffered.length; i++) {
|
|
|
+ currentBytesLoaded += buffered.end(i) - buffered.start(i);
|
|
|
+ cachedDuration += buffered.end(i) - buffered.start(i);
|
|
|
+ // console.log(buffered.end(i), buffered.start(i), 'bufferd');
|
|
|
+ buffterCatchArray = formatEffectiveTime([
|
|
|
+ ...buffterCatchArray,
|
|
|
+ [buffered.start(i), buffered.end(i)]
|
|
|
+ ]);
|
|
|
+ }
|
|
|
+ for (let i = 0; i < buffered.length; i++) {
|
|
|
+ // 寻找当前时间之后最近的点
|
|
|
+ if (buffered.start(buffered.length - 1 - i) < element.currentTime) {
|
|
|
cachedDuration += buffered.end(i) - buffered.start(i);
|
|
|
- // console.log(buffered.end(i), buffered.start(i), 'bufferd');
|
|
|
- buffterCatchArray = formatEffectiveTime([
|
|
|
- ...buffterCatchArray,
|
|
|
- [buffered.start(i), buffered.end(i)]
|
|
|
- ]);
|
|
|
- }
|
|
|
- for (let i = 0; i < buffered.length; i++) {
|
|
|
- // 寻找当前时间之后最近的点
|
|
|
- if (
|
|
|
- buffered.start(buffered.length - 1 - i) < element.currentTime
|
|
|
- ) {
|
|
|
- cachedDuration += buffered.end(i) - buffered.start(i);
|
|
|
- currentLength =
|
|
|
- (buffered.end(buffered.length - 1 - i) / duration) * 100;
|
|
|
- break;
|
|
|
- }
|
|
|
+ currentLength =
|
|
|
+ (buffered.end(buffered.length - 1 - i) / duration) * 100;
|
|
|
+ break;
|
|
|
}
|
|
|
- currentBytesLoaded *= element.duration * element.seekable.end(0); // 更精确地近似字节加载量
|
|
|
}
|
|
|
+ currentBytesLoaded *= element.duration * element.seekable.end(0); // 更精确地近似字节加载量
|
|
|
+ }
|
|
|
|
|
|
- // 计算未缓存的时间段
|
|
|
- const uncachedDuration = duration - cachedDuration;
|
|
|
- let uncachedTime = true; // 没有缓存时间
|
|
|
- buffterCatchArray.forEach((item: any) => {
|
|
|
- if (element.currentTime >= item[0] && uncachedTime <= item[1]) {
|
|
|
- uncachedTime = false;
|
|
|
- }
|
|
|
- });
|
|
|
-
|
|
|
- if (duration) {
|
|
|
- const sliderDom: any = document.querySelector(
|
|
|
- '#' + videoSlider + ' .n-slider'
|
|
|
- );
|
|
|
- if (sliderDom) {
|
|
|
- sliderDom.style.setProperty(
|
|
|
- '--catch-width',
|
|
|
- uncachedDuration > 0 ? `${currentLength}%` : 'calc(100% + 17px)'
|
|
|
- );
|
|
|
- }
|
|
|
+ // 计算未缓存的时间段
|
|
|
+ const uncachedDuration = duration - cachedDuration;
|
|
|
+ let uncachedTime = true; // 没有缓存时间
|
|
|
+ buffterCatchArray.forEach((item: any) => {
|
|
|
+ if (element.currentTime >= item[0] && uncachedTime <= item[1]) {
|
|
|
+ uncachedTime = false;
|
|
|
+ }
|
|
|
+ });
|
|
|
|
|
|
- console.log(
|
|
|
- uncachedTime,
|
|
|
- duration,
|
|
|
- cachedDuration,
|
|
|
- 'duration',
|
|
|
- buffterCatchArray,
|
|
|
- element.currentTime,
|
|
|
- currentLength + '%',
|
|
|
- isWaiting,
|
|
|
- currentBytesLoaded <= previousBytesLoaded
|
|
|
+ if (duration) {
|
|
|
+ const sliderDom: any = document.querySelector(
|
|
|
+ '#' + videoSlider + ' .n-slider'
|
|
|
+ );
|
|
|
+ if (sliderDom) {
|
|
|
+ sliderDom.style.setProperty(
|
|
|
+ '--catch-width',
|
|
|
+ uncachedDuration > 0 ? `${currentLength}%` : 'calc(100% + 17px)'
|
|
|
);
|
|
|
}
|
|
|
|
|
|
- const isNoBuffer = currentBytesLoaded <= previousBytesLoaded;
|
|
|
- // 如果存在未缓存的时间段,可以根据具体情况做出相应处理
|
|
|
- if (uncachedDuration > 0) {
|
|
|
- // console.log(
|
|
|
- // 'progress',
|
|
|
- // currentBytesLoaded > previousBytesLoaded,
|
|
|
- // currentBytesLoaded,
|
|
|
- // previousBytesLoaded,
|
|
|
- // '------ 加载中'
|
|
|
- // );
|
|
|
- if (
|
|
|
- currentBytesLoaded > previousBytesLoaded &&
|
|
|
- videoFroms.isOnline
|
|
|
- ) {
|
|
|
- const timeDiff = (currentTime - previousTime) / 1000; // 时间差转换为秒
|
|
|
- const bytesDiff = currentBytesLoaded - previousBytesLoaded; // 字节差值
|
|
|
- const speed = bytesDiff / timeDiff; // 字节每秒
|
|
|
- // console.log(timeDiff, bytesDiff, speed);
|
|
|
- // console.log(element.paused, 'element.paused');
|
|
|
- if (!element.paused) {
|
|
|
- const kbps = speed / 1024;
|
|
|
- const speedInKbps = kbps.toFixed(2); // 转换为千字节每秒并保留两位小数
|
|
|
- if (kbps > 1024) {
|
|
|
- videoFroms.speedInKbps = `${Number(
|
|
|
- (kbps / 1024).toFixed(2)
|
|
|
- )} M/s`;
|
|
|
- } else {
|
|
|
- videoFroms.speedInKbps = `${Number(speedInKbps)} KB/s`;
|
|
|
- }
|
|
|
+ console.log(
|
|
|
+ uncachedTime,
|
|
|
+ duration,
|
|
|
+ cachedDuration,
|
|
|
+ 'duration',
|
|
|
+ buffterCatchArray,
|
|
|
+ element.currentTime,
|
|
|
+ currentLength + '%',
|
|
|
+ isWaiting,
|
|
|
+ currentBytesLoaded <= previousBytesLoaded
|
|
|
+ );
|
|
|
+ }
|
|
|
|
|
|
- // 如果1秒钟没有返回就重置数据
|
|
|
- clearTimeout(timer);
|
|
|
- resetDownloadSpeed();
|
|
|
+ const isNoBuffer = currentBytesLoaded <= previousBytesLoaded;
|
|
|
+ // 如果存在未缓存的时间段,可以根据具体情况做出相应处理
|
|
|
+ if (uncachedDuration > 0) {
|
|
|
+ // console.log(
|
|
|
+ // 'progress',
|
|
|
+ // currentBytesLoaded > previousBytesLoaded,
|
|
|
+ // currentBytesLoaded,
|
|
|
+ // previousBytesLoaded,
|
|
|
+ // '------ 加载中'
|
|
|
+ // );
|
|
|
+ if (currentBytesLoaded > previousBytesLoaded && videoFroms.isOnline) {
|
|
|
+ const timeDiff = (currentTime - previousTime) / 1000; // 时间差转换为秒
|
|
|
+ const bytesDiff = currentBytesLoaded - previousBytesLoaded; // 字节差值
|
|
|
+ const speed = bytesDiff / timeDiff; // 字节每秒
|
|
|
+ // console.log(timeDiff, bytesDiff, speed);
|
|
|
+ // console.log(element.paused, 'element.paused');
|
|
|
+ if (!element.paused) {
|
|
|
+ const kbps = speed / 1024;
|
|
|
+ const speedInKbps = kbps.toFixed(2); // 转换为千字节每秒并保留两位小数
|
|
|
+ if (kbps > 1024) {
|
|
|
+ videoFroms.speedInKbps = `${Number(
|
|
|
+ (kbps / 1024).toFixed(2)
|
|
|
+ )} M/s`;
|
|
|
+ } else {
|
|
|
+ videoFroms.speedInKbps = `${Number(speedInKbps)} KB/s`;
|
|
|
}
|
|
|
|
|
|
- previousBytesLoaded = currentBytesLoaded;
|
|
|
- previousTime = currentTime;
|
|
|
- noData = false;
|
|
|
- }
|
|
|
- if (isNoBuffer && !uncachedTime) {
|
|
|
// 如果1秒钟没有返回就重置数据
|
|
|
- if (!noData) {
|
|
|
- clearTimeout(timer);
|
|
|
- clearTimeout(bufferTimeout);
|
|
|
- setTimeout(() => {
|
|
|
- if (isBuffering) {
|
|
|
- // 如果计时器到达且isBuffering仍为true,则认为缓存停止
|
|
|
- console.log('停止缓存数据-。');
|
|
|
- isBuffering = false;
|
|
|
- videoFroms.speedInKbps = '';
|
|
|
- }
|
|
|
- }, 800);
|
|
|
- }
|
|
|
-
|
|
|
- noData = true;
|
|
|
- }
|
|
|
- if (element.paused || !videoFroms.isOnline) {
|
|
|
clearTimeout(timer);
|
|
|
- videoFroms.speedInKbps = '';
|
|
|
+ resetDownloadSpeed();
|
|
|
}
|
|
|
|
|
|
- if (!isWaiting) {
|
|
|
- resetBuffterCatch();
|
|
|
- }
|
|
|
- } else {
|
|
|
- clearTimeout(timer);
|
|
|
- buffterCatch(1000);
|
|
|
+ previousBytesLoaded = currentBytesLoaded;
|
|
|
+ previousTime = currentTime;
|
|
|
+ noData = false;
|
|
|
}
|
|
|
- });
|
|
|
- element.addEventListener('waiting', () => {
|
|
|
- console.log('waiting');
|
|
|
- isWaiting = true;
|
|
|
- let uncachedTime = true; // 没有缓存时间
|
|
|
- buffterCatchArray.forEach((item: any) => {
|
|
|
- if (element.currentTime >= item[0] && uncachedTime <= item[1]) {
|
|
|
- uncachedTime = false;
|
|
|
+ if (isNoBuffer && !uncachedTime) {
|
|
|
+ // 如果1秒钟没有返回就重置数据
|
|
|
+ if (!noData) {
|
|
|
+ clearTimeout(timer);
|
|
|
+ clearTimeout(bufferTimeout);
|
|
|
+ setTimeout(() => {
|
|
|
+ if (isBuffering) {
|
|
|
+ // 如果计时器到达且isBuffering仍为true,则认为缓存停止
|
|
|
+ console.log('停止缓存数据-。');
|
|
|
+ isBuffering = false;
|
|
|
+ videoFroms.speedInKbps = '';
|
|
|
+ }
|
|
|
+ }, 800);
|
|
|
}
|
|
|
- });
|
|
|
|
|
|
- if (!element.paused && videoFroms.isOnline && uncachedTime) {
|
|
|
- // 如果1秒钟没有返回就重置数据
|
|
|
+ noData = true;
|
|
|
+ }
|
|
|
+ if (element.paused || !videoFroms.isOnline) {
|
|
|
clearTimeout(timer);
|
|
|
- resetDownloadSpeed();
|
|
|
+ videoFroms.speedInKbps = '';
|
|
|
}
|
|
|
|
|
|
- // 如果有缓存检测计时器,则清除它
|
|
|
- if (bufferTimeout) {
|
|
|
- clearTimeout(bufferTimeout);
|
|
|
+ if (!isWaiting) {
|
|
|
+ resetBuffterCatch();
|
|
|
}
|
|
|
- });
|
|
|
- element.addEventListener('canplay', () => {
|
|
|
- console.log('canplay');
|
|
|
- isWaiting = false;
|
|
|
- resetBuffterCatch();
|
|
|
- });
|
|
|
-
|
|
|
- element.addEventListener('pause', () => {
|
|
|
+ } else {
|
|
|
clearTimeout(timer);
|
|
|
- // 如果有缓存检测计时器,则清除它
|
|
|
- if (bufferTimeout) {
|
|
|
- clearTimeout(bufferTimeout);
|
|
|
+ buffterCatch(1000);
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ const onWaiting = () => {
|
|
|
+ console.log('waiting');
|
|
|
+ isWaiting = true;
|
|
|
+ let uncachedTime = true; // 没有缓存时间
|
|
|
+ buffterCatchArray.forEach((item: any) => {
|
|
|
+ if (element.currentTime >= item[0] && uncachedTime <= item[1]) {
|
|
|
+ uncachedTime = false;
|
|
|
}
|
|
|
- videoFroms.speedInKbps = '';
|
|
|
});
|
|
|
- });
|
|
|
+
|
|
|
+ if (!element.paused && videoFroms.isOnline && uncachedTime) {
|
|
|
+ // 如果1秒钟没有返回就重置数据
|
|
|
+ clearTimeout(timer);
|
|
|
+ resetDownloadSpeed();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果有缓存检测计时器,则清除它
|
|
|
+ if (bufferTimeout) {
|
|
|
+ clearTimeout(bufferTimeout);
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ const onCanplay = () => {
|
|
|
+ console.log('canplay');
|
|
|
+ isWaiting = false;
|
|
|
+ resetBuffterCatch();
|
|
|
+ };
|
|
|
+
|
|
|
+ const onPause = () => {
|
|
|
+ clearTimeout(timer);
|
|
|
+ // 如果有缓存检测计时器,则清除它
|
|
|
+ if (bufferTimeout) {
|
|
|
+ clearTimeout(bufferTimeout);
|
|
|
+ }
|
|
|
+ videoFroms.speedInKbps = '';
|
|
|
+ };
|
|
|
+
|
|
|
+ element.removeEventListener('progress', onProgress);
|
|
|
+ element.removeEventListener('waiting', onWaiting);
|
|
|
+ element.removeEventListener('canplay', onCanplay);
|
|
|
+ element.removeEventListener('pause', onPause);
|
|
|
+ // if (type !== 'remove') {
|
|
|
+ element.addEventListener('progress', onProgress);
|
|
|
+ element.addEventListener('waiting', onWaiting);
|
|
|
+ element.addEventListener('canplay', onCanplay);
|
|
|
+ element.addEventListener('pause', onPause);
|
|
|
+ // } else {
|
|
|
+ // element.removeEventListener('progress', onProgress);
|
|
|
+ // element.removeEventListener('waiting', onWaiting);
|
|
|
+ // element.removeEventListener('canplay', onCanplay);
|
|
|
+ // element.removeEventListener('pause', onPause);
|
|
|
+ // }
|
|
|
};
|
|
|
|
|
|
const onChangeOnlineStatus = (val: any) => {
|
|
@@ -515,7 +526,6 @@ export default defineComponent({
|
|
|
watch(
|
|
|
() => props.item,
|
|
|
() => {
|
|
|
- // console.log(item.value, 'value----');
|
|
|
videoItem.value.pause();
|
|
|
videoItem.value.currentTime(0);
|
|
|
if (item.value?.id) {
|
|
@@ -525,6 +535,9 @@ export default defineComponent({
|
|
|
|
|
|
videoFroms.paused = true;
|
|
|
}
|
|
|
+ nextTick(() => {
|
|
|
+ calculateSpeed(videoRef.value);
|
|
|
+ });
|
|
|
}
|
|
|
);
|
|
|
watch(
|