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

使用JavaScript上传视频至bunny.net成功但文件为空损坏求解决

解决bunny.net Stream视频上传后为空损坏的问题

问题场景

使用JavaScript上传视频到bunny.net Stream时,上传流程无报错,但最终生成的视频为空且损坏,原代码如下:

const fileInput = document.getElementById('videoFile');
           
let file = fileInput.files[0];
console.log(file);
video_name = file.name;
let video;
const toBase64 = file => new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = () => resolve(reader.result);
    reader.onerror = error => reject(error);
});
async function Main() {
    video = await toBase64(file);
}

video = Main();

const options = {
method: 'POST',
headers: {
    'Content-Type': 'application/json',
    accept: 'application/json',
    AccessKey: 'e3214df7-7dba-4a74-b93649716004-454b-46c3'
},
body: JSON.stringify({ 'title': video_name }),

};

result = fetch('https://video.bunnycdn.com/library/390820/videos', options)
.then(res => res.json())

.then(res => {
    videoId = res.guid;
    console.log(videoId);
    const options = {
    method: 'PUT',
    headers: {
        AccessKey: 'e3214df7-7dba-4a74-b93649716004-454b-46c3',
        'Content-Type': 'application/octet-stream',
    },
    data: video,
    };

    fetch(`https://video.bunnycdn.com/library/390820/videos/${videoId}`, options)
    .then(res => res.json())
    .then(res => console.log(res))
    .catch(err => console.error(err));
})
.catch(err => console.error(err));

错误原因分析

  1. 异步处理错误:Main()是异步函数,直接赋值给video得到的是Promise对象,而非实际文件数据,导致PUT请求发送无效内容。
  2. DataURL格式错误:readAsDataURL返回的结果包含data:xxx;base64,前缀,bunny.net的PUT接口需要纯二进制或不带前缀的Base64数据,直接传递会导致文件损坏。
  3. fetch参数错误:fetch API中没有data参数,应该使用body字段携带请求内容,原代码中data: video不会被正确识别,导致请求无有效数据。

修正后的代码

直接使用File对象上传二进制数据,无需转Base64,更高效且避免格式问题:

const fileInput = document.getElementById('videoFile');

async function uploadVideo() {
    const file = fileInput.files[0];
    if (!file) return;

    const videoName = file.name;
    const accessKey = 'e3214df7-7dba-4a74-b93649716004-454b-46c3';
    const libraryId = '390820';

    try {
        // 1. 创建视频条目
        const createRes = await fetch(`https://video.bunnycdn.com/library/${libraryId}/videos`, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'accept': 'application/json',
                'AccessKey': accessKey
            },
            body: JSON.stringify({ title: videoName })
        });
        const createData = await createRes.json();
        const videoId = createData.guid;
        console.log('创建视频条目成功,ID:', videoId);

        // 2. 上传视频文件
        const uploadRes = await fetch(`https://video.bunnycdn.com/library/${libraryId}/videos/${videoId}`, {
            method: 'PUT',
            headers: {
                'AccessKey': accessKey,
                'Content-Type': 'application/octet-stream'
            },
            body: file // 直接传递File对象作为二进制数据
        });
        const uploadData = await uploadRes.json();
        console.log('视频上传成功:', uploadData);
    } catch (err) {
        console.error('上传失败:', err);
    }
}

// 绑定上传触发事件(比如按钮点击)
document.getElementById('uploadBtn')?.addEventListener('click', uploadVideo);

关键优化点

  • 使用async/await统一处理异步流程,避免Promise回调嵌套和异步顺序错误。
  • 直接传递File对象作为PUT请求的body,无需转Base64,减少数据体积和格式转换错误。
  • 完善错误捕获,便于排查问题。

重要注意事项

  • AccessKey安全:前端代码直接暴露AccessKey存在被盗用风险,生产环境必须通过后端代理上传请求,由后端携带AccessKey。
  • 文件大小限制:bunny.net对单文件上传有大小限制,大文件建议使用分片上传接口。
  • Content-Type:PUT请求的Content-Type需设为application/octet-stream或对应视频MIME类型(如video/mp4)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 01:50:15