TikTok
支持公开单条视频和图文作品。
tiktok.com/@user/video/{id}tiktok.com/@user/photo/{id}tiktok.com/t/{shortCode}vm.tiktok.com/{code} or other TikTok share links不支持主页、直播页和 TikTok Lite 页面。
Easydown API
你可以在自己的后端、脚本或自动化服务里调用 Easydown API,把公开媒体链接解析成统一的数据结构。
POST https://api.easydown.org/api/v1/parse
把私有 API token 放在 Bearer token 中请求。不要把 ed_live token 暴露在浏览器 JavaScript 里。
Authorization
Bearer ed_live_xxx
Content-Type
application/json
curl -X POST https://api.easydown.org/api/v1/parse \
-H "Authorization: Bearer ed_live_xxx" \
-H "Content-Type: application/json" \
-d '{"url":"https://www.instagram.com/reel/..."}'{
"url": "https://www.instagram.com/reel/..."
}所有平台都使用同一个解析接口。下面这些格式会被识别为公开单条媒体链接;最终是否返回媒体仍取决于内容是否公开且可解析。
支持公开单条视频和图文作品。
tiktok.com/@user/video/{id}tiktok.com/@user/photo/{id}tiktok.com/t/{shortCode}vm.tiktok.com/{code} or other TikTok share links不支持主页、直播页和 TikTok Lite 页面。
支持公开视频、图文、分享短链和部分抖音媒体 CDN 直链。
v.douyin.com/{code}douyin.com/video/{id}douyin.com/share/video/{id}douyin.com/note/{id}douyin.com/share/note/{id}douyin.com/shipin/{id}douyin.com/vsdetail/{id}douyinpic.com / douyinvod.com / douyinstatic.com media URLs不支持主页、搜索、合集、关注页和直播页。
支持公开视频、Shorts 和可解析为视频 ID 的 live 回放链接。
youtu.be/{id}youtube.com/watch?v={id}youtube.com/shorts/{id}youtube.com/live/{id}不支持播放列表、频道页、社区帖子和私密视频。
支持带 status ID 的公开帖子链接。
x.com/{user}/status/{id}twitter.com/{user}/status/{id}不支持主页、搜索页、Spaces 和直接媒体 CDN 链接。
支持公开帖子、Reels、视频、图片、图集、embed 和 share 跳转链接。
instagram.com/p/{code}instagram.com/reel/{code}instagram.com/reels/{code}instagram.com/tv/{code}instagram.com/{username}/p/{code}instagram.com/{username}/reel/{code}instagram.com/p/{code}/embedinstagram.com/r/{code}instagram.com/share/...不支持 Stories、Highlights、主页、私信、Explore 页面和私密内容。
支持公开视频笔记和图文笔记链接。
xhslink.com/{code}xiaohongshu.com/explore/{noteId}xiaohongshu.com/discovery/item/{noteId}Share text containing a Xiaohongshu URL不支持主页、搜索页、合集和私密笔记。
支持公开视频页、短链、带 bvid 的列表播放页和部分可播放页面。
bilibili.com/video/BV...bilibili.com/video/av...b23.tv/{code}bili.im/{code}bilibili.com/list/...?...bvid=BV...bilibili.com/bangumi/play/ep...bilibili.com/bangumi/play/ss...bilibili.com/cheese/play/ss...不支持稍后再看列表、收藏夹、主页和没有单个视频标识的列表页。
支持公开单条快手视频链接和分享文案。
kuaishou.com/short-video/{photoId}kuaishou.com/f/{token}v.kuaishou.com/{token}gifshow.com/fw/photo/{photoId}chenzhongtech.com/fw/photo/{photoId}Share text containing a Kuaishou URL不支持主页、搜索页、合集、直播页和私密视频。
支持公开视频、图片或图集微博正文链接。
weibo.com/{uid}/{postId}weibo.com/{uid}/{mblogid}m.weibo.cn/status/{id}weibo.com/tv/show/1034:{id}video.weibo.com/show?fid=1034:{id}t.cn/{code}mapp.api.weibo.cn/fx/...Share text containing a Weibo URL不支持主页、搜索页、话题、超话、直播、文章页和合集。
API key 可以设置过期时间,不填写表示永久有效。你也可以把 key 限制为指定平台;选择全平台表示允许所有支持平台。编辑 key 只会修改名称、过期时间和平台权限,不会改变 token 明文。重置会轮换 token 明文,但保留权限设置。
{
"status": 200,
"data": {
"platform": "instagram",
"title": "Example title",
"thumbnail": "https://...",
"duration": 12,
"images": [
{
"url": "https://...",
"width": 1080,
"height": 1350
}
],
"videos": [
{
"url": "https://...",
"quality": "HD",
"mimeType": "video/mp4",
"width": 1080,
"height": 1920,
"hasAudio": true,
"source": "direct"
}
],
"audios": []
},
"msg": "success"
}{
"status": 401,
"data": null,
"msg": "Unauthorized",
"code": "missing_token"
}| Field | Type | Description |
|---|---|---|
| platform | string | Normalized platform name such as instagram or youtube. |
| title | string | Media title or caption when available. |
| thumbnail | string | Preview image URL when available. |
| duration | number | Duration in seconds. Images and galleries usually return 0. |
| images[] | array | Downloadable image items with url, width, and height. |
| videos[] | array | Downloadable video items with url, quality, mimeType, dimensions, hasAudio, and source. |
| audios[] | array | Downloadable audio items when the platform exposes audio separately. |
Easydown 会在 images[]、videos[]、audios[] 中返回媒体资源地址。这些地址来自原平台,可能受到链接时效、防盗链、跨域、Cookie、地区限制或音视频分离等因素影响。
很多平台 CDN 会校验 Origin、Referer、Cookie、IP 地区和请求头。同一个媒体 URL,在服务端请求可能正常,但在浏览器 JavaScript 中可能出现 CORS、CORP、403、404 或空文件。
| 平台 | 建议请求头 | 是否需要 Cookie | 特殊处理 | 时效说明 |
|---|---|---|---|---|
| Douyin | Referer: https://www.douyin.com/;浏览器 User-Agent;有 Range 时继续转发。 | 通常不需要 | 视频和图文媒体建议由服务端流式下载。 | 链接时效较短,遇到 403 或 404 时重新解析。 |
| TikTok | Referer: https://www.tiktok.com/;浏览器 User-Agent。 | 有时需要 | 部分 Web 媒体可能需要用户自己访问上下文中的 tt_chain_token 等 Cookie;地区限制内容需要使用可访问地区的服务端。 | 直连失败时重新解析并重试。 |
| Bilibili | Referer: https://www.bilibili.com/;浏览器 User-Agent;转发 Range。 | 部分高清或账号限制流需要 | DASH 结果可能返回独立视频流和音频流,需要分别下载后用 FFmpeg 合并。 | 签名流过期后需要重新解析。 |
| Xiaohongshu | Referer: https://www.xiaohongshu.com/;浏览器 User-Agent。 | 有时需要 | 图片和视频 CDN 防盗链较严格,建议通过后端下载。 | CDN 地址失效后重新解析。 |
| Referer: https://weibo.com/ 或 https://m.weibo.cn/;浏览器 User-Agent。 | 通常不需要 | 返回多个清晰度时,按业务需要选择对应 URL。 | 图片和视频链接可能过期,重新解析可刷新。 | |
| YouTube | Referer: https://www.youtube.com/;Origin: https://www.youtube.com;浏览器 User-Agent。 | 受保护或账号限制内容需要 | 高画质常见音视频分离,需要用 FFmpeg 合并独立流。 | 部分流会绑定地区或 IP,需要使用可访问地区服务端并在必要时重新解析。 |
| Referer: https://www.instagram.com/;浏览器 User-Agent。 | 有时需要 | 浏览器预览容易遇到 CORS 或 CORP,稳定下载建议走后端代理。 | CDN URL 可能过期,需要重新解析公开帖子。 | |
| Kuaishou | Referer: https://www.kuaishou.com/;浏览器 User-Agent;转发 Range。 | 通常不需要 | 大文件短视频建议服务端流式下载。 | 媒体链接可能过期,重新解析公开作品链接。 |
| X / Twitter | Referer: https://x.com/;浏览器 User-Agent。 | 通常不需要 | 视频资源可能返回多码率,按业务场景选择清晰度。 | 选中的媒体 variant 失败时重新解析。 |
Node.js / Next.js 代理路由
// app/api/media-proxy/route.js
const PLATFORM_HEADERS = {
douyin: {
Referer: 'https://www.douyin.com/',
'User-Agent': 'Mozilla/5.0 AppleWebKit/537.36 Chrome/120 Safari/537.36',
},
tiktok: {
Referer: 'https://www.tiktok.com/',
'User-Agent': 'Mozilla/5.0 AppleWebKit/537.36 Chrome/120 Safari/537.36',
},
bilibili: {
Referer: 'https://www.bilibili.com/',
'User-Agent': 'Mozilla/5.0 AppleWebKit/537.36 Chrome/120 Safari/537.36',
},
xiaohongshu: {
Referer: 'https://www.xiaohongshu.com/',
'User-Agent': 'Mozilla/5.0 AppleWebKit/537.36 Chrome/120 Safari/537.36',
},
weibo: {
Referer: 'https://weibo.com/',
'User-Agent': 'Mozilla/5.0 AppleWebKit/537.36 Chrome/120 Safari/537.36',
},
youtube: {
Referer: 'https://www.youtube.com/',
Origin: 'https://www.youtube.com',
'User-Agent': 'Mozilla/5.0 AppleWebKit/537.36 Chrome/120 Safari/537.36',
},
instagram: {
Referer: 'https://www.instagram.com/',
'User-Agent': 'Mozilla/5.0 AppleWebKit/537.36 Chrome/120 Safari/537.36',
},
kuaishou: {
Referer: 'https://www.kuaishou.com/',
'User-Agent': 'Mozilla/5.0 AppleWebKit/537.36 Chrome/120 Safari/537.36',
},
twitter: {
Referer: 'https://x.com/',
'User-Agent': 'Mozilla/5.0 AppleWebKit/537.36 Chrome/120 Safari/537.36',
},
};
export async function GET(request) {
const { searchParams } = new URL(request.url);
const mediaUrl = searchParams.get('url');
const platform = searchParams.get('platform');
if (!mediaUrl || !platform || !PLATFORM_HEADERS[platform]) {
return Response.json({ error: 'invalid_request' }, { status: 400 });
}
const range = request.headers.get('range');
const headers = { ...PLATFORM_HEADERS[platform] };
if (range) headers.Range = range;
const mediaResponse = await fetch(mediaUrl, { headers });
if (!mediaResponse.ok || !mediaResponse.body) {
return Response.json(
{ error: 'download_failed', status: mediaResponse.status },
{ status: 502 }
);
}
const responseHeaders = new Headers();
const contentType = mediaResponse.headers.get('content-type');
const contentLength = mediaResponse.headers.get('content-length');
const contentRange = mediaResponse.headers.get('content-range');
if (contentType) responseHeaders.set('Content-Type', contentType);
if (contentLength) responseHeaders.set('Content-Length', contentLength);
if (contentRange) responseHeaders.set('Content-Range', contentRange);
responseHeaders.set('Accept-Ranges', 'bytes');
responseHeaders.set('Cache-Control', 'private, max-age=300');
return new Response(mediaResponse.body, {
status: mediaResponse.status,
headers: responseHeaders,
});
}浏览器调用方式
// Browser code: call your own backend, not the platform CDN directly.
const downloadUrl = new URL('/api/media-proxy', window.location.origin);
downloadUrl.searchParams.set('platform', media.platform);
downloadUrl.searchParams.set('url', media.videos[0].url);
window.location.href = downloadUrl.toString();音视频分离合并
# When video and audio are returned separately, download both files first.
ffmpeg -i video.mp4 -i audio.m4a -c copy output.mp4成功解析 1 次扣 1 credit。解析失败、不支持的链接、鉴权失败和平台响应失败都不会扣 credits。
API 面向公开单条媒体内容。私密内容、已删除内容、地区限制内容、直播、主页、搜索页和合集页不在支持范围内。
| HTTP | Code | Meaning |
|---|---|---|
| 401 | missing_token / invalid_token | Authorization header is missing or the token is invalid. |
| 401 | token_expired | The API token has passed its expiration date. Edit the key or create a new one. |
| 403 | platform_not_allowed | The API token is not allowed to access the platform detected from the URL. |
| 402 | insufficient_credits | The account does not have enough credits for a successful parse. |
| 400 | 302 | The URL format is unsupported or not a single supported media post. |
| 200 | 304 | Easydown could not return downloadable media for this public link. |
需要接入帮助?加入 Telegram 或 Discord 咨询。