You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 09:07:59