December 5, 2025
214 閲覧数
Default

マルチプラットフォーム動画リンクダウンロードガイド

本ドキュメントでは、抖音、TikTok、哔哩哔哩、小红书、微博などのプラットフォームから動画リンクを取得した後、動画ファイルを正しくダウンロードする方法を詳しく紹介します。クロスオリジン、防盗リンク、リクエストヘッダー検証などのよくある問題の解決に重点を置いています。

マルチプラットフォーム動画リンクダウンロードガイド

本文書では、抖音、TikTok、哔哩哔哩、小红书、微博などのプラットフォームから動画リンクを取得した後、動画ファイルを正しくダウンロードする方法を詳しく紹介します。クロスオリジン、防盗鏈、リクエストヘッダー検証などの一般的な問題の解決に重点を置いています。

目次


共通問題の概要

各プラットフォームから動画リンクを取得した後、直接ダウンロードすると通常以下の問題に遭遇します:

問題タイプ説明解決策
防盗鏈 (Referer)サーバーがリクエスト元を確認し、不正な送信元を拒否する正しい Referer ヘッダーを設定する
クロスオリジン (CORS)ブラウザのセキュリティポリシーがクロスオリジンリクエストをブロックするバックエンドプロキシ / サーバー側ダウンロード
User-Agent 検証サーバーがクライアント識別子を確認するブラウザ UA を模擬する
Cookie 検証一部のリンクはログイン状態が必要有効な Cookie を付与する
リンクの有効期限動画リンクには有効期限がある速やかに使用し、期限切れなら再取得する
IP 制限一部のリンクはアクセス地域を制限する対応地域のプロキシを使用する

抖音 (Douyin)

動画リンクの特徴

抖音の動画リンクには通常、以下のような形式があります:

txt
1# 播放地址 (无水印)
2https://www.douyin.com/aweme/v1/play/?video_id=xxx&line=0&file_id=xxx
3
4# CDN 地址
5https://v26-web.douyinvod.com/xxx/xxx.mp4
6
7# 带水印下载地址
8https://aweme.snssdk.com/aweme/v1/playwm/?video_id=xxx

ダウンロード要件

リクエストヘッダー必須か
Referer必須https://www.douyin.com/
User-Agent推奨ブラウザ UA
Cookie任意一部の高画質リンクで必要

サーバー側ダウンロード例

python
1import httpx
2
3async def download_douyin_video(video_url: str, save_path: str) -> bool:
4    """
5    下载抖音视频
6
7    Args:
8        video_url: 视频播放地址
9        save_path: 保存路径
10
11    Returns:
12        是否下载成功
13    """
14    headers = {
15        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
16        "Referer": "https://www.douyin.com/",  # 必须
17        "Accept": "*/*",
18        "Accept-Encoding": "identity",  # 避免压缩,方便流式下载
19        "Range": "bytes=0-",  # 支持断点续传
20    }
21
22    async with httpx.AsyncClient(follow_redirects=True, timeout=60) as client:
23        async with client.stream("GET", video_url, headers=headers) as response:
24            if response.status_code in [200, 206]:
25                with open(save_path, "wb") as f:
26                    async for chunk in response.aiter_bytes(chunk_size=8192):
27                        f.write(chunk)
28                return True
29    return False

フロントエンドのクロスオリジン問題

抖音の動画リンクはCORS をサポートしていないため、フロントエンドから直接リクエストするとブラウザにブロックされます:

javascript
1// ❌ 错误方式 - 会被 CORS 拦截
2fetch('https://v26-web.douyinvod.com/xxx.mp4')
3  .then(res => res.blob())  // CORS error!
4
5// ✅ 正确方式 - 使用后端代理
6fetch('/api/proxy/video?url=' + encodeURIComponent(videoUrl))
7  .then(res => res.blob())
8  .then(blob => {
9    const url = URL.createObjectURL(blob);
10    const a = document.createElement('a');
11    a.href = url;
12    a.download = 'video.mp4';
13    a.click();
14  });

