Deno使用ReadableStream流式传输视频时的异常问题求助
Deno使用ReadableStream流式传输视频时的异常问题求助
我最近在Deno里尝试用ReadableStream实现视频的流式传输,这个API本来是和浏览器端的实现兼容的,但官方文档里的示例都是基于日期定时器和文本的,没有视频相关的参考。于是我在网上找了一段比较旧的代码来改,代码逻辑是把视频分成100个16KB的小区块,组合成约1.5MB的 chunk 来分段返回给客户端。
先贴一下我用的代码:
const { size } = await Deno.stat("video.mp4"); const range = req.headers.get("range"); if (!range) { throw new Error("no range"); } console.log("req range=", range) const num_blocks = 100; const block_size = 16_384; const chunk_size = block_size * num_blocks; const start_index = Number(range.replace(/\D/g, "")?.trim()); const end_index = Math.min(start_index + chunk_size, size); const file = await Deno.open("video.mp4", { read: true }); if (start_index > 0) { await file.seek(start_index, Deno.SeekMode.Start); } let read_blocks = num_blocks; let read_bytes = 0; console.info("calc range=", start_index, end_index, size) const stream = new ReadableStream({ start(){ console.log("start") }, async pull(controller) { const chunk = new Uint8Array(block_size); try { const read = await file.read(chunk); console.log("read block bytes=", read) if (read !== null && read > 0) { controller.enqueue(chunk.subarray(0, read)); read_bytes += read; } read_blocks--; if (read_blocks === 0) { log.info("no more blocks", read_bytes) controller.close(); file.close(); } } catch (e) { controller.error(e); console.log(e) file.close(); } }, cancel(reason){ console.log("canceled=", reason) file.close(); } }); return new Response(stream, { status: 206, headers: { "Content-Range": `bytes ${start_index}-${end_index}/${size}`, "Accept-Ranges": "bytes", "Content-Length": `${end_index - start_index}`, "Content-Type": "video/mp4", }, });
现在遇到的问题是:
- 在Firefox里视频看起来能正常播放,但Deno控制台偶尔会抛出错误:
TypeError: The stream controller cannot close or enqueue - 在Chrome里视频只能播放大约12秒(原视频总长30秒),点击重新播放会从头开始,控制台也偶尔会出现和Firefox一样的错误
想请教各位,这段代码哪里有问题?怎么修改才能解决这些异常,让视频在Chrome和Firefox里都能正常流式播放?
备注:内容来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

