使用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
相关产品推荐
相关产品推荐