注意事項

  1. リンクの有効期限: 抖音の動画リンクは通常 24 時間 以内有効
  2. 透かしなしリンク: play_addr を使用し、download_addr は使用しない
  3. 高画質リンク: 一部の 4K/原画動画はサイズが大きいため、分割ダウンロードを推奨し、一括ダウンロード失敗を避ける

TikTok

動画リンクの特徴

txt
1# 播放地址
2https://v16-webapp-prime.tiktok.com/video/tos/xxx.mp4
3
4# 无水印地址
5https://www.tiktok.com/aweme/v1/play/?video_id=xxx
6
7# 带水印地址
8https://v16-webapp.tiktok.com/video/tos/xxx.mp4

ダウンロード要件

Web 端動画リンク

リクエストヘッダー必須か
Referer必須https://www.tiktok.com/
User-Agent必須ブラウザ UA
Cookie必須tt_chain_token フィールドが必要

重要: TikTok Web 端が返す動画リンクは、ダウンロードするために必ず tt_chain_token Cookie を付与する必要があります。そうしないと 403 エラーが返されます。

App 端動画リンク

リクエストヘッダー必須か
User-Agent推奨任意の UA
Cookie不要App 端リンクにはこの制限がない

推奨: App 端リンクを取得できる場合は、Cookie 問題を処理する必要がないため、優先して使用してください。

サーバー側ダウンロード例

Web 端ダウンロード (tt_chain_token が必要)

python
1import httpx
2
3async def download_tiktok_video_web(
4    video_url: str,
5    save_path: str,
6    tt_chain_token: str  # 必须提供
7) -> bool:
8    """
9    下载 TikTok Web 端视频
10
11    注意:
12    - Web 端链接必须携带 tt_chain_token Cookie
13    - tt_chain_token 可从浏览器或 API 响应中获取
14    """
15    headers = {
16        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36",
17        "Referer": "https://www.tiktok.com/",
18        "Accept": "video/webm,video/ogg,video/*;q=0.9,*/*;q=0.8",
19        "Accept-Language": "en-US,en;q=0.5",
20        "Cookie": f"tt_chain_token={tt_chain_token}",  # 必须
21        "Sec-Fetch-Dest": "video",
22        "Sec-Fetch-Mode": "no-cors",
23        "Sec-Fetch-Site": "cross-site",
24    }
25
26    async with httpx.AsyncClient(follow_redirects=True, timeout=60) as client:
27        async with client.stream("GET", video_url, headers=headers) as response:
28            if response.status_code in [200, 206]:
29                with open(save_path, "wb") as f:
30                    async for chunk in response.aiter_bytes(chunk_size=8192):
31                        f.write(chunk)
32                return True
33            elif response.status_code == 403:
34                print("下载失败: tt_chain_token 无效或缺失")
35    return False
python
1async def download_tiktok_video_app(video_url: str, save_path: str) -> bool:
2    """
3    下载 TikTok App 端视频
4
5    App 端链接无需 Cookie,直接下载即可
6    """
7    headers = {
8        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
9        "Accept": "*/*",
10    }
11
12    async with httpx.AsyncClient(follow_redirects=True, timeout=60) as client:
13        async with client.stream("GET", video_url, headers=headers) as response:
14            if response.status_code in [200, 206]:
15                with open(save_path, "wb") as f:
16                    async for chunk in response.aiter_bytes(chunk_size=8192):
17                        f.write(chunk)
18                return True
19    return False

tt_chain_token の取得方法

tt_chain_token は TikTok が動画ダウンロード認証に使用する Cookie で、取得方法は以下の通りです:

  1. ブラウザから取得: TikTok サイトを開き、F12 開発者ツール -> Application -> Cookies -> tt_chain_token を探す

  2. API レスポンスから取得: 一部の TikTok API レスポンスの Set-Cookie ヘッダーにこの値が含まれることがあります

  3. TikHub API を使用: API の返却データに利用可能な token がすでに含まれている場合があります

