|
|
@@ -92,89 +92,6 @@ const maxRetries = 3;
|
|
|
const videoContainer = ref<HTMLDivElement>();
|
|
|
const player = ref<any>(null);
|
|
|
|
|
|
-// 保存原始的 XMLHttpRequest.open 和 setRequestHeader 方法
|
|
|
-let originalXHROpen: any = null;
|
|
|
-let originalXHRSetRequestHeader: any = null;
|
|
|
-let originalFetch: any = null;
|
|
|
-let xhrInterceptorActive = false;
|
|
|
-
|
|
|
-// 设置 XMLHttpRequest 和 Fetch 拦截器以移除 Range 请求头
|
|
|
-const setupXHRInterceptor = (): void => {
|
|
|
- if (xhrInterceptorActive) return;
|
|
|
-
|
|
|
- // 保存原始方法
|
|
|
- originalXHROpen = XMLHttpRequest.prototype.open;
|
|
|
- originalXHRSetRequestHeader = XMLHttpRequest.prototype.setRequestHeader;
|
|
|
- originalFetch = window.fetch;
|
|
|
-
|
|
|
- // 拦截 XMLHttpRequest.open 方法
|
|
|
- XMLHttpRequest.prototype.open = function (
|
|
|
- method: string,
|
|
|
- url: string | URL,
|
|
|
- ...rest: any[]
|
|
|
- ) {
|
|
|
- // 保存 URL 以便后续检查
|
|
|
- (this as any)._url = url.toString();
|
|
|
- return originalXHROpen.apply(this, [method, url, ...rest]);
|
|
|
- };
|
|
|
-
|
|
|
- // 拦截 XMLHttpRequest.setRequestHeader 方法
|
|
|
- XMLHttpRequest.prototype.setRequestHeader = function (
|
|
|
- header: string,
|
|
|
- value: string
|
|
|
- ) {
|
|
|
- // 如果是 .m3u8 文件的 Range 请求头,则跳过
|
|
|
- const url = (this as any)._url || "";
|
|
|
- if (url && /\.m3u8(\?|$)/i.test(url) && header.toLowerCase() === "range") {
|
|
|
- return; // 不设置 Range 请求头
|
|
|
- }
|
|
|
- return originalXHRSetRequestHeader.apply(this, [header, value]);
|
|
|
- };
|
|
|
-
|
|
|
- // 拦截 fetch 方法
|
|
|
- window.fetch = function (
|
|
|
- input: RequestInfo | URL,
|
|
|
- init?: RequestInit
|
|
|
- ): Promise<Response> {
|
|
|
- const url = typeof input === "string" ? input : input instanceof URL ? input.toString() : input.url;
|
|
|
-
|
|
|
- // 如果是 .m3u8 文件,移除 Range 请求头
|
|
|
- if (url && /\.m3u8(\?|$)/i.test(url)) {
|
|
|
- const modifiedInit = { ...init };
|
|
|
- if (modifiedInit.headers) {
|
|
|
- const headers = new Headers(modifiedInit.headers);
|
|
|
- headers.delete("Range");
|
|
|
- headers.delete("range");
|
|
|
- modifiedInit.headers = headers;
|
|
|
- } else {
|
|
|
- modifiedInit.headers = new Headers();
|
|
|
- }
|
|
|
- return originalFetch.apply(this, [input, modifiedInit]);
|
|
|
- }
|
|
|
-
|
|
|
- return originalFetch.apply(this, [input, init]);
|
|
|
- };
|
|
|
-
|
|
|
- xhrInterceptorActive = true;
|
|
|
-};
|
|
|
-
|
|
|
-// 恢复原始的 XMLHttpRequest 和 Fetch 方法
|
|
|
-const restoreXHRInterceptor = (): void => {
|
|
|
- if (!xhrInterceptorActive) return;
|
|
|
-
|
|
|
- if (originalXHROpen) {
|
|
|
- XMLHttpRequest.prototype.open = originalXHROpen;
|
|
|
- }
|
|
|
- if (originalXHRSetRequestHeader) {
|
|
|
- XMLHttpRequest.prototype.setRequestHeader = originalXHRSetRequestHeader;
|
|
|
- }
|
|
|
- if (originalFetch) {
|
|
|
- window.fetch = originalFetch;
|
|
|
- }
|
|
|
-
|
|
|
- xhrInterceptorActive = false;
|
|
|
-};
|
|
|
-
|
|
|
// 计算属性
|
|
|
const hasVideoSource = computed(
|
|
|
() => !!props.m3u8Url && props.m3u8Url.trim() !== ""
|
|
|
@@ -390,8 +307,7 @@ const initVideoJSPlayer = async (): Promise<void> => {
|
|
|
poster: posterUrl, // 使用处理后的封面URL
|
|
|
};
|
|
|
|
|
|
- // 设置 XMLHttpRequest 拦截器以禁用 .m3u8 文件的 Range 请求
|
|
|
- setupXHRInterceptor();
|
|
|
+ // 注意:拦截器已在 api.ts 中全局设置,无需在此处设置
|
|
|
|
|
|
try {
|
|
|
// 注册快进按钮组件
|
|
|
@@ -569,8 +485,7 @@ const destroyPlayer = (): void => {
|
|
|
player.value.dispose();
|
|
|
player.value = null;
|
|
|
}
|
|
|
- // 恢复 XMLHttpRequest 拦截器
|
|
|
- restoreXHRInterceptor();
|
|
|
+ // 注意:拦截器在 api.ts 中全局管理,无需在此处恢复
|
|
|
};
|
|
|
|
|
|
// 重试功能
|