调用TikTok Video Kit API上传视频失败 报错缺少二进制video字段
问题根因
你遇到的两个报错分属不同阶段的问题:
- 持续返回
expecting a binary field 'video' in the form-data和视频时长、文件来源完全无关,是两个配置错误导致的:一是你手动写死了Content-Type: multipart/form-data请求头,丢失了multipart格式必须的boundary分隔符,服务端根本无法正确拆分表单字段;二是你往FormData里追加流/Buffer时没有指定文件元信息,form-data库会把传入的内容当成普通文本字段处理,不会按二进制文件格式编码,自然识别不到video字段。 - 换长视频后出现的KRAKEND Bad Gateway报错,是axios默认超时时间过短,大文件流还没传输完成客户端就主动断开了连接,触发网关报错。
你之前尝试的拼接流为字符串再上传的方案是错的,二进制视频数据转字符串会出现编码损坏,就算格式对了传上去也是损坏的文件。
修复方案
按以下步骤调整代码即可,不需要把文件存到本地,完全支持内存/云存储流直传:
- Node环境下必须使用官方
form-datanpm包,不要用浏览器环境的FormData polyfill。 - 不要手动设置
Content-Type请求头,调用formData实例自带的getHeaders()方法生成请求头,它会自动带上正确的boundary参数。 - 调用
formData.append()添加视频字段时,必须传入第三个配置参数,显式指定filename和contentType,告诉form-data这是一个二进制文件,不是普通文本。 - 调大axios的超时时间,同时放开请求体大小限制,避免大文件传输中途断连。
- 测试视频必须满足平台基础要求:时长大于3秒、H.264编码、无违规内容,排除业务层面的拦截。
可直接复用的代码
const { Storage } = require('@google-cloud/storage'); const axios = require('axios'); const FormData = require('form-data'); const storage = new Storage(); const bucket = storage.bucket("<你的GCS桶名>"); const remoteFile = bucket.file("<视频在GCS中的路径>"); const openId = token['open_id']; const accessToken = token['access_token']; const postUrl = `${process.env.TIKTOK_POST_URL}?open_id=${openId}&access_token=${accessToken}`; const formData = new FormData(); // 核心:传GCS可读流,显式标记为二进制视频文件 formData.append('video', remoteFile.createReadStream(), { filename: 'tiktok_upload.mp4', // 文件名可自定义,必须带正确的视频后缀 contentType: 'video/mp4' }); const postResponse = await axios.post(postUrl, formData, { headers: formData.getHeaders(), // 自动生成带boundary的Content-Type,不要手动写 timeout: 300000, // 超时设为5分钟,可根据文件大小调整 maxContentLength: Infinity, // 取消响应体大小限制 maxBodyLength: Infinity // 取消请求体大小限制 }); console.log('上传结果:', postResponse.data);
如果要上传本地文件,只需要把append的第二个参数替换成本地文件可读流即可,其他配置完全一致:
const fs = require('fs'); formData.append('video', fs.createReadStream("C:/Users/[ME]/Downloads/tem.mp4"), { filename: 'tem.mp4', contentType: 'video/mp4' });
如果要传Buffer格式的视频,写法也一样:
// 假设videoBuffer是你存在内存里的视频Buffer formData.append('video', videoBuffer, { filename: 'upload.mp4', contentType: 'video/mp4' });
内容的提问来源于stack exchange,提问作者Mr.Grease
相关产品推荐
相关产品推荐