python
1# 示例:从响应头提取 tt_chain_token
2def extract_tt_chain_token(response_headers: dict) -> str:
3    """从响应头中提取 tt_chain_token"""
4    cookies = response_headers.get("set-cookie", "")
5    for cookie in cookies.split(";"):
6        if "tt_chain_token=" in cookie:
7            return cookie.split("tt_chain_token=")[1].split(";")[0]
8    return ""

地域制限

TikTok の動画には地域制限がある場合があり、一部の動画は特定の国でのみアクセス可能です:

python
1# 使用代理下载特定地区视频
2proxies = {
3    "http://": "http://us-proxy:8080",
4    "https://": "http://us-proxy:8080",
5}
6
7async with httpx.AsyncClient(proxies=proxies) as client:
8    # ...

注意事項

  1. 地域制限: 一部の動画は米国/欧州の IP でのみアクセス可能
  2. リンクの有効期限: リンクの有効期限は約 24 時間
  3. 透かしなし: downloadAddr フィールドを優先して使用する

哔哩哔哩 (Bilibili)

動画リンクの特徴

B站の動画リンクは少し特殊で、音声と動画が分離されています:

txt
1# 视频流 (DASH)
2https://upos-sz-mirrorali.bilivideo.com/xxx/xxx.m4s
3
4# 音频流 (DASH)
5https://upos-sz-mirrorali.bilivideo.com/xxx/xxx.m4s
6
7# FLV 格式 (旧版)
8https://upos-sz-mirrorali.bilivideo.com/xxx/xxx.flv

ダウンロード要件

リクエストヘッダー必須か
Referer必須https://www.bilibili.com/
User-Agent推奨ブラウザ UA
Cookie高画質、4K は必須SESSDATA など
Range推奨分割ダウンロード

サーバー側ダウンロード例

python
1import httpx
2import subprocess
3from pathlib import Path
4
5async def download_bilibili_video(
6    video_url: str,
7    audio_url: str,
8    save_path: str,
9    cookie: str = None
10) -> bool:
11    """
12    下载 B站 视频 (需要合并音视频)
13
14    Args:
15        video_url: 视频流地址
16        audio_url: 音频流地址
17        save_path: 最终保存路径
18        cookie: 可选,高清视频需要 SESSDATA
19    """
20    headers = {
21        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36",
22        "Referer": "https://www.bilibili.com/",  # 必须,否则 403
23        "Accept": "*/*",
24        "Accept-Encoding": "identity",
25        "Origin": "https://www.bilibili.com",
26    }
27
28    if cookie:
29        headers["Cookie"] = cookie
30
31    # 临时文件路径
32    video_temp = save_path + ".video.m4s"
33    audio_temp = save_path + ".audio.m4s"
34
35    async with httpx.AsyncClient(follow_redirects=True, timeout=120) as client:
36        # 下载视频流
37        async with client.stream("GET", video_url, headers=headers) as response:
38            if response.status_code not in [200, 206]:
39                return False
40            with open(video_temp, "wb") as f:
41                async for chunk in response.aiter_bytes(chunk_size=8192):
42                    f.write(chunk)
43
44        # 下载音频流
45        async with client.stream("GET", audio_url, headers=headers) as response:
46            if response.status_code not in [200, 206]:
47                return False
48            with open(audio_temp, "wb") as f:
49                async for chunk in response.aiter_bytes(chunk_size=8192):
50                    f.write(chunk)
51
52    # 使用 FFmpeg 合并音视频
53    try:
54        subprocess.run([
55            "ffmpeg", "-y",
56            "-i", video_temp,
57            "-i", audio_temp,
58            "-c:v", "copy",
59            "-c:a", "copy",
60            save_path
61        ], check=True, capture_output=True)
62
63        # 删除临时文件
64        Path(video_temp).unlink()
65        Path(audio_temp).unlink()
66        return True
67    except subprocess.CalledProcessError:
68        return False
画質ログインが必要かCookie 要件
360P/480Pいいえなし
720PはいSESSDATA
1080PはいSESSDATA + 大会员
4K/HDRはいSESSDATA + 大会员

