为什么要折腾这一步
我的短剧流水线分三段:IPloom 存剧本和提示词,文本交给 DeepSeek,画面交给 Muse,生产管理放在 ArcReel。DeepSeek 早就通过 Magpie(本机的模型网关,OpenAI 兼容)接好了,Muse 一直是单独开网页用。
目标很简单:所有模型都收进 Magpie 统一调度,下游工具只认一个地址。
先排除两条路
1. 现成的 magpie-muse-web 插件。 它确实存在,但只做文本进、文本出。它自己的 README 也写了:要图片和视频,去用 muse2api 加对应插件。
2. 社区的两个 Muse Code 插件。
magpie-muse-bridge:走官方 Muse Code SDK 和muse serve,接口是 Anthropic Messages。作者写明只用假上游测过,没用真实订阅账号测过。magpie-muse-direct:伪装成 Muse Code CLI,用公开的 OAuth client id 和伪造的请求头直连 Meta 接口。README 自己警告:大概率违反条款,账号或订阅可能被限制甚至封禁。
这两个都只管 Muse Code 的对话和工具调用,没有视频任务的提交、轮询、取回接口,满足不了 ArcReel 生视频的需求。我两个都没装。bridge 留作以后把 Muse 当 Agent 用时再评估,direct 不建议长期用。
还要澄清一个常见误解:按 Meta 文档,Muse Spark 能接收视频输入,但输出是文本,它本身不生成视频。生视频走的是 muse.ai 网页端的能力。
最终架构
链路就一条:muse.ai → muse2api(Docker)→ Magpie → 下游工具(封面图即架构图)。
- muse2api:用容器内的 Chromium 驱动 muse.ai 网页,维持登录态,对外提供 OpenAI 兼容的对话、图片、视频接口。端口 18610,模型
muse-spark、muse-image、muse-video。 - magpie-muse2api-plugin:Magpie 插件,provider id 是
muse2api,默认上游http://127.0.0.1:18610/v1。 - 插件会过滤掉媒体模型,Magpie 里只出现
muse2api/muse-spark。图片和视频不走 Magpie,直接调 muse2api 自己的异步任务接口。
部署:从原生改成 Docker
第一版是原生跑的:Python 虚拟环境加 macOS 的 LaunchAgent,监听 127.0.0.1:18610。能用,但我想要隔离、好迁移,于是改成 Docker。
compose 在上游基础上改了几处:只绑本机回环、restart 改为 unless-stopped、密钥放 .env、浏览器 profile 单独挂卷。
name: muse2api
services:
muse2api:
build:
context: ./source-<commit>
dockerfile: Dockerfile.local
image: local/muse2api:<commit>
container_name: muse2api
restart: unless-stopped
ports:
- "127.0.0.1:18610:18610" # 上游是 "18610:18610",会暴露到局域网
env_file: .env # MUSE2API_KEY=<你的 API Key>
volumes:
- ./data:/app/data
- profiles:/root/muse2api-profiles
shm_size: 2gb # Chromium 需要
volumes:
profiles:
上游镜像基于 python:3.11-slim-bookworm,装 Chromium、中文字体、curl、git,Python 依赖是 FastAPI、uvicorn、pydantic、requests、websocket-client。
切换脚本保证不中断:先停原生服务,再 compose up,检查 /v1/models 里有 muse-video、Chromium 起来了,成功就禁用原生的 LaunchAgent,失败就回滚。地址没变,Magpie 那边一行配置都不用改。
接入 Magpie
magpie plugin add <插件目录>
magpie plugin login muse2api
# 选 2:连接已有实例
# Base URL: http://localhost:18610/v1
# Key: <你的 API Key>
插件登录有 4 种方式:自动部署、连接已有实例、连接并导入账号、只填 key。我已经有实例,选 2。
我当时也问过:这个 API Key 从哪来? 它不是找 Meta 申请的,是你自己在 muse2api 的 .env 里设置的 MUSE2API_KEY,只用来保护本机这个服务。
导入 Muse 账号
muse.ai 的 4 个核心 Cookie 都是 httpOnly,网页脚本读不到。muse2api 给了两种办法:浏览器扩展(MV3,权限是 cookies、storage、activeTab),或者走 CDP 的取 Cookie 脚本。
我不想另开一个专用浏览器重新登录,就用扩展复用已登录的 Chrome:
- 复制一份官方扩展,把
host_permissions收窄到只允许 muse.ai 和 127.0.0.1,上游地址写死成本机实例。 - 打开
chrome://extensions,开启开发者模式,加载已解压的扩展。 - 打开已登录的 muse.ai,粘贴 API Key,点「读取并导入」。
结果:账号池 1 个账号,状态是已启用、临近到期,但可以用。muse2api 自带续期机制,会定期刷新。
实测
文本,已通过。 向 Magpie 的 /v1/chat/completions 发请求,模型选 muse2api/muse-spark,让它原样回一个随机串:
curl http://localhost:3425/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{"model":"muse2api/muse-spark",
"messages":[{"role":"user","content":"只回复:<随机串>"}]}'
返回 HTTP 200,内容一致。整条链路 Muse → muse2api → Magpie 通了。
图片,进行中。 走的是 muse2api 的异步接口:
# 提交
curl -X POST http://localhost:18610/v1/images/tasks \
-H "Authorization: Bearer <你的 API Key>" \
-H "Content-Type: application/json" \
-d '{"model":"muse-image","prompt":"一只红色玩具帆船","aspect_ratio":"16:9","response_format":"url"}'
# 轮询
curl http://localhost:18610/v1/images/tasks/<task_id> -H "Authorization: Bearer <你的 API Key>"
任务状态有 queued、processing、completed、failed 四种。Muse 本身不提供百分比,进度只是几个观察到的节点。我这次跑到 processing 40%,写这篇时还没出最终结果。
视频,还没测。 计划用上一步的图做首帧,生成 4 秒 16:9 视频,接口是 POST /v1/videos,再轮询 GET /v1/videos/{task_id}。
踩坑记录
- 只看模型列表,漏了现成插件。 第一次检查只看了 Magpie 的模型列表,没看插件目录,以为没人做过。查了才发现插件有,只是只支持文本。
- Debian 源 502。 第一次构建镜像,deb.debian.org 在 libxfixes3、libgl1 上返回 502,大约 182 个包、220MB 下载。解决:写一个
Dockerfile.local,把源换成 HTTPS 的 USTC 镜像,apt 加重试,再用一个小脚本并行下载 .deb,带重试和大小校验。之后构建通过,Chromium 156。 - 管理页 401。 管理页的更新和查询一直 401,原因是管理页没存对 key。用上游较新的提交重建镜像(1.6.0 → 1.6.7,新 Dockerfile 多复制了一个 proxy.py),之后管理接口 200,检查更新显示已是最新。
- Chrome 不让自动填 key。 想用 AppleScript 往页面注入 JS 填 key,但 Chrome 默认关闭了「允许 Apple 事件中的 JavaScript」。改成把 key 放进剪贴板,在管理页和扩展里手动粘贴。
- ArcReel 容器访问宿主机。 ArcReel 跑在 Docker 里,访问宿主机服务要用
host.docker.internal:18610,我实测能通(200)。ArcReel 支持声明式的自定义供应商(提交 → 轮询),正好对得上 muse2api 的任务接口,但我还没配完。
限制和风险
- 这是非官方的逆向接口。 muse2api 靠浏览器自动化驱动 muse.ai 网页,不是 Meta 提供的 API。网页一改版就可能失效,也可能违反 Muse 的服务条款。账号被限制或封禁的风险由你自己承担。建议用不重要的号,不要连主力邮箱和支付。
- 登录态就是账号。 导入的 Cookie 等于账号的完整权限。扩展要收窄权限,实例只绑 127.0.0.1,
.env不进 Git。 - Magpie 只管文本。 图片和视频要直接调 muse2api,下游工具需要支持「提交 + 轮询」的异步模式。
- 没有精确进度。 长任务只能轮询状态,超时要设宽:上游默认图片 240 秒、视频 600 秒、对话 300 秒。
- 账号状态要盯。 我的账号导入时就显示临近到期,续期失败时链路会直接断。
下一步
等图片任务出结果,跑一遍图生视频,再在 ArcReel 里用声明式供应商把 muse-image 和 muse-video 接进去。跑通后再写一篇。
说明:本文按我自己的操作记录整理。文本链路已实测通过;图片只跑到 processing 40%,视频和 ArcReel 接入还没验证,不代表能用。所有 key、地址都已替换成占位符。
COMMENTS
读者评论