
PigeonPod 干的事很直接:把 B 站 UP 主和 YouTube 频道变成私人播客电台。视频一更新它就自动下载、抽成音频、生成标准播客 RSS,苹果播客和小宇宙都能直接订阅,新单集自己冒出来。
地铁挤得抬不起手,开车更不敢瞄屏幕。老番茄一口气更新了三期,等周末有空看,热度早过了。每天通勤来回一小时的人,对这个时刻太熟了。想追的 UP 主越攒越多,眼睛却只有一双。刷视频的时间挤不出来,听音频的时间一抓一大把。
一个自托管小服务,订阅 B 站 UP 主后自动下载转音频,生成标准播客 RSS,苹果播客、小宇宙都能直接订。
代价先说清:得有一台一直开机的服务器或 NAS;B 站源还要上传一次登录 Cookie,缺了一集都下不下来。两条都占的人往下看。只有手机没机器的,转给家里有 NAS 的那个朋友就行。
视频进,播客出,它只干这一件事
PigeonPod 是跑在自己机器上的服务器,GitHub 上 1193 星。订阅一个 UP 主,它就盯着更新,新视频一出就下载、转音频,再喂出一条标准播客源。
全家手机的播客 App 都能订这条源。开车、跑步、洗碗的时候,UP 主的视频变成耳朵里的电台。「全部单集」源还能把所有订阅合成一个流,一个入口听全部更新。
它只认 B 站和 YouTube 两类源,现成的播客 RSS 订不进来。视频转播客归它管,现成播客的订阅不归它管。
多用户和角色权限也做了,家里一人一个账号,各订各的 UP 主互不干扰。关键词、时长、直播回放的过滤在订阅时就设好,水视频和回放直接不进列表。单集能生成分享页,链接甩进群里,朋友不用装任何东西点开就听。想折腾的还有 OPML 导出、Webhook 和邮件通知、S3 存储、WebDAV,都躺在设置页里。
装起来就一个 compose 文件
部署只需要一个 docker-compose.yml,镜像 684MB。冷启动 27 秒。跑起来内存 270MB 上下,数据用 SQLite 存,不用再拖一个数据库容器。所有数据全在 ./data 目录里,备份就拷这一个文件夹。
services:
pigeon-pod:
image: 'ghcr.io/aizhimou/pigeon-pod:latest'
restart: unless-stopped
container_name: pigeon-pod
ports:
- '8834:8080'
environment:
- SPRING_DATASOURCE_URL=jdbc:sqlite:/data/pigeon-pod.db
- TZ=Asia/Shanghai
volumes:
- ./data:/data
起来后跑一句 docker logs pigeon-pod | grep -i password,日志里躺着 root 的随机密码。浏览器打开 http://服务器IP:8834 登录,界面右上角一键切中文。
想让外网的手机也能听,拿反代套一层 HTTPS 就行,设置里有对应选项。
仪表盘长这样:等待中、下载中、已下载、已失败四张统计卡,顶上是订阅输入框,底下是订阅源卡片。

订阅老番茄,全程点不了几下
把老番茄的频道链接粘进订阅框,确认。订阅时能顺手设几件事:自动下载最近几集、新视频延迟多久再下、只存音频还是连视频一起下。频道页很快拉出单集列表,封面、时长、下载状态排得清清楚楚,哪集成了哪集败了一眼能看出来。

想拿播客地址,先去设置页把 Base URL 填成 http://服务器IP:8834,不填直接报「base-url is empty」。填完回到订阅源点 RSS 按钮,弹窗里就是一条带 apikey 的 XML 地址,这条链接别往外乱发。