注意事項

  1. 必ず結合する: DASH 形式では音声と動画が分離されているため、FFmpeg で結合する必要がある
  2. Referer 必須: 正しい Referer がないと 403 が返される
  3. リンクの有効期限: 約 2 時間 有効
  4. 分割ダウンロード: 大容量ファイルは Range ヘッダーでの分割ダウンロードを推奨

小红书 (Xiaohongshu)

動画リンクの特徴

txt
1# 视频地址
2https://sns-video-bd.xhscdn.com/xxx.mp4
3https://sns-video-hw.xhscdn.com/xxx.mp4
4
5# 图片地址
6https://sns-img-bd.xhscdn.com/xxx.jpg

ダウンロード要件

リクエストヘッダー必須か
Referer必須https://www.xiaohongshu.com/
User-Agent推奨ブラウザ UA
Cookie任意一部コンテンツで必要

サーバー側ダウンロード例

python
1import httpx
2
3async def download_xiaohongshu_video(video_url: str, save_path: str) -> bool:
4    """
5    下载小红书视频
6
7    小红书对 Referer 检查较严格
8    """
9    headers = {
10        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
11        "Referer": "https://www.xiaohongshu.com/",  # 必须
12        "Accept": "*/*",
13        "Origin": "https://www.xiaohongshu.com",
14        "Sec-Fetch-Dest": "video",
15        "Sec-Fetch-Mode": "cors",
16        "Sec-Fetch-Site": "cross-site",
17    }
18
19    async with httpx.AsyncClient(follow_redirects=True, timeout=60) as client:
20        async with client.stream("GET", video_url, headers=headers) as response:
21            if response.status_code in [200, 206]:
22                with open(save_path, "wb") as f:
23                    async for chunk in response.aiter_bytes(chunk_size=8192):
24                        f.write(chunk)
25                return True
26    return False

画像ダウンロード

小红书の画像にも防盗鏈があります:

python
1async def download_xiaohongshu_image(image_url: str, save_path: str) -> bool:
2    """下载小红书图片"""
3    headers = {
4        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
5        "Referer": "https://www.xiaohongshu.com/",
6        "Accept": "image/avif,image/webp,image/apng,image/*,*/*;q=0.8",
7    }
8
9    async with httpx.AsyncClient(follow_redirects=True) as client:
10        response = await client.get(image_url, headers=headers)
11        if response.status_code == 200:
12            with open(save_path, "wb") as f:
13                f.write(response.content)
14            return True
15    return False

注意事項

  1. Referer が厳格: xiaohongshu.com の Referer を必ず付与する
  2. CDN ノード: bd (百度云)、hw (華為云) などの異なるノード
  3. 透かしなし: API が返すリンクは通常透かしなしです

微博 (Weibo)

動画リンクの特徴

微博の動画リンク形式は複数あります:

txt
1# 标准视频
2https://f.video.weibocdn.com/xxx.mp4
3
4# 直播回放
5https://live.video.weibocdn.com/xxx.flv
6
7# 高清视频
8https://video.weibo.com/media/play?fid=xxx

ダウンロード要件

リクエストヘッダー必須か
Referer必須https://weibo.com/ または https://m.weibo.cn/
User-Agent推奨ブラウザ UA
Cookie一部必要非公開動画で必要

サーバー側ダウンロード例

python
1import httpx
2
3async def download_weibo_video(video_url: str, save_path: str) -> bool:
4    """
5    下载微博视频
6
7    微博支持多个 Referer 域名
8    """
9    headers = {
10        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
11        "Referer": "https://weibo.com/",  # 或 https://m.weibo.cn/
12        "Accept": "*/*",
13        "Accept-Encoding": "identity",
14    }
15
16    async with httpx.AsyncClient(follow_redirects=True, timeout=60) as client:
17        async with client.stream("GET", video_url, headers=headers) as response:
18            if response.status_code in [200, 206]:
19                with open(save_path, "wb") as f:
20                    async for chunk in response.aiter_bytes(chunk_size=8192):
21                        f.write(chunk)
22                return True
23    return False

