Jellyfin API 实战教程:4 个关卡搞定认证、查询与数据写入
【免费下载链接】jellyfinThe Free Software Media System - Server Backend & API项目地址: https://gitcode.com/GitHub_Trending/je/jellyfin
你想给家庭影院做个遥控 App,或者写个脚本每天自动检查媒体库有没有新片入库?只要 Jellyfin(一个可自托管的开源媒体服务器)跑在你的机器上,这些事情都能通过它的 HTTP 接口——也就是Jellyfin API——完成。本文不讲抽象架构,按"动手闯关"的顺序带你走完:先拿到访问令牌,再查一遍媒体库,然后试着写入数据,最后备一份排错速查。跟着做,你就能把自己的 App 或脚本接进 Jellyfin。
🎫 第一关:拿到 Jellyfin 认证令牌(登录接口写法)
Jellyfin 的多数接口要求先"登录"换一张令牌。登录接口是POST /Users/AuthenticateByName,把用户名和密码放在 JSON 请求体里:
curl -X POST "http://127.0.0.1:8096/Users/AuthenticateByName" \ -H "Content-Type: application/json" \ -d '{"Username": "admin", "Pw": "你的密码"}'响应里重点看两个字段:
{ "AccessToken": "a1b2c3d4e5f6g7h8i9j0", "User": { "Id": "3f2a8b9c-1d2e-4a3b-9c8d-0e1f2a3b4c5d", "Name": "admin" }, "SessionInfo": { "Id": "6e5d4c3b-..." } }AccessToken:你的访问令牌,后面每个请求都要带上;User.Id:用户 ID,查询媒体库等接口要用到,先存下来。
拿到令牌后,放进请求头的X-Emby-Token即可(也可以写成Authorization: MediaBrowser Token="..."的形式,二者等价):
curl "http://127.0.0.1:8096/Users/Me" \ -H "X-Emby-Token: a1b2c3d4e5f6g7h8i9j0"如果返回了你自己的用户信息,说明令牌生效了,第一关通过。想确认令牌是否还有效,随时可以打这个GET /Users/Me。
🔎 第二关:查询媒体库(Jellyfin 接口调用示例)
现在用一次真实查询,把类型过滤、分页、字段裁剪这些常用参数一次串起来。请求GET /Items,带上上一关存下的用户 ID:
curl "http://127.0.0.1:8096/Items?userId=3f2a8b9c-...&includeItemTypes=Movie&Recursive=true&SortBy=PremiereDate&SortOrder=Descending&StartIndex=0&Limit=20&fields=PrimaryImageAspectRatio" \ -H "X-Emby-Token: a1b2c3d4e5f6g7h8i9j0"各参数在做什么:
includeItemTypes=Movie:只查电影,换成Series、MusicAlbum或逗号分隔的多个类型也行;Recursive=true:递归进入子文件夹;StartIndex=0&Limit=20:分页,第一页 20 条,下一页把StartIndex改成 20;fields=PrimaryImageAspectRatio:字段裁剪,只额外返回你点名的字段,省流量;SortBy=PremiereDate&SortOrder=Descending:按上映日期倒序,最新入库的排在前面。
响应长这样:
{ "Items": [ { "Id": "b7e1f2a0-...", "Name": "星际穿越", "Type": "Movie", "PremiereDate": "2014-11-05T08:00:00Z" } ], "StartIndex": 0, "Size": 20, "TotalRecordCount": 42 }TotalRecordCount告诉你总数是 42 条,Items里每一项的Id就是后续"动数据"要用的项目 ID。电影海报、简介这些元数据大多来自 OMDb 之类的元数据插件,你在 App 里拿到的正是它们入库后的结果:
✍️ 第三关:写入数据——按使用场景来
写接口的返回大多是204 No Content(没有响应体),状态码本身就是你判断成功的依据。
Jellyfin 播放进度上报示例
你的播放器每 10 秒上报一次位置,用POST /Sessions/Playing/Progress:
curl -X POST "http://127.0.0.1:8096/Sessions/Playing/Progress" \ -H "X-Emby-Token: a1b2c3d4e5f6g7h8i9j0" \ -H "Content-Type: application/json" \ -d '{ "ItemId": "b7e1f2a0-...", "PositionTicks": 18000000000, "IsPaused": false, "PlayMethod": "Transcode" }'注意PositionTicks的单位是 .NET 的 tick:1 秒 = 10,000,000 ticks,上例的 18000000000 就是播到了第 30 分钟。
标记已看 / 取消已看
比逐帧上报更简单的是直接改状态:POST /UserPlayedItems/{itemId}标记已看,DELETE /UserPlayedItems/{itemId}取消,返回该项目的用户数据,方便你校验:
curl -X POST "http://127.0.0.1:8096/UserPlayedItems/b7e1f2a0-..." \ -H "X-Emby-Token: a1b2c3d4e5f6g7h8i9j0"给家人开账号:创建用户
这是管理员专属接口(对应源码里的RequiresElevation策略),必须用管理员账户的令牌。POST /Users/New:
curl -X POST "http://127.0.0.1:8096/Users/New" \ -H "X-Emby-Token: <管理员令牌>" \ -H "Content-Type: application/json" \ -d '{"Name": "xiaoming", "Password": "初始密码"}'返回200和新用户的 DTO,其中Id字段就是你后续给这个孩子账户发权限、查资料要用的用户 ID。
新增媒体文件夹:VirtualFolders
新硬盘挂载好了,想让 Jellyfin 收进去?POST /Library/VirtualFolders新建一个虚拟文件夹:
curl -X POST "http://127.0.0.1:8096/Library/VirtualFolders" \ -H "X-Emby-Token: <管理员令牌>" \ -H "Content-Type: application/json" \ -d '{"CollectionType": "movies", "Name": "电影 2026", "Locations": ["/media/movies-2026"]}'CollectionType决定媒体库类型(movies、tv、music、photos、books等)。成功后可以再打GET /Library/VirtualFolders确认新文件夹已出现在列表里,然后触发一次库扫描即可。
🩹 排错速查:Jellyfin 接口 HTTP 状态码对照
| 状态码 | 常见含义 | 先查什么 |
|---|---|---|
| 400 | 请求体或查询参数格式不对 | 看返回的 errors 字段,逐个修正 |
| 401 | 令牌缺失或无效 | X-Emby-Token是否拼错、令牌是否被吊销 |
| 403 | 权限不足 | 该接口是否要求管理员令牌(如创建用户) |
| 404 | 项目/用户不存在 | itemId、userId是否复制完整 |
| 405 | HTTP 方法用错 | 该接口是 GET 还是 POST |
| 500 | 服务端异常 | 翻服务器日志找对应时间点的堆栈 |
参数类错误会返回标准的 JSON 问题详情,例如登录时漏了Pw:
{ "type": "https://tools.ietf.org/html/rfc9110#section-15.5.1", "title": "One or more validation errors occurred.", "status": 400, "errors": { "Pw": [ "The Pw field is required." ] } }而 5xx 在生产模式下只回一句Error processing request.,具体原因要去服务器日志里看。排查思路记三句:401 先怀疑令牌,403 先怀疑账户角色,500 直接看日志——认证逻辑在 Jellyfin.Api/Auth 和 Jellyfin.Server.Implementations/Security 里,报错处理在 Jellyfin.Api/Middleware/ExceptionMiddleware.cs,想深挖时可以对号入座。
⚡ 提效小抄:5 条实践清单
- 分页用
StartIndex+Limit,响应里的TotalRecordCount决定要不要翻下一页。 - 列表查询加
fields参数,只取渲染界面真正需要的字段。 - 令牌等同长期密码,别硬编码在公开脚本里,改动服务器密码后要重新登录换令牌。
- 多设备共享令牌时,给每个请求带上
X-Emby-Client和X-Emby-Device-Id头,"当前会话"页里才好区分是谁在播。 - 懒得背接口就打开
http://你的服务器:8096/docs,那是随服务器附带的交互式完整 API 文档,可以直接在线调试。
写在最后
到这里,你手上已经有了一个能登录、能查库、能写数据的完整链路:从 Jellyfin.Api/Controllers 里的几十个控制器挑出你要的接口,用令牌换取信任,剩下的就是循环和判断。把这套流程搬进你的遥控 App 或定时脚本,再配合/docs页面查漏补缺,绝大多数自动化需求都能自己解决;遇到拿不准的行为,去项目仓库的 issue 区或社区论坛看看,大概率有人踩过同一个坑。
【免费下载链接】jellyfinThe Free Software Media System - Server Backend & API项目地址: https://gitcode.com/GitHub_Trending/je/jellyfin
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考