这条地址丢进苹果播客或小宇宙的「添加播客」就完事。以后 UP 主一更新,播客 App 里自动出现新单集。通勤路上点开就听,只走音频流量,比开着视频省得多。
订阅之后基本不用回后台。它定时去翻 UP 主的更新,新视频出来自动排队、下载、转码进库,全程不用人盯着。转出来的是 AAC 音频,封面嵌在文件里,播客 App 里显示的就是 UP 主头像。失败的单集它自己重试,成了自动上架。音质默认档通勤足够,耳朵挑的去订阅默认配置里调高。
这四个坑,先知道再动手
坑一:B 站不配 Cookie,一集都下不下来。 订阅能成功,单集列表也拉得出来,一到下载就报 HTTP Error 403,连试 6 集全灭。怪就怪在预览模式明明拿得到音频流,真下载就被 403 拍回来。B 站的风控拦在数据流环节,没登录拿不到流。解法在设置页的 Cookie 管理:上传 Netscape 格式的 Bilibili cookies.txt。官方 README 也明说,Cookie 就是给受限内容更稳下载用的。拿主号上传有被临时限制的风险,官方建议用小号。

坑二:默认开字幕下载,满屏警告带偏排查方向。 初始化配置里字幕语言默认填了中文和英文,没登录去抓 B 站字幕必然刷警告,日志一眼望过去全是「Subtitles are only available when logged in」。真正卡死下载的是 403,跟这些警告没关系,顺着警告去查只会白耗时间。不用字幕的,去订阅默认配置里把字幕语言清空,日志立刻清净。

坑三:失败的单集不能手动重下。 下载失败会自动重试,间隔从 30 分钟起步往上递增,4 次还不成就彻底躺平。FAILED 状态的单集点「重试」,它只会排进下一轮自动计划,不会立刻重下,报错原文是「Only READY episodes can be manually downloaded」。急也没用,只能等自动重试点,批量重下也得跟着自动计划一起跑。
坑四:YouTube 源是另一套门槛。 订 YouTube 频道得先去 Google Cloud 拿一个 API key,不配直接报「YouTube API key is not set」。国内网络还得在设置页挂代理。和 B 站正好反过来:YouTube 要 key 不要 Cookie,B 站要 Cookie 不要 key,两头都得备齐才算通吃。

跟同类摆在一起看
| 项目 |
星数 |
差异 |
该选谁 |
| PigeonPod |
1193 |
B 站+YouTube 转播客 RSS |
要听 B 站的人 |
| Pinchflat |
5404 |
只做 YouTube,轻量 |
只看 YouTube 的人 |
| Tube Archivist |
8517 |
视频库管理,要 ES |
囤视频的人 |
| yt-dlp |
无 |
命令行,无 RSS |
爱敲命令的人 |
yt-dlp 是这行的老祖宗,免费又强,但纯命令行,没界面没 RSS,得自己写脚本定时跑。Pinchflat 专做 YouTube,Docker 一起就完事,可惜不认 B 站。Tube Archivist 是囤视频的路子,要拖一个 Elasticsearch 起来,跟「只想听」的人走两条路。
立场给清楚:想听 B 站 UP 主,PigeonPod 是目前唯一原生同时吃 B 站和 YouTube、还能吐标准播客 RSS 的自托管项目,没有平替。只看 YouTube 的选 Pinchflat,更轻更省心。真想把视频囤成媒体库的,再考虑 Tube Archivist。
短处也摆上台面:PigeonPod 星数最少,社区小文档少,出问题多半得自己翻日志。Java 应用跑起来 270MB 内存,比 Go 写的同类重一截。在意的自己掂量。
今天就能做的三步
- 在一直开机的服务器上跑起上面那份 compose,登录后台改掉默认密码。
- 设置页填好 Base URL,上传 B 站小号的
cookies.txt。
- 粘一个常看的 UP 主频道链接,把 RSS 地址加进手机播客 App。
什么人值得装:手里有台常开机的服务器或 NAS,平时有听播客的习惯,关注的 UP 主以聊天、讲故事这类「听也行」的内容为主。纯看画面操作的教学类视频,转成音频就少了一半信息,别勉强。
值不值,看平时听不听 B 站。天天拿 UP 主视频当背景音的,这套东西值得花半小时部署,装一次后面全自动;只看从来不听的,划走就行。
身边有每天开车通勤、拿 B 站视频当背景音听的家人的,可以把这篇转过去,堵车路上能多听两期更新。想找更多自托管玩法或者跟同好聊聊折腾经验,云栈社区 是个不错的去处。
参考资料