fix(onebot): route oversized videos to the file path up front (#145)

A video larger than MAX_VIDEO_SIZE (~100 MB, QQ's video-resource cap)
uploads "successfully" — the server accepts the Highway bytes — but the
receiver sees 视频已过期 because no valid video resource is ever produced.

The existing large-video → file fallback only fired from the send catch
block, i.e. when the upload threw. An oversized upload doesn't throw, so
the fallback never triggered. Add a proactive split before the send: any
video whose source size is known to exceed MAX_VIDEO_SIZE is re-routed to
the file pipeline up front (mirrored for private and group sends). Smaller
videos (verified up to ~49 MB) are unaffected and still send as videos.

This pairs with the c2c-file fix (f8caa92): the re-routed video now rides
the now-working offline-file path and downloads correctly.
This commit is contained in:
DrSmoothl
2026-06-30 01:24:00 +08:00
parent f8caa92333
commit 547640bbfd
@@ -583,6 +583,19 @@ export async function sendPrivateMessage(
let allFileElements = elements.filter(e => e.type === 'file');
let nonFileElements = elements.filter(e => e.type !== 'file');
// [#145] A video above QQ's ~100 MB video-resource cap (MAX_VIDEO_SIZE)
// uploads "successfully" but renders as 视频已过期 on the receiver — the
// server accepts the bytes yet never produces a valid video resource. The
// on-error fallback below can't catch it (the oversized upload doesn't
// throw), so route known-oversized videos to the file path up front.
{
const pre = splitVideoFileFallback(nonFileElements, false);
if (pre.fileEls.length > 0) {
allFileElements = [...allFileElements, ...pre.fileEls];
nonFileElements = pre.remaining;
}
}
let lastReceipt: Awaited<ReturnType<typeof ref.bridge.apis.message.sendPrivate>> | undefined;
if (nonFileElements.length > 0) {
try {
@@ -690,6 +703,16 @@ export async function sendGroupMessage(
let allFileElements = elements.filter(e => e.type === 'file');
let nonFileElements = elements.filter(e => e.type !== 'file');
// [#145] Route known-oversized videos (> MAX_VIDEO_SIZE) to the file path
// up front — they upload as a video without error but render expired.
{
const pre = splitVideoFileFallback(nonFileElements, false);
if (pre.fileEls.length > 0) {
allFileElements = [...allFileElements, ...pre.fileEls];
nonFileElements = pre.remaining;
}
}
let lastReceipt: Awaited<ReturnType<typeof ref.bridge.apis.message.sendGroup>> | undefined;
if (nonFileElements.length > 0) {
try {