Skip to content

上传相关

  • 需 带入 authorization 头部

上传分为 视频 字幕 图片 等, 分为3步 获取基本信息 -> 获取上传token -> 保存上传结果

获取上传token

POST /api/upload/getUploadToken

请求参数

json5
{
  // 资源类型 video 视频 subtitle 字幕 image 图片
  "type": "video",
  // 文件格式
  "file_type": "video/mp4",
  // 文件名称
  "file_name": "demo.mp4",
  // 文件大小 字节
  "file_size": 250817,
  // 储存位置
  "file_storage": "default"
}
file_storage 储存位置
  • global 国际
  • internal 国内
  • default 默认
  • zn_r2_upload Zn存档服R2
  • google_drive 谷歌盘

响应内容

json5
{
  // 上传的存储设备 分为 onedrive google_drive r2 local 等 不同的储存设备请求方式不同
  "type": "onedrive",
  // 文件id
  "file_id": "xWDKXEMv2E",
  // 上传具体参数
  "data": {
    "upload_url": "url"
  }
}

具体上传方法

  • 如果出现 cors 等问题 请及时反馈 本地可以用 http://localhost:5173 进行测试

onedrive / google_drive

google_drive 不支持国内直传且存在 cors 问题

js
let file = File,
    start = 0,
    end = file.size - 1,
    total = file.size

/**
 * onedrive 分片必须是 320 KB 的整数倍
 * google_drive 分片必须是 256 KB 的整数倍 最小为 5MB
 */

fetch(upload_url, {
    method: 'PUT',
    headers: {
        // 实际的 mime type
        'Content-Type': 'application/octet-stream',
        'Content-Range': `bytes ${start}-${end}/${total}`
    },
    body: file,
})

r2

js
let file = File

fetch(upload_url, {
    method: 'PUT',
    body: file,
})

tusd

tus-js-client
js
let file = File

let upload = new tus.Upload(file, {
    endpoint: '[上传地址 upload_url]',
    // 分片大小 不要超过100
    chunkSize: 100 * 1024 * 1024,
    retryDelays: [0, 1000],
    // 移除上传成功的记录 开发用
    removeFingerprintOnSuccess: true,
    metadata: {
        user_id: '[用户ID]',
        file_id: '[文件ID]',
    },
    onError: function (error) {
        console.log('Failed because: ' + error)
    },
    onProgress: function (bytesUploaded, bytesTotal) {
        var percentage = ((bytesUploaded / bytesTotal) * 100).toFixed(2)
        console.log(bytesUploaded, bytesTotal, percentage + '%')
    },
    onSuccess: function (res) {
        let {file_id, url} = JSON.parse(res.lastResponse.getBody())

        // {"file_id":"xxxx","url":"xxxx"}
        console.log(file_id, url)
        console.log('success %s from %s', upload.file.name, url)
    },
})

upload.start()

multipart

这是个 分片上传 流程为 获取上传凭证 -> 客户端进行上传 -> 分片合并

js
let file = File

// 根据获取上传凭证中的 分片限制文件大小 计算要分片的数量

// 请求分片凭证
let presigns = [
    {
        "number": 1,
        "upload_url": "https://emos.local/xxxx",
        // 暂未用到
        "upload_data": {}
    }
]

// 分片上传
let parts = []
for (let persign of presigns) {
   let part_res = fetch(persign.upload_url, {
        method: 'PUT',
        // 切片文件
        body: file.slice(start, end),
    })
    parts.push({
        number: persign.number,
        // 拿到响应头返回的 ETag
        etag: res.headers.get('ETag'),
    })
}

// 调用分片合并接口

视频相关

获取基本信息

GET /api/upload/video/base?item_type=[item_type]&item_id=[item_id]

请求参数

  • item_type 资源类型 电影类型的 vl 或 电视剧类型的 ve
  • item_id 资源id

响应内容

电影 vl
json5
{
  "title": "阿凡达:水之道"
}
电视集 ve
json5
{
  "video_list_name": "【我推的孩子】",
  "season_number": "S01",
  "episode_number": "E03",
  "episode_title": "漫画原作的电视剧",
  "title": "【我推的孩子】 - S01E03 - 漫画原作的电视剧"
}

保存上传结果

POST /api/upload/video/save

请求参数

json5
{
  "item_type": "vl",
  "item_id": 1,
  "file_id": "xWDKXEMv2E"
}
  • item_typeitem_id 与获取基本信息相同
  • file_id 从获取上传token获取到的

响应内容

正常
json5
{
  // 总上传的数量
  "count": 2,
  // 获得的胡萝卜数量
  "carrot": 0,
  // 媒体资源ID 删除或获取详情时用
  "media_id": "Y1qy9kW9v86K"
}
错误

http code 422

json5
{
  "message": "视频正在合并中 请等待1分钟后再保存试下"
}

字幕相关

字幕无须获取详细信息 直接保存即可

保存字幕

POST /api/upload/subtitle/save

请求参数

json5
{
  "item_type": "vl",
  "item_id": 1,
  "file_id": "xWDKXEMv2E"
}
  • item_typeitem_id 与获取基本信息相同
  • file_id 从获取上传token获取到的

响应内容

正常
json5
{
  // 获得的胡萝卜数量
  "carrot": 0,
  // 字幕ID 删除时用
  "subtitle_id": "Bpvx8YxPoVdQ"
}

其他

通知

目前的上传通知会在 emospg_notify 这里推送

如果需要接入通知 可提供一个地址 系统将会以 POST 形式发送以下内容到的你的接口

tmdb_iduser_pseudonym 有概率为 null

json5
// 电视
{
  "video_id": 1000,
  "video_type": "tv",
  "video_title": "21世纪大君夫人",
  "todb_id": 1000,
  "tmdb_id": 278573,
  "media_id": "xxxxx",
  "user_pseudonym": "张三",
  "season_number": 1,
  "episode_number": 1
}

// 电影
{
  "video_id": 1001,
  "video_type": "movie",
  "video_title": "最伟大的作品",
  "todb_id": 1001,
  "tmdb_id": null,
  "media_id": "xxxxxx",
  "user_pseudonym": null
}