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

使用Pinata SDK(Node.js)上传大文件至Pinata的问题

解决方案

1. 手动实现Pinata API分段上传

Pinata SDK的pinFileToIPFS对大文件支持有限,但底层API支持分片上传,你可以自己拆分文件后逐个上传分片,最后组合成完整文件:

  • 把视频按固定大小(比如100MB)拆成分片
  • 用axios或其他HTTP库逐个上传分片到Pinata的/pinning/pinFileToIPFS接口,记录每个分片的CID
  • 最后创建一个包含所有分片的目录结构并上传,得到根CID,这个根CID就对应完整的视频文件

代码示例(Node.js):

const fs = require('fs');
const axios = require('axios');
const FormData = require('form-data');

const PINATA_API_KEY = '你的API密钥';
const PINATA_SECRET_KEY = '你的API密钥';
const FILE_PATH = 'path/to/your-video.mp4';
const CHUNK_SIZE = 100 * 1024 * 1024; // 100MB分片

async function uploadLargeFile() {
  const fileSize = fs.statSync(FILE_PATH).size;
  const totalChunks = Math.ceil(fileSize / CHUNK_SIZE);
  const chunkCIDs = [];

  // 上传所有分片
  for (let i = 0; i < totalChunks; i++) {
    const start = i * CHUNK_SIZE;
    const end = Math.min(start + CHUNK_SIZE, fileSize);
    const chunkStream = fs.createReadStream(FILE_PATH, { start, end });

    const form = new FormData();
    form.append('file', chunkStream, { filename: `chunk-${i}.part` });

    const res = await axios.post('https://api.pinata.cloud/pinning/pinFileToIPFS', form, {
      headers: {
        ...form.getHeaders(),
        'pinata_api_key': PINATA_API_KEY,
        'pinata_secret_api_key': PINATA_SECRET_KEY
      },
      maxBodyLength: Infinity,
      maxContentLength: Infinity
    });

    chunkCIDs.push(res.data.IpfsHash);
    console.log(`分片 ${i+1}/${totalChunks} 上传完成,CID: ${res.data.IpfsHash}`);
  }

  // 上传包含所有分片的目录
  const dirForm = new FormData();
  chunkCIDs.forEach((cid, idx) => {
    const chunkMeta = JSON.stringify({
      path: `video-chunks/chunk-${idx}.part`,
      cid: cid,
      size: Math.min(CHUNK_SIZE, fileSize - idx * CHUNK_SIZE)
    });
    dirForm.append('file', chunkMeta, { filename: `meta-${idx}.json` });
  });

  const dirRes = await axios.post('https://api.pinata.cloud/pinning/pinFileToIPFS', dirForm, {
    headers: {
      ...dirForm.getHeaders(),
      'pinata_api_key': PINATA_API_KEY,
      'pinata_secret_api_key': PINATA_SECRET_KEY
    }
  });

  console.log('完整视频根CID:', dirRes.data.IpfsHash);
  return dirRes.data.IpfsHash;
}

uploadLargeFile().catch(err => console.error('上传失败:', err));

2. 优化Node.js运行配置

直接上传大文件时,Node.js的默认内存限制和请求超时容易导致崩溃,调整以下配置:

  • 启动服务器时增加内存配额:node --max-old-space-size=4096 your-server.js(分配4GB内存,根据需求调整)
  • 发起请求时设置无限大的内容长度和更长的超时:
// 以axios为例
axios.post(..., {
  timeout: 3600000, // 1小时超时
  maxBodyLength: Infinity,
  maxContentLength: Infinity
});
  • 确保用流式上传:给pinFileToIPFS传入fs.createReadStream()而不是文件Buffer,避免把整个视频加载到内存

3. 用Pinata Desktop客户端上传(非自动化场景)

如果不需要程序化上传,Pinata官方的桌面客户端会自动处理大文件的分片、上传和组合,完全不用自己写代码,还能避免服务器崩溃问题。

4. 本地IPFS节点预处理后再Pin

先在本地IPFS节点把视频分片:

ipfs add --pin=false your-video.mp4

得到根CID后,用Pinata SDK的pinByHash接口来Pin这个CID,Pinata会自动拉取所有相关分片,省去自己处理分片的麻烦:

const pinataSDK = require('@pinata/sdk');
const pinata = pinataSDK('你的API密钥', '你的API密钥');

async function pinPreprocessedCID() {
  const rootCID = '本地IPFS生成的根CID';
  const result = await pinata.pinByHash(rootCID, {
    pinataMetadata: { name: 'My Large Video' }
  });
  console.log('Pin成功:', result);
}

pinPreprocessedCID().catch(err => console.error(err));

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 21:03:31