複数画質の選択

微博の動画は通常、複数の画質を提供します:

python
1def select_best_quality(media_info: dict) -> str:
2    """选择最高清晰度的视频链接"""
3    # 清晰度优先级
4    quality_priority = ["mp4_720p_mp4", "mp4_hd_mp4", "mp4_ld_mp4"]
5
6    playback_list = media_info.get("playback_list", [])
7
8    for quality in quality_priority:
9        for item in playback_list:
10            if item.get("quality_label") == quality:
11                return item.get("play_info", {}).get("url")
12
13    # 降级使用 stream_url
14    return media_info.get("stream_url")

注意事項

  1. Referer ドメイン: weibo.comm.weibo.cn をサポート
  2. 複数画質: 返却データに複数の画質候補がある
  3. リンクの有効期限: 一部のリンクには有効期限制限がある

YouTube

動画リンクの特徴

YouTube の動画リンクには通常、以下のような形式があります:

txt
1# 标准视频流地址
2https://rr1---sn-xxx.googlevideo.com/videoplayback?expire=xxx&ei=xxx&ip=xxx&id=xxx&itag=xxx&source=youtube&...
3
4# 自适应流地址 (DASH)
5https://manifest.googlevideo.com/api/manifest/dash/...
6
7# 直播流地址 (HLS)
8https://manifest.googlevideo.com/api/manifest/hls_variant/...

ダウンロード要件

厳格な IP 制限: YouTube の動画ストリームアドレスは IP の地理的位置に対して極めて厳格な検証を行い、米国カリフォルニア州ロサンゼルス地域の IP を使用しないとダウンロードに成功できません。そうでない場合は 403 Forbidden エラーが返されます。

リクエストヘッダー必須か
User-Agent必須ブラウザ UA
Referer推奨https://www.youtube.com/
Origin推奨https://www.youtube.com
プロキシ IP必須米国カリフォルニア州ロサンゼルスの IP

IP 地域制限の説明

YouTube の動画ストリームアドレスは生成時にリクエスト元の IP アドレスに紐づけられ、ダウンロード時には同じ地域の IP を使用する必要があります:

txt
1# 视频流 URL 中包含 IP 绑定参数
2https://rr1---sn-xxx.googlevideo.com/videoplayback?
3    expire=1234567890        # 过期时间
4    &ei=xxx                  # 加密标识
5    &ip=1.2.3.4             # 绑定的 IP 地址 (关键!)
6    &id=xxx
7    &itag=137               # 视频质量标识
8    &source=youtube
9    &...

なぜロサンゼルスの IP でなければならないのか?

  1. YouTube の大部分の CDN ノードは米国西海岸にある
  2. 動画ストリーム URL は生成時にリクエスト IP に基づいて最寄りの CDN を選択する
  3. ダウンロード時に IP 地域が一致しないと 403 エラーになる
  4. ロサンゼルスは YouTube の主要データセンター所在地であり、互換性が最も高い

サーバー側ダウンロード例

