如何在Node.js中通过GramJS流式下载Telegram大视频
GramJS大视频流式下载正确实现方案
你的核心问题是错误添加了thumbSize参数,导致Telegram返回的是视频缩略图而非完整视频流,所以保存为MP4会损坏,改成JPG能打开缩略图。以下是修正后的实现方案:
修正后的代码
// const message = event.message; (来自client.addEventHandler的事件参数) try { await client.sendMessage(message.chatId, { message: "正在下载视频..." }); // 视频在Telegram中以Document类型存储,从media.document提取文件信息 const document = message.media.document; const writeStream = fs.createWriteStream("./myPath.mp4", { flags: "w" }); try { // 构造正确的文件位置,移除thumbSize参数以获取完整视频 const fileLocation = new Api.InputDocumentFileLocation({ id: document.id, accessHash: document.accessHash, fileReference: document.fileReference }); // 流式下载,每次请求2MB数据块 for await (const chunk of client.iterDownload({ file: fileLocation, requestSize: 2 * 1024 * 1024 })) { console.log("已下载数据块大小:", chunk.length); const canWrite = writeStream.write(chunk); // 处理流背压,等待写入缓冲区空闲 if (!canWrite) { await new Promise(resolve => writeStream.once("drain", resolve)); } } await client.sendMessage(message.chatId, { message: "视频下载完成!" }); } catch (error) { console.error("下载错误:", error); await client.sendMessage(message.chatId, { message: `下载失败:${error.message}` }); } finally { // 确保写入流正确关闭 writeStream.end(); } } catch (outerError) { console.error("意外错误:", outerError); }
关键说明
移除
thumbSize参数
这个参数是专门用于获取文档的缩略图,保留它会让Telegram返回缩略图二进制数据,而非完整的视频流,这就是你保存的MP4文件损坏的根本原因。正确获取视频文档对象
聊天中的视频属于Telegram的Document媒体类型,必须从message.media.document中提取文件ID、访问哈希等核心信息,部分版本的GramJS没有message.video这个快捷属性,直接使用message.media.document更可靠。流式写入的背压处理
通过监听drain事件等待写入缓冲区空闲,避免因写入速度跟不上下载速度导致的数据丢失或内存占用过高,这也是流式处理大文件的关键。
其他Location类型报错原因
Api.InputFileLocation:仅适用于临时上传到Telegram服务器的文件,不支持下载聊天中的视频文档,因此会返回LOCATION_INVALID。Api.InputPhotoFileLocation:专门用于照片类型媒体,视频属于Document类型,所以会触发FILE_REFERENCE_EXPIRED或类型不匹配的错误。
内容的提问来源于stack exchange,提问作者winner_vth
相关产品推荐
相关产品推荐

