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

Node.js 18生成视频Blob后客户端无法使用问题求助

Node.js服务端生成的Blob URL无法在客户端使用的问题解决

问题描述

我正在学习Node.js和Blob,尝试在Node.js中从视频文件创建Blob,并将其通过JSON发送至客户端,数据将在Next.js的GetStaticProps中获取。以下是我在Node.js服务端编写的代码:

const fileBuffer = fs.readFileSync(filePath); // Path is something like example.com/video.mp4
const blob = new Blob([fileBuffer], { type: 'video/mp4' });
blobUrl = URL.createObjectURL(blob); // Return blob:nodedata:c3b1baf2-fba8-404f-8d3c-a1184a3a6db2

代码返回的内容为:

blob:nodedata:c3b1baf2-fba8-404f-8d3c-a1184a3a6db2

但我无法在客户端使用该URL,<video src="blob:nodedat...">无法正常工作,肯定是哪里出错了?

问题根源

Node.js环境中的Blob是v18+版本新增的实现,和浏览器端的Blob属于完全独立的运行环境对象。服务端通过URL.createObjectURL生成的blob:nodedata:... URL仅在当前Node.js进程内部有效,客户端浏览器无法识别该协议的地址,自然无法加载对应的视频资源。

可行解决方案

方案1:直接使用静态资源路径(Next.js推荐)

如果视频文件放在Next.js项目的public目录下,直接在GetStaticProps中返回文件的相对路径,客户端直接用该路径作为video的src即可,Next.js会自动处理静态资源的托管和访问。

服务端(GetStaticProps)代码:

export async function getStaticProps() {
  // 假设视频文件在public/videos/example.mp4
  const videoPath = '/videos/example.mp4';
  return {
    props: { videoPath }
  };
}

客户端组件代码:

export default function VideoPage({ videoPath }) {
  return <video src={videoPath} controls />;
}

方案2:将二进制数据转为Base64传递

如果必须通过JSON传递视频数据,可以将服务端的文件Buffer转为Base64格式,客户端接收后再转回Blob并生成浏览器可用的Object URL。

服务端代码:

import fs from 'fs';

export async function getStaticProps() {
  const filePath = './public/videos/example.mp4';
  const fileBuffer = fs.readFileSync(filePath);
  // 转为Base64格式的data URL
  const base64Video = `data:video/mp4;base64,${fileBuffer.toString('base64')}`;
  return {
    props: { base64Video }
  };
}

客户端组件代码:

import { useRef, useEffect } from 'react';

export default function VideoPage({ base64Video }) {
  const videoRef = useRef(null);

  useEffect(() => {
    if (!base64Video || !videoRef.current) return;

    // 解析Base64数据并转为Blob
    const [, base64Data] = base64Video.split(',');
    const byteCharacters = atob(base64Data);
    const byteArray = new Uint8Array(byteCharacters.length);
    for (let i = 0; i < byteCharacters.length; i++) {
      byteArray[i] = byteCharacters.charCodeAt(i);
    }
    const blob = new Blob([byteArray], { type: 'video/mp4' });
    const blobUrl = URL.createObjectURL(blob);

    videoRef.current.src = blobUrl;

    // 组件卸载时释放Blob URL,避免内存泄漏
    return () => URL.revokeObjectURL(blobUrl);
  }, [base64Video]);

  return <video ref={videoRef} controls />;
}

方案3:通过API路由返回视频流

如果视频文件较大,Base64会导致数据体积增大30%,此时可以创建Next.js API路由,直接返回视频文件的流,客户端用API地址作为video的src。

创建pages/api/video.js:

import fs from 'fs';
import path from 'path';
import { createReadStream } from 'fs';

export default function handler(req, res) {
  const filePath = path.join(process.cwd(), 'public/videos/example.mp4');
  const stat = fs.statSync(filePath);
  res.writeHead(200, {
    'Content-Type': 'video/mp4',
    'Content-Length': stat.size,
  });
  const stream = createReadStream(filePath);
  stream.pipe(res);
}

客户端组件代码:

export default function VideoPage() {
  return <video src="/api/video" controls />;
}

内容的提问来源于stack exchange,提问作者Lucas

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 14:25:46