python
1import httpx
2
3async def download_youtube_video(
4    video_url: str,
5    save_path: str,
6    proxy: str = None  # 必须是美国加州洛杉矶代理
7) -> bool:
8    """
9    下载 YouTube 视频
10
11    重要:
12    - 必须使用美国加利福尼亚州洛杉矶地区的代理 IP
13    - 其他地区 IP 会返回 403 Forbidden
14    - 视频流 URL 有时效性,通常 6 小时内有效
15    """
16    headers = {
17        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36",
18        "Referer": "https://www.youtube.com/",
19        "Origin": "https://www.youtube.com",
20        "Accept": "*/*",
21        "Accept-Language": "en-US,en;q=0.9",
22        "Accept-Encoding": "identity",  # 避免压缩
23        "Range": "bytes=0-",  # 支持断点续传
24        "Sec-Fetch-Dest": "video",
25        "Sec-Fetch-Mode": "no-cors",
26        "Sec-Fetch-Site": "cross-site",
27    }
28
29    # 代理配置 - 必须是洛杉矶 IP
30    proxies = None
31    if proxy:
32        proxies = {
33            "http://": proxy,
34            "https://": proxy,
35        }
36
37    async with httpx.AsyncClient(
38        follow_redirects=True,
39        timeout=120,
40        proxies=proxies
41    ) as client:
42        async with client.stream("GET", video_url, headers=headers) as response:
43            if response.status_code in [200, 206]:
44                with open(save_path, "wb") as f:
45                    async for chunk in response.aiter_bytes(chunk_size=8192):
46                        f.write(chunk)
47                return True
48            elif response.status_code == 403:
49                print("下载失败: IP 地区不符合要求,请使用美国加州洛杉矶的代理")
50            elif response.status_code == 410:
51                print("下载失败: 视频链接已过期,请重新获取")
52    return False

音声と動画の分離処理

YouTube の高画質動画 (1080p+) は DASH 形式を採用しており、音声と動画が分離されています:

python
1import subprocess
2from pathlib import Path
3
4async def download_youtube_video_with_audio(
5    video_url: str,
6    audio_url: str,
7    save_path: str,
8    proxy: str = None
9) -> bool:
10    """
11    下载 YouTube 视频并合并音频
12
13    YouTube 1080p 及以上清晰度的视频,音频和视频是分离的
14    需要分别下载后使用 FFmpeg 合并
15    """
16    video_temp = save_path + ".video.mp4"
17    audio_temp = save_path + ".audio.m4a"
18
19    # 下载视频流
20    success = await download_youtube_video(video_url, video_temp, proxy)
21    if not success:
22        return False
23
24    # 下载音频流
25    success = await download_youtube_video(audio_url, audio_temp, proxy)
26    if not success:
27        return False
28
29    # 使用 FFmpeg 合并
30    try:
31        subprocess.run([
32            "ffmpeg", "-y",
33            "-i", video_temp,
34            "-i", audio_temp,
35            "-c:v", "copy",
36            "-c:a", "aac",
37            save_path
38        ], check=True, capture_output=True)
39
40        # 删除临时文件
41        Path(video_temp).unlink()
42        Path(audio_temp).unlink()
43        return True
44    except subprocess.CalledProcessError as e:
45        print(f"FFmpeg 合并失败: {e}")
46        return False

プロキシ設定例

python
1# 推荐的代理配置 - 必须是洛杉矶地区
2LA_PROXIES = [
3    "http://user:pass@la-proxy1.example.com:8080",  # 洛杉矶代理 1
4    "http://user:pass@la-proxy2.example.com:8080",  # 洛杉矶代理 2
5    "socks5://user:pass@la-socks.example.com:1080", # SOCKS5 代理
6]
7
8# 验证代理 IP 是否在洛杉矶
9async def verify_proxy_location(proxy: str) -> bool:
10    """验证代理 IP 是否在洛杉矶地区"""
11    async with httpx.AsyncClient(proxies={"https://": proxy}) as client:
12        response = await client.get("https://ipapi.co/json/")
13        data = response.json()
14
15        city = data.get("city", "")
16        region = data.get("region", "")
17        country = data.get("country_code", "")
18
19        # 检查是否在加州洛杉矶
20        is_la = (
21            country == "US" and
22            region == "California" and
23            "Los Angeles" in city
24        )
25
26        if is_la:
27            print(f"✓ 代理 IP 位于: {city}, {region}, {country}")
28        else:
29            print(f"✗ 代理 IP 位于: {city}, {region}, {country} (不符合要求)")
30
31        return is_la

画質識別 (itag) 対照表

