|
@@ -2,6 +2,7 @@ import {
|
|
|
defineComponent,
|
|
|
nextTick,
|
|
|
onMounted,
|
|
|
+ onUnmounted,
|
|
|
reactive,
|
|
|
toRefs,
|
|
|
watch
|
|
@@ -63,6 +64,7 @@ export default defineComponent({
|
|
|
const { item, isEmtry } = toRefs(props);
|
|
|
const data = reactive({
|
|
|
speedInKbps: '',
|
|
|
+ isOnline: true,
|
|
|
timer: null as any,
|
|
|
currentTime: 0,
|
|
|
duration: 0,
|
|
@@ -271,96 +273,117 @@ export default defineComponent({
|
|
|
}, BUFFER_CHECK_INTERVAL);
|
|
|
}
|
|
|
|
|
|
- element.addEventListener('progress', () => {
|
|
|
- const currentTime = Date.now();
|
|
|
- const buffered = element.buffered;
|
|
|
- let currentBytesLoaded = 0;
|
|
|
-
|
|
|
- if (buffered.length > 0) {
|
|
|
- for (let i = 0; i < buffered.length; i++) {
|
|
|
- currentBytesLoaded += buffered.end(i) - buffered.start(i);
|
|
|
- }
|
|
|
- currentBytesLoaded *= element.duration * element.seekable.end(0); // 更精确地近似字节加载量
|
|
|
+ function resetBuffterCatch() {
|
|
|
+ // 如果有缓存检测计时器,则清除它
|
|
|
+ if (bufferTimeout) {
|
|
|
+ clearTimeout(bufferTimeout);
|
|
|
}
|
|
|
+ // 标记为正在缓存
|
|
|
+ isBuffering = true;
|
|
|
|
|
|
- console.log('progress', currentBytesLoaded > previousBytesLoaded);
|
|
|
- if (currentBytesLoaded > previousBytesLoaded) {
|
|
|
- const timeDiff = (currentTime - previousTime) / 1000; // 时间差转换为秒
|
|
|
- const bytesDiff = currentBytesLoaded - previousBytesLoaded; // 字节差值
|
|
|
- const speed = bytesDiff / timeDiff; // 字节每秒
|
|
|
-
|
|
|
- console.log(timeDiff, bytesDiff, speed);
|
|
|
-
|
|
|
- if (!element.paused) {
|
|
|
- const kbps = speed / 1024;
|
|
|
- const speedInKbps = kbps.toFixed(2); // 转换为千字节每秒并保留两位小数
|
|
|
- if (kbps > 1024) {
|
|
|
- data.speedInKbps = `${Number((kbps / 1024).toFixed(2))} M/s`;
|
|
|
- } else {
|
|
|
- data.speedInKbps = `${Number(speedInKbps)} KB/s`;
|
|
|
+ buffterCatch();
|
|
|
+ }
|
|
|
+
|
|
|
+ element.addEventListener('loadedmetadata', () => {
|
|
|
+ // 获取视频总时长
|
|
|
+ const duration = element.duration;
|
|
|
+
|
|
|
+ element.addEventListener('progress', () => {
|
|
|
+ const currentTime = Date.now();
|
|
|
+ const buffered = element.buffered;
|
|
|
+ let currentBytesLoaded = 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);
|
|
|
}
|
|
|
+ currentBytesLoaded *= element.duration * element.seekable.end(0); // 更精确地近似字节加载量
|
|
|
}
|
|
|
|
|
|
- previousBytesLoaded = currentBytesLoaded;
|
|
|
- previousTime = currentTime;
|
|
|
- }
|
|
|
+ // 计算未缓存的时间段
|
|
|
+ const uncachedDuration = duration - cachedDuration;
|
|
|
+ // console.log(uncachedDuration, duration, cachedDuration, 'duration');
|
|
|
+ // 如果存在未缓存的时间段,可以根据具体情况做出相应处理
|
|
|
+ if (uncachedDuration > 0) {
|
|
|
+ if (currentBytesLoaded > previousBytesLoaded && data.isOnline) {
|
|
|
+ const timeDiff = (currentTime - previousTime) / 1000; // 时间差转换为秒
|
|
|
+ const bytesDiff = currentBytesLoaded - previousBytesLoaded; // 字节差值
|
|
|
+ const speed = bytesDiff / timeDiff; // 字节每秒
|
|
|
+
|
|
|
+ console.log(timeDiff, bytesDiff, speed);
|
|
|
+
|
|
|
+ if (!element.paused) {
|
|
|
+ const kbps = speed / 1024;
|
|
|
+ const speedInKbps = kbps.toFixed(2); // 转换为千字节每秒并保留两位小数
|
|
|
+ if (kbps > 1024) {
|
|
|
+ data.speedInKbps = `${Number((kbps / 1024).toFixed(2))} M/s`;
|
|
|
+ } else {
|
|
|
+ data.speedInKbps = `${Number(speedInKbps)} KB/s`;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- if (!element.paused) {
|
|
|
- // 如果1秒钟没有返回就重置数据
|
|
|
- clearTimeout(timer);
|
|
|
- resetDownloadSpeed();
|
|
|
- }
|
|
|
+ previousBytesLoaded = currentBytesLoaded;
|
|
|
+ previousTime = currentTime;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!element.paused && data.isOnline) {
|
|
|
+ // 如果1秒钟没有返回就重置数据
|
|
|
+ clearTimeout(timer);
|
|
|
+ resetDownloadSpeed();
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!isWaiting) {
|
|
|
+ resetBuffterCatch();
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ resetBuffterCatch();
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ element.addEventListener('waiting', () => {
|
|
|
+ console.log('waiting');
|
|
|
+ isWaiting = true;
|
|
|
+ if (!element.paused && data.isOnline) {
|
|
|
+ // 如果1秒钟没有返回就重置数据
|
|
|
+ clearTimeout(timer);
|
|
|
+ resetDownloadSpeed();
|
|
|
+ }
|
|
|
|
|
|
- if (!isWaiting) {
|
|
|
// 如果有缓存检测计时器,则清除它
|
|
|
if (bufferTimeout) {
|
|
|
clearTimeout(bufferTimeout);
|
|
|
}
|
|
|
- // 标记为正在缓存
|
|
|
- isBuffering = true;
|
|
|
- buffterCatch();
|
|
|
- }
|
|
|
- });
|
|
|
-
|
|
|
- element.addEventListener('waiting', () => {
|
|
|
- console.log('waiting');
|
|
|
- isWaiting = true;
|
|
|
+ });
|
|
|
+ element.addEventListener('canplay', () => {
|
|
|
+ console.log('canplay');
|
|
|
+ isWaiting = false;
|
|
|
+ resetBuffterCatch();
|
|
|
+ });
|
|
|
|
|
|
- if (!element.paused) {
|
|
|
- // 如果1秒钟没有返回就重置数据
|
|
|
+ element.addEventListener('pause', () => {
|
|
|
clearTimeout(timer);
|
|
|
- resetDownloadSpeed();
|
|
|
- }
|
|
|
-
|
|
|
- // 如果有缓存检测计时器,则清除它
|
|
|
- if (bufferTimeout) {
|
|
|
- clearTimeout(bufferTimeout);
|
|
|
- }
|
|
|
- });
|
|
|
- element.addEventListener('canplay', () => {
|
|
|
- console.log('canplay');
|
|
|
- isWaiting = false;
|
|
|
- // 如果有缓存检测计时器,则清除它
|
|
|
- if (bufferTimeout) {
|
|
|
- clearTimeout(bufferTimeout);
|
|
|
- }
|
|
|
- // 标记为正在缓存
|
|
|
- isBuffering = true;
|
|
|
- buffterCatch();
|
|
|
+ // 如果有缓存检测计时器,则清除它
|
|
|
+ if (bufferTimeout) {
|
|
|
+ clearTimeout(bufferTimeout);
|
|
|
+ }
|
|
|
+ data.speedInKbps = '';
|
|
|
+ });
|
|
|
+ // element.addEventListener('error', () => {
|
|
|
+ // element.pause();
|
|
|
+ // videoItem.value.pause();
|
|
|
+ // });
|
|
|
});
|
|
|
+ };
|
|
|
|
|
|
- element.addEventListener('pause', () => {
|
|
|
- clearTimeout(timer);
|
|
|
- // 如果有缓存检测计时器,则清除它
|
|
|
- if (bufferTimeout) {
|
|
|
- clearTimeout(bufferTimeout);
|
|
|
- }
|
|
|
- data.speedInKbps = '';
|
|
|
- });
|
|
|
- // element.addEventListener('error', () => {
|
|
|
- // element.pause();
|
|
|
- // videoItem.value.pause();
|
|
|
- // });
|
|
|
+ const onChangeOnlineStatus = (val: any) => {
|
|
|
+ if (val.type === 'online') {
|
|
|
+ data.isOnline = true;
|
|
|
+ } else if (val.type === 'offline') {
|
|
|
+ data.isOnline = false;
|
|
|
+ }
|
|
|
};
|
|
|
|
|
|
onMounted(() => {
|
|
@@ -378,6 +401,13 @@ export default defineComponent({
|
|
|
nextTick(() => {
|
|
|
calculateSpeed(videoRef.value);
|
|
|
});
|
|
|
+ window.addEventListener('online', onChangeOnlineStatus);
|
|
|
+ window.addEventListener('offline', onChangeOnlineStatus);
|
|
|
+ });
|
|
|
+
|
|
|
+ onUnmounted(() => {
|
|
|
+ window.removeEventListener('online', onChangeOnlineStatus);
|
|
|
+ window.removeEventListener('offline', onChangeOnlineStatus);
|
|
|
});
|
|
|
|
|
|
const pause = () => {
|