Merge pull request #302 from dhd2333/main

修复iOS端视频观看问题,添加视频进度条可拉动功能
This commit is contained in:
叁月柒
2025-08-29 14:42:27 +08:00
committed by GitHub
2 changed files with 68 additions and 25 deletions

View File

@@ -175,7 +175,9 @@ async function handleTelegramChunkedFile(context, imgRecord, encodedFileName, fi
const headers = new Headers();
setCommonHeaders(headers, encodedFileName, fileType, Referer, url);
headers.set('Content-Length', totalSize.toString());
headers.append('Vary', 'Range');
// 添加ETag支持
const etag = `"${metadata.TimeStamp || Date.now()}-${totalSize}"`;
headers.set('ETag', etag);
@@ -268,20 +270,27 @@ async function handleTelegramChunkedFile(context, imgRecord, encodedFileName, fi
}
});
// 设置Range相关头部
if (isRangeRequest) {
setRangeHeaders(headers, rangeStart, rangeEnd, totalSize);
return new Response(stream, {
status: 206, // Partial Content
headers,
});
} else {
return new Response(stream, {
status: 200,
headers,
});
}
// 设置Range相关头部
if (isRangeRequest) {
setRangeHeaders(headers, rangeStart, rangeEnd, totalSize);
// 明确告诉浏览器/CF支持分段请求
headers.set('Accept-Ranges', 'bytes');
return new Response(stream, {
status: 206, // Partial Content
headers,
});
} else {
// 关键:避免首个 200 整段被缓存,导致后续 Range 请求直接命中 200
headers.set('Cache-Control', 'no-store'); // 或 'max-age=0, must-revalidate'
return new Response(stream, {
status: 200,
headers,
});
}
} catch (error) {
return new Response(`Error: Failed to reconstruct chunked file - ${error.message}`, { status: 500 });

View File

@@ -35,6 +35,8 @@ export function setCommonHeaders(headers, encodedFileName, fileType, Referer, ur
headers.set('Content-Disposition', `inline; filename="${encodedFileName}"; filename*=UTF-8''${encodedFileName}`);
headers.set('Access-Control-Allow-Origin', '*');
headers.set('Accept-Ranges', 'bytes');
headers.append('Vary', 'Range');
if (fileType) {
headers.set('Content-Type', fileType);
@@ -81,25 +83,57 @@ export async function getFileContent(request, targetUrl, max_retries = 2) {
let retries = 0;
while (retries <= max_retries) {
try {
const response = await fetch(targetUrl, {
method: request.method,
headers: request.headers,
body: request.body,
// 复制请求头,确保 Range / If-None-Match 等关键头被透传
const fwdHeaders = new Headers(request.headers);
// 显式兜底:有些运行时需要手动 set 一下
const range = request.headers.get("Range");
if (range) fwdHeaders.set("Range", range);
// 只允许 GET/HEAD 转发
const method = request.method === "HEAD" ? "HEAD" : "GET";
const upstreamReq = new Request(targetUrl, {
method,
headers: fwdHeaders,
redirect: "follow",
});
if (response.ok || response.status === 304) {
return response;
} else if (response.status === 404) {
return new Response('Error: Image Not Found', { status: 404 });
const upstreamRes = await fetch(upstreamReq);
if (upstreamRes.ok || upstreamRes.status === 304) {
const headers = new Headers(upstreamRes.headers);
// 关键:让缓存区分是否带 Range
headers.append("Vary", "Range");
// 如果是 Range 请求但上游仍返回 200这里兜底改成 206
if (range && upstreamRes.status === 200) {
headers.set("Accept-Ranges", "bytes");
return new Response(upstreamRes.body, {
status: 206,
headers,
});
}
return new Response(upstreamRes.body, {
status: upstreamRes.status,
statusText: upstreamRes.statusText,
headers,
});
} else if (upstreamRes.status === 404) {
return new Response("Error: Image Not Found", { status: 404 });
} else {
retries++;
}
} catch (error) {
} catch (_err) {
retries++;
}
}
return null;
}
export function isTgChannel(imgRecord) {
return imgRecord.metadata?.Channel === 'Telegram' || imgRecord.metadata?.Channel === 'TelegramNew';
}
@@ -208,4 +242,4 @@ export async function returnWhiteListImg(url) {
},
});
}
}
}