itag解像度形式音声を含むか
18360pMP4はい
22720pMP4はい
1371080pMP4いいえ (結合が必要)
2481080pWebMいいえ (結合が必要)
2711440pWebMいいえ (結合が必要)
3132160pWebMいいえ (結合が必要)
140-M4A 音声音声のみ
251-WebM 音声音声のみ

注意事項

  1. IP 制限が非常に厳しい: 米国カリフォルニア州ロサンゼルスの IP を使用する必要があり、他地域 (米国の他州を含む) では失敗する可能性がある
  2. リンクの有効期限: 動画ストリーム URL は通常 6 時間 以内有効
  3. 音声と動画の分離: 720p 以上の画質では音声と動画を別々にダウンロードしてから結合する必要がある
  4. 速度制限: YouTube はダウンロード速度に制限があるため、大容量ファイルは分割ダウンロードを推奨
  5. 著作権保護: 一部の動画には DRM 保護があり、直接ダウンロードできない

フロントエンドダウンロード方案

CORS 制限のため、フロントエンドから大部分のプラットフォームの動画を直接ダウンロードすることはできません。以下が実行可能な方案です:

方案一:バックエンドプロキシ(推奨)

javascript
1// 前端请求后端代理接口
2async function downloadVideo(videoUrl, platform, filename) {
3  const proxyUrl = `/api/download/video?url=${encodeURIComponent(videoUrl)}&platform=${platform}`;
4
5  const response = await fetch(proxyUrl);
6  const blob = await response.blob();
7
8  // 创建下载链接
9  const url = URL.createObjectURL(blob);
10  const a = document.createElement('a');
11  a.href = url;
12  a.download = filename || 'video.mp4';
13  document.body.appendChild(a);
14  a.click();
15  document.body.removeChild(a);
16  URL.revokeObjectURL(url);
17}

方案二:新しいウィンドウで開く(対応するプラットフォームのみ)

javascript
1// 部分平台链接可以直接在新窗口打开下载
2function openVideoInNewTab(videoUrl) {
3  window.open(videoUrl, '_blank');
4}

方案三:download 属性を使用する(同一オリジン環境)

html
1<!-- 仅适用于同源或允许 CORS 的资源 -->
2<a href="video.mp4" download="video.mp4">下载视频</a>

バックエンドプロキシダウンロード方案

FastAPI プロキシ例

python
1from fastapi import FastAPI, Query, Response
2from fastapi.responses import StreamingResponse
3import httpx
4
5app = FastAPI()
6
7# 各平台的请求头配置
8PLATFORM_HEADERS = {
9    "douyin": {
10        "Referer": "https://www.douyin.com/",
11        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
12    },
13    "tiktok": {
14        "Referer": "https://www.tiktok.com/",
15        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
16    },
17    "bilibili": {
18        "Referer": "https://www.bilibili.com/",
19        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
20    },
21    "xiaohongshu": {
22        "Referer": "https://www.xiaohongshu.com/",
23        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
24    },
25    "weibo": {
26        "Referer": "https://weibo.com/",
27        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
28    },
29}
30
31
32@app.get("/api/download/video")
33async def proxy_video(
34    url: str = Query(..., description="视频 URL"),
35    platform: str = Query(..., description="平台标识"),
36):
37    """
38    视频代理下载接口
39
40    解决前端跨域和防盗链问题
41    """
42    headers = PLATFORM_HEADERS.get(platform, {})
43
44    async def video_stream():
45        async with httpx.AsyncClient(follow_redirects=True, timeout=120) as client:
46            async with client.stream("GET", url, headers=headers) as response:
47                async for chunk in response.aiter_bytes(chunk_size=8192):
48                    yield chunk
49
50    return StreamingResponse(
51        video_stream(),
52        media_type="video/mp4",
53        headers={
54            "Content-Disposition": "attachment; filename=video.mp4",
55            "Access-Control-Allow-Origin": "*",  # 允许跨域
56        }
57    )
58
59
60@app.get("/api/download/image")
61async def proxy_image(
62    url: str = Query(..., description="图片 URL"),
63    platform: str = Query(..., description="平台标识"),
64):
65    """图片代理下载接口"""
66    headers = PLATFORM_HEADERS.get(platform, {})
67
68    async with httpx.AsyncClient(follow_redirects=True) as client:
69        response = await client.get(url, headers=headers)
70
71        return Response(
72            content=response.content,
73            media_type=response.headers.get("content-type", "image/jpeg"),
74            headers={
75                "Access-Control-Allow-Origin": "*",
76            }
77        )

