用Cloudflare R2做图/音视频床并完成大小文件自动分流Github/R2
用Cloudflare R2做图/音视频床并完成大小文件自动分流Github/R2
已经有了Github用 jsDelivr/CDN 访问的图床(PicList本地端自动上传,样式为https://cdn.jsdelivr.net/gh/用户名/仓库名@分支/路径/文件.jpg),允许上传图片以外的文件,只是不能上传大文件(大概不超过20M),所以大一点的音视频文件就无法使用这个图床了。免费的音视频床试了几个,都不太稳定,于是找到了CloudFlare R2。
✅ 优点:
- ✅ 无大小限制
- ✅ CDN 全球加速
- ✅ 可以绑定域名
- ✅ 完全替代图床
根据社区和账单说明:
👉 R2 是按 billing cycle(账单周期)重置
👉 通常是 从你启用/订阅 R2 那天开始算约30天周期 [community…dflare.com]
✅ 在这个周期内
你能用:
1 | 10GB 存储(GB-month) |
👉 每个周期重置 ✅
🔍 ✅ 在哪里可以查看你的周期
👉 Cloudflare 控制台:
1 | R2 → Usage / Billing |
或:
1 | Billing → R2 使用记录 |
👉 你会看到:
1 | 当前周期用量 |
🎯 ✅ 核心结论
✅ 删除文件会减少“后续占用” ❗但 不会完全消除当前周期已经产生的用量
🧠 ✅ 为什么会这样(理解GB‑month)
Cloudflare R2 不是按“存不存在”算的,而是:
✅ 按“存了多久 × 存了多少”算(平均值)
官方说明:
“Storage is calculated by averaging usage over the billing period (30 days)” [cloudcredits.io]
📊 ✅ 举例(非常重要)
🎯 情况1:你上传又立刻删除
1 | 上传 1GB 文件 |
👉 实际计费:
1 | 1GB × (1 / 30) = 0.033 GB-month ✅ |
👉 ✅ 结论:
❗ 还是占了一点额度(但很少)
🎯 情况2:放了 15 天再删
1 | 1GB × (15 / 30) = 0.5 GB-month ✅ |
👉 ✅ 占用一半额度
🎯 情况3:放满30天
1 | 1GB × (30 / 30) = 1 GB-month ✅ |
👉 ✅ 才算完整1GB
✅ ✅ ✅ 回答你问题(非常直接)
❓ 删除掉就不再占用同周期限额?
👉 答案分两部分:
✅ ✅ 1️⃣ 之后不会再增长 ✅
删除后:
1 | ✅ 不再继续增加用量 |
❌ ❌ 2️⃣ 已经产生的不会清零 ❌
删除前的:
1 | 已累计的 GB‑month ❌ |
🎯 ✅ 一句话总结(最关键)
✅ 删除可以“止损”
❌ 但不能“回档”
🧠 ✅ 对你实际使用的意义(非常实用)
✅ ✅ 场景1:上传测试文件
👉 ✅ 建议:
1 | 测试完立刻删除 ✅ |
👉 ✅ 成本几乎为0
✅ ✅ 场景2:大视频
👉 ✅ 建议:
1 | 短期用 → 删除 |
✅ ✅ 场景3:博客资源
👉 最佳做法:
1 | 稳定内容 → 长期存 ✅ |
🚀 ✅ 高级优化(你可以用)
✅ 技巧1:利用“后半周期上传”
比如:
1 | 周期第25天上传 |
👉 只计算:
1 | 5 / 30 ≈ 0.16 GB ✅ |
👉 ✅ 更省额度
✅ 技巧2:大文件分批上传
避免:
1 | 同一天突然爆量 ❌ |
⚠️ ✅ 一个很多人不知道的坑
❗ 即使删除:
1 | 请求次数(Class A/B) |
👉 ❌ 不会回滚
🏁 ✅ 最终总结
✅ 删除文件后:
✔ 后续不再占用
✖ 已产生的额度不会消失👉 本质:
R2 是“时间加权计费”,不是“是否存在计费”
所以最好大文件还是压缩一下:
🎧 1. 上传前压缩音频
用 FFmpeg:
1 | ffmpeg -i input.wav -b:a 128k output.mp3 |
👉 效果:
| 文件 | 大小 |
|---|---|
| 原始 WAV | 200MB |
| 压缩 MP3 | ~15MB ✅ |
✅ 换更高压缩格式(推荐)
👉 用 AAC:
ffmpeg -i input.wav -c:a aac -b:a 64k output.m4a
👉 或 Opus(更猛):
ffmpeg -i input.wav -c:a libopus -b:a 48k output.opus
✅ 同质量更小体积 ✅
✅ 六、极限压缩(播客/语音)
ffmpeg -i input.wav -ac 1 -ar 16000 -c:a libopus -b:a 32k output.opus
👉 结果:
体积极小 ✅
语音依然清晰 ✅
🎬 2. 视频压缩
1 | ffmpeg -i input.mp4 -vcodec h264 -crf 28 output.mp4 |
步骤 1:创建 R2 存储桶
1️⃣ 登录 Cloudflare
👉 https://dash.cloudflare.com/
2️⃣ 进入 R2
左侧:
1 | R2 Object Storage → Overview |
3️⃣ 创建桶
填:
1 | Create a bucket |
页面里有 4 个可配置项:
- Bucket name
- Location
- Storage Class
- Create bucket 按钮
✅ ✅ 一项一项填(照做就行)
✅ ① Bucket name(非常重要)
👉 在输入框填写:
1 | media |
✅ 说明:
- ✅ 简单、通用(以后好管理)
- ✅ URL 也更干净
- ❗ 不能改(创建后永久固定)
👉 如果提示已存在,可以换:
1 | media-files |
✅ ② Location(不用动 ✅)
你现在是:
1 | Automatic ✅(已选中) |
👉 保持这个就行 ✅
✅ 为什么?
- Cloudflare 会自动选择最佳位置
- 不影响访问速度(后面用 CDN)
✅ ③ Storage Class(不要改 ✅)
你现在是:
1 | Standard ✅(已选中) |
👉 保持这个 ✅
❗ 不选 Infrequent Access
因为:
- 音频会被访问(播放)
- Infrequent 反而更贵(读取收费更高)
✅ ④ 直接创建
👉 点击右下角:
1 | Create bucket |
🚨 一个你可能注意到的点
页面底部写着:
1 | By default buckets are not publicly accessible |
👉 ✅ 不用管它!
因为:
👉 我们后面用 Worker 来“公开访问”
👉 这是正确做法(也更安全)
✅ 完成
✅ 三、步骤 2:开启公开访问
进入你的 bucket:
👉 Settings → 打开:
1 | ✅ Allow Access (Public) |
⚠️ 默认 URL 会给你一个类似:
1 | https://<account_id>.r2.cloudflarestorage.com/media/test.mp3 |
但这个我们不用(不好看)
✅ 四、步骤 3:创建 Worker(核心)
1️⃣ 新建 Worker
左侧:
1 | Compute → Workers & Pages → Create Worker |
点:
1 | Start from scratch |
2️⃣ 替换代码(直接用)
把默认代码删掉,换成👇这个:
1 | export default { |
3️⃣ 绑定 R2
👉 在 Worker 页面:
1 | Settings → Bindings → Add binding |
类型选(先点Add后在右侧界面弹出选项):
1 | R2 bucket |
填:
1 | Variable name: MY_BUCKET |
✅ 保存
✅ ✅ 操作步骤(照点)
✅ 第一步
👉 点击:
1 | Add a binding |
(就在你截图右侧那一块)
✅ 第二步(填写)
会弹出一个配置窗口,按下面填👇
✅ 类型:
选择:
1 | R2 bucket |
✅ Variable name:
填:
1 | MY_BUCKET |
(必须完全一样,不要改)
✅ Bucket:
选择你刚才创建的:
1 | media |
👉 然后点击:
1 | Save / Add binding |
✅ 五、步骤 4:绑定域名(变“图床”关键)
1️⃣ 添加自定义域
Worker → Domains
点:
1 | Add Custom Domain |
填:
1 | cdn.yoursite.com |
👉 Cloudflare 会自动帮你配置 DNS ✅
✅ 完成后访问示例
1 | https://cdn.yoursite.com/audio/test.mp3 |
✅ 六、步骤 5:上传文件
你现在有三种上传方式👇
✅ 方法1:网页上传(最简单)
R2 → Bucket → Upload
直接拖文件 ✅
✅ 方法2:API(推荐长期)
生成:
1 | R2 API Token |
用工具比如:
- rclone
- aws-cli
✅ 方法3:PicGo(进阶)
你可以接入:
👉 picgo-plugin-s3
配置为:
1 | endpoint: https://<account_id>.r2.cloudflarestorage.com |
✅ 七、文件访问规则
假设你上传:
1 | audio/test.mp3 |
访问就是:
1 | https://cdn.yoursite.com/audio/test.mp3 |
✅ 八、推荐目录结构(很重要)
1 | media/ |
👉 以后你就是一个“全能资源床”
🚀 1. 增加防盗链(Worker改造)
可以限制:
1 | if (!request.headers.get("Referer")) { |
🚀 3. CDN缓存优化
你已设置:
1 | Cache-Control: 31536000 |
👉 会极快 ✅
✅ 🎧 最后一步:测试访问
假设你上传的是:
1 | test.mp3 |
访问:
1 | https://cdn.yoursite.com/test.mp3 |
✅ 成功的话:
👉 浏览器直接播放 ✅
👉 这就是你的“音频直链” ✅
✅ 🧠 先搞清概念(非常重要)
你看到的:
1 | S3 API |
👉 ✅ 就是我们需要的东西(访问 R2 的 API)
但注意👇
❗它 ≠ Cloudflare普通的 API Tokens
✅ 它是 R2 专用的 Access Key / Secret Key
✅ ✅ 你要创建的是这两个
真正需要的是:
1 | Access Key ID |
👉 类似 AWS S3 那一套
✅ ✅ 正确创建步骤(一步一步)
请按这个路径走👇
✅ 第一步:进入 S3 API 页面
你现在已经找到了这个入口 ✅
通常路径:
1 | R2 → S3 API |
✅ 第二步:点击创建按钮
你会看到类似按钮:
1 | Create API Token |
👉 点击 ✅
✅ 第三步:选择权限(很关键)
会让你选:
1 | Permissions |
👉 选择:
1 | Admin Read & Write ✅(推荐) |
✅ 这样你能:
- ✅ 上传文件
- ✅ 读取文件
- ✅ 删除文件
✅ 第四步:绑定 bucket
选择:
1 | media |
(你刚创建的)
✅ 第五步:创建
👉 点击:
1 | Create |
✅ ✅ 创建完成后你会得到👇
⚠️ 这一页非常重要(只显示一次!)
你会看到:
1 | Access Key ID: xxxxxxxxx |
✅ 必须马上保存!
👉 建议:
- 复制到记事本
- 或截图保存
❗ 注意:
Secret Key 丢了就找不回,只能重新生成
👉 你现在在 bucket 的 Settings 页面(对)
👉 但这里只提供 endpoint,不是创建 key 的地方(很多人卡这里)
✅ 🚨 结论先说
👉 你现在看到的这个:
1 | S3 API: |
✅ 这是 Endpoint(地址)
❌ 不是 Access Key / Secret Key 的创建入口
✅ ✅ 正确创建 Key 的入口
👉 不在这个页面!!!
请你这样走 👇
✅ ✅ 第一步:回到 R2 主页面
左侧菜单:
1 | Storage & databases → R2 Object Storage |
👉 回到 Overview 页面
✅ ✅ 第二步:找这个入口(关键)
在页面里找:
1 | S3 API |
👉 或右上角 / 页面中间会有:
1 | Manage R2 API Tokens |
📌 如果你没看到:
👉 直接看左侧👇
1 | R2 Object Storage |
👉 在 Overview 页面中会有 S3 API 区域
✅ ✅ 第三步:创建 Key
点击:
1 | Create API Token / Create Access Key |
✅ ✅ 第四步:填写
一般会让你选👇
✅ 权限(Permissions)
选择:
1 | Admin Read & Write ✅(推荐) |
✅ Bucket 绑定
选择:
1 | media |
✅ ✅ 第五步:创建
点击:
1 | Create |
✅ ✅ 关键结果(最重要)
创建后你会看到👇(只出现一次):
1 | Access Key ID: xxxxxxxxx |
🚨 ⚠️ 必须立刻保存
👉 复制下来!
因为:
❗ Secret Key 不会再显示第二次
✅ ✅ 回头看你当前页面(解释一下)
你截图里的:
1 | S3 API: |
👉 这个是:
✅ Endpoint(PicGo要填)
✅ 用来访问 bucket
你现在在:
1 | R2 Object Storage → API Tokens 页面 ✅ |
并且看到两个选项:
1 | Account API Tokens |
✅ 🥇 正确选择是什么?
👉 选这个👇
1 | Create User API token ✅(点击它) |
❗ 为什么不能选 Account?
| 类型 | 推荐度 |
|---|---|
| Account API token | ❌ 不推荐(太大权限、复杂) |
| User API token | ✅ 推荐(简单、够用) |
✅ ✅ 下一步(点击后怎么填)
点 Create User API token 后,会进入配置页面
✅ 填写如下(照做就行)
✅ 权限(Permissions)
选择:
1 | Object Read & Write ✅ |
👉 如果没有这个选项,选:
1 | Admin Read & Write ✅ |
✅ Bucket 选择
会让你选:
1 | Specify bucket |
👉 选:
1 | media ✅ |
✅ 名字(随便)
例如:
1 | picgo |
✅ ✅ 创建成功后你会得到👇
⚠️ 这一页非常关键!!!
1 | Access Key ID: xxxxxxxxx |
✅ 必须马上保存!
👉 复制到记事本:
1 | AccessKeyId |
⚠️ 注意:
❗ Secret Key 只显示一次,丢了要重建
好了,现在已经成功将文件上传到R2并获取外链。接下来,我们要用Rclone工具实现对于上传文件的自动判别:大的音视频等文件直接上传R2,而其他原来的图片等文件还是分流到Github。
🧠 ✅ 目标效果(此部分自动分流实际上未能实现)
你在 Typora 里:
1 | 拖入一张图片 ✅ |
👉 自动变成:
1 | https://github-cdn/xxx.png |
Typora之前一直只走PicList到Github,配置如下:
✅ 🎯 现在要做的核心改造
你要把这里👇
1 | 上传服务:PicList ❌ |
👉 改成:
1 | Custom Command ✅ |
✅ ✅ 一步一步改
✅ 第一步:改上传服务类型
在你截图这一行:
1 | 上传服务:PicList |
👉 点击下拉框
👉 选择:
1 | Custom Command |
✅ 第二步:填写命令
会出现一个输入框,填👇
1 | C:\path\to\upload.cmd |
👉 替换成你自己的脚本路径,例如:
1 | C:\upload\upload.cmd |
✅ ✅ 第三步:准备 upload.cmd
👉 新建文件(很关键)
1 | upload.cmd |
内容👇(直接复制)
✅ ✅ ✅ Windows最终完整版脚本
1 | @echo off |
因为上述方法自动切换未能成功,于是退而求其次,原来Typora中的图片上传仍采用PicList直接上传至Github,而大的图片、音视频等都通过一个Python程序或封闭好的软件直接上传到R2(最好上传后可以直接生成Typora引用直链或粘贴)。
✅ ✅ ✅ Rclone配置方法
🥇✅ 步骤1
在终端执行:
1 | rclone config |
✅ 步骤2:新建
1 | n |
✅ 步骤3 填:
1 | name: r2 |
✅ 步骤4:
1 | Storage: s3 |
✅ 步骤5:
1 | provider: Cloudflare |
✅ 步骤6 填 key:
1 | access_key_id: (你的) |
✅ 步骤7(关键)
1 | endpoint: |
👉 必须填:
1 | https://你的accountid.r2.cloudflarestorage.com |
❌ 不带 /media
✅ 步骤8:
1 | region: auto |
测试(这一步必须成功)
rclone ls r2new:audio
👉 如果能列出其中文件(或为空) ✅ 说明成功
🚀 ✅ ✅ ✅ 最终完整Python代码(直接上传至R2,并返回剪贴版markdown版播放地址,可直接粘贴到Typora)
👉 直接复制替换使用
1 | import tkinter as tk |
✅ ✅ ✅ 网页不显示播放器的正确解决方案(标准写法)
你要改成👇这种 HTML标签
🥇 ✅ 音频(标准写法 ✅)
1 | <audio controls> |
✅ 效果(网页)
👉 ✅ 所有静态博客都会显示播放器
👉 ✅ 支持播放
🥈 ✅ 视频(标准写法)
1 | <video controls width="600"> |