進捗付きダウンロード例

python
1import httpx
2from tqdm import tqdm
3
4async def download_with_progress(url: str, save_path: str, headers: dict) -> bool:
5    """带进度条的下载"""
6    async with httpx.AsyncClient(follow_redirects=True, timeout=120) as client:
7        async with client.stream("GET", url, headers=headers) as response:
8            total = int(response.headers.get("content-length", 0))
9
10            with open(save_path, "wb") as f:
11                with tqdm(total=total, unit="B", unit_scale=True, desc="下载中") as pbar:
12                    async for chunk in response.aiter_bytes(chunk_size=8192):
13                        f.write(chunk)
14                        pbar.update(len(chunk))
15
16            return True
17    return False

まとめ

各プラットフォームのダウンロード要点早見表

プラットフォームRefererCookie 要件特殊処理リンク有効期限
抖音https://www.douyin.com/任意なし24 時間
TikTok Webhttps://www.tiktok.com/必須 tt_chain_token地域プロキシが必要1-6 時間
TikTok App不要不要使用推奨長い
B站https://www.bilibili.com/高画質では SESSDATA 必須音声と動画の分離は結合が必要2 時間
小红书https://www.xiaohongshu.com/任意なし長い
微博https://weibo.com/一部必要複数画質長い
YouTubehttps://www.youtube.com/不要ロサンゼルス IP 必須 + 音声と動画の分離6 時間

よくあるエラーの切り分け

エラーコード可能な原因解決策
403 ForbiddenReferer の誤りまたは欠落Referer ヘッダーを確認する
403 ForbiddenTikTok で tt_chain_token が不足Cookie を追加するか App 端リンクを使用する
403 ForbiddenYouTube の IP 地域不一致米国カリフォルニア州ロサンゼルスのプロキシを使用する
404 Not Foundリンク切れリンクを再取得する
410 GoneYouTube リンク切れ動画ストリーム URL を再取得する
CORS Errorブラウザのクロスオリジン制限バックエンドプロキシを使用する
タイムアウトネットワーク問題またはファイルが大きすぎるタイムアウト時間を延長し、分割ダウンロードする

ベストプラクティス

  1. 常に Referer を設定する: これは大部分のプラットフォームで必要条件です
  2. バックエンドプロキシを使用する: フロントエンドの CORS 問題を解決する最善策です
  3. リンクの有効期限に対応する: 速やかにリンクを使用し、期限切れなら再取得する
  4. 断点継続ダウンロードをサポートする: 大容量ファイルは Range ヘッダーで分割ダウンロードする
  5. エラー再試行: ネットワークが不安定な場合は再試行機構を実装する

お問い合わせ

本文書の案内に従って操作しても動画を正常にダウンロードできない場合は、カスタマーサポートまでお問い合わせください:

カスタマーサポートに連絡する際は、より迅速に支援できるよう以下の情報をご提供ください:

  1. プラットフォーム名: 抖音/TikTok/B站/小红书/微博/YouTube
  2. 動画リンク: 元の動画ページ URL
  3. エラー情報: 完全なエラーコードとエラー説明
  4. リクエストヘッダー設定: 使用している Referer、Cookie などの情報
  5. プロキシ情報: プロキシを使用している場合は、プロキシ地域を提供してください

この記事は気に入りましたか?

友達や同僚と共有しましょう!

Default
Last updated: May 15, 2026
相关文章
正在检查服务状态...
多平台视频链接下载指南 - TikHub.io