Kodi 常用命令与运维实战(核心篇)
Kodi 21.2 运维核心篇:JSON-RPC 五域实战(Player 播放/Playlist 播放列表/Application 音量静音/VideoLibrary 扫描导出/Settings 改值,174 方法 Introspect 自查)、kodi-send UDP 事件推送与状态验证、tar+sqlite .backup 双层备份与恢复演练、三类假错误(libva/VDPAU/AESink)与两类真错误定位、apt 升级与版本锁定,命令速查表收尾。
Kodi 常用命令与运维实战(核心篇)
目标:把 headless Kodi 21.2 的日常运维浓缩成一套可复制的命令集——JSON-RPC 全域实战(播放/播放列表/应用/媒体库/设置)、kodi-send 事件推送、备份与恢复演练、日志排障、升级流程。全部命令与回显均为 2026-10-28 在一台 Debian 13 (trixie) 服务器(Kodi 21.2,包版本
2:21.2+dfsg-4,Xvfb headless 运行,Web/JSON-RPC 8080 端口)实测逐行照抄;部署见 《Kodi 安装实战(Debian 13 Headless 部署与远程控制)》,配置项语义见《Kodi 21.2 配置参数详解》。
一、环境信息
- 操作系统:Debian GNU/Linux 13 (trixie),x86_64;
- Kodi 版本:21.2 "Omega"(
2:21.2+dfsg-4),JSON-RPC 协议版本 13.5; - 运行形态:headless,Xvfb
:99+ systemd 双服务(xvfb.service、kodi.service),运行用户kodi; - 远程接口:HTTP/JSON-RPC
127.0.0.1:8080(Basic 认证admin/q1w2e3r4),EventServer UDP9777; - 数据目录
/home/kodi/.kodi/,媒体/srv/media/movies/(4 部测试影片已入库),备份/srv/backup/; - 客户端工具:
curl(HTTP RPC)、kodi-send(UDP 事件,包kodi-eventclients-kodi-send)、sqlite3。
二、前置条件
- 服务处于运行态,RPC 通道打通:
systemctl is-active kodi
curl -s -u admin:q1w2e3r4 -H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","method":"JSONRPC.Ping","id":1}' \
http://127.0.0.1:8080/jsonrpc
实测回显:
active
{"id":1,"jsonrpc":"2.0","result":"pong"}
- 本章约定一个 curl 别名简化书写(后文所有
$RPC均指它,远程调用只需换 IP):
RPC='curl -s -u admin:q1w2e3r4 -H "Content-Type: application/json" -d'
$RPC '{"jsonrpc":"2.0","method":"JSONRPC.Ping","id":1}' http://127.0.0.1:8080/jsonrpc
实测回显:
{"id":1,"jsonrpc":"2.0","result":"pong"}
kodi-send已随kodi-eventclients-kodi-send安装(which kodi-send→/usr/bin/kodi-send)。
⚠️ 注意:Kodi 的 JSON-RPC 报文里方法名、参数名严格大小写(
Player.Open、movieid),写错一律返回{"error":{"code":-32601,"message":"Method not found."}}或 Invalid params,这是命令行调试最常见的翻车点。
三、JSON-RPC 远程控制(核心域)
3.1 通道与协议基础
Kodi 21.2 的 JSON-RPC 内省自描述能力极强,JSONRPC.Introspect 一次拿全接口手册:
$RPC '{"jsonrpc":"2.0","method":"JSONRPC.Version","id":1}' http://127.0.0.1:8080/jsonrpc
实测回显:
{"id":1,"jsonrpc":"2.0","result":{"major":13,"minor":5,"patch":0}}
$RPC '{"jsonrpc":"2.0","method":"JSONRPC.Introspect","id":1}' \
http://127.0.0.1:8080/jsonrpc | python3 -c "
import json,sys; d=json.load(sys.stdin)['result']
print('methods:',len(d['methods']),'types:',len(d['types']))"
实测回显:
methods: 174 types: 200
174 个方法、200 个类型定义都在这一条命令里,配合 filter 参数可取单个方法的参数定义,不用去翻 Wiki。认证失败的边界(实测):无认证头与错误密码均返回 HTTP 401。
💡 技术拓展:
ss -ltnp显示 Kodi 除 8080 外还监听127.0.0.1:9090——这是 JSON-RPC 的 TCP 通道(仅回环,供局域网遥控 App 直连),HTTP 通道带 Basic 认证、能力一致,运维脚本统一走 8080 最省心。
3.2 播放器域(Player.*)
取版本信息(安装验收的标准一枪):
$RPC '{"jsonrpc":"2.0","method":"Application.GetProperties","params":{"properties":["version","name"]},"id":1}' http://127.0.0.1:8080/jsonrpc
实测回显:
{"id":1,"jsonrpc":"2.0","result":{"name":"Kodi","version":{"major":21,"minor":2,"revision":"20250330-nogitfound","tag":"stable"}}}
远程点播 → 查询进度 → 暂停 → 停止一条龙(以库内 movieid=1 为例):
$RPC '{"jsonrpc":"2.0","method":"Player.GetActivePlayers","id":1}' http://127.0.0.1:8080/jsonrpc
# → {"id":1,"jsonrpc":"2.0","result":[]} (当前无播放器活跃)
$RPC '{"jsonrpc":"2.0","method":"Player.Open","params":{"item":{"movieid":1}},"id":1}' http://127.0.0.1:8080/jsonrpc
# → {"id":1,"jsonrpc":"2.0","result":"OK"}
sleep 4
$RPC '{"jsonrpc":"2.0","method":"Player.GetProperties","params":{"playerid":1,"properties":["speed","time","totaltime","percentage"]},"id":1}' http://127.0.0.1:8080/jsonrpc
# → {"id":1,"jsonrpc":"2.0","result":{"percentage":0.0,"speed":1,"time":{"hours":0,"milliseconds":0,"minutes":0,"seconds":0},"totaltime":{"hours":0,"milliseconds":0,"minutes":1,"seconds":0}}}
$RPC '{"jsonrpc":"2.0","method":"Player.GetItem","params":{"playerid":1,"properties":["title","file"]},"id":1}' http://127.0.0.1:8080/jsonrpc
# → {"id":1,"jsonrpc":"2.0","result":{"item":{"file":"/srv/media/movies/Big Buck Bunny 2008.mp4","id":1,"label":"Big Buck Bunny","title":"Big Buck Bunny","type":"movie"}}}
$RPC '{"jsonrpc":"2.0","method":"Player.PlayPause","params":{"playerid":1},"id":1}' http://127.0.0.1:8080/jsonrpc
# → {"id":1,"jsonrpc":"2.0","result":{"speed":0}} (0=已暂停)
$RPC '{"jsonrpc":"2.0","method":"Player.Stop","params":{"playerid":1},"id":1}' http://127.0.0.1:8080/jsonrpc
# → {"id":1,"jsonrpc":"2.0","result":"OK"}
以上为实测完整序列(注释标注关键返回)。Player.GetProperties 的 time/totaltime 结构为时分秒毫秒对象,进度百分比与秒数可直接供脚本做进度条。也支持按文件路径直放,不经过媒体库:
$RPC '{"jsonrpc":"2.0","method":"Player.Open","params":{"item":{"file":"/srv/media/movies/Kodi.Demo.Movie.One.2024.mp4"}},"id":1}' http://127.0.0.1:8080/jsonrpc
$RPC '{"jsonrpc":"2.0","method":"Player.GetItem","params":{"playerid":1,"properties":["title","file"]},"id":1}' http://127.0.0.1:8080/jsonrpc
实测回显:
{"id":1,"jsonrpc":"2.0","result":"OK"}
{"id":1,"jsonrpc":"2.0","result":{"item":{"file":"/srv/media/movies/Kodi.Demo.Movie.One.2024.mp4","id":2,"label":"Kodi Demo Movie One","title":"Kodi Demo Movie One","type":"movie"}}}
playerid 用 Player.GetActivePlayers 现查现用;视频是 1、音乐是 0、图片是 2。
3.3 播放列表域(Playlist.*)
播放列表实例按媒体类型预置,先查再操作(实测 Playlist.GetPlayLists):
$RPC '{"jsonrpc":"2.0","method":"Playlist.GetPlayLists","id":1}' http://127.0.0.1:8080/jsonrpc
实测回显:
{"id":1,"jsonrpc":"2.0","result":[{"playlistid":0,"type":"audio"},{"playlistid":1,"type":"video"},{"playlistid":2,"type":"picture"}]}
组装 → 插队 → 查看 → 删除 → 清空全流程(playlistid=1 即视频播放列表):
$RPC '{"jsonrpc":"2.0","method":"Playlist.Add","params":{"playlistid":1,"item":{"movieid":2}},"id":1}' http://127.0.0.1:8080/jsonrpc
$RPC '{"jsonrpc":"2.0","method":"Playlist.Add","params":{"playlistid":1,"item":{"movieid":3}},"id":1}' http://127.0.0.1:8080/jsonrpc
# → {"id":1,"jsonrpc":"2.0","result":"OK"}
$RPC '{"jsonrpc":"2.0","method":"Playlist.Insert","params":{"playlistid":1,"position":1,"item":{"movieid":4}},"id":1}' http://127.0.0.1:8080/jsonrpc
$RPC '{"jsonrpc":"2.0","method":"Playlist.GetItems","params":{"playlistid":1,"properties":["title"]},"id":1}' http://127.0.0.1:8080/jsonrpc
实测回显(加入两支、在位置 1 插入一支后):
{"id":1,"jsonrpc":"2.0","result":{"limits":{"end":3,"start":0,"total":3},"items":[{"label":"Kodi Demo Movie One","title":"Kodi Demo Movie One","type":"movie"},{"label":"Sintel","title":"Sintel","type":"movie"},{"label":"Kodi Demo Movie Two","title":"Kodi Demo Movie Two","type":"movie"}]}}
$RPC '{"jsonrpc":"2.0","method":"Playlist.Remove","params":{"playlistid":1,"position":2},"id":1}' http://127.0.0.1:8080/jsonrpc
$RPC '{"jsonrpc":"2.0","method":"Playlist.Clear","params":{"playlistid":1},"id":1}' http://127.0.0.1:8080/jsonrpc
实测回显:
{"id":1,"jsonrpc":"2.0","result":"OK"}
{"id":1,"jsonrpc":"2.0","result":"OK"}
⚠️ 注意:
Playlist.GetPlayLists可列出播放列表实例,但不存在Playlist.Create方法——列表按 media 类型预置(0 音乐/1 视频/2 图片),直接往playlistid里 Add 即可(实测调用Playlist.Create返回Method not found)。
3.4 应用与系统域(Application.* / System.*)
音量与静音控制(headless 无声卡也照样维护状态值):
$RPC '{"jsonrpc":"2.0","method":"Application.GetProperties","params":{"properties":["volume","muted"]},"id":1}' http://127.0.0.1:8080/jsonrpc
# → {"id":1,"jsonrpc":"2.0","result":{"muted":false,"volume":42}} (此前实验把音量设到过 42)
$RPC '{"jsonrpc":"2.0","method":"Application.SetVolume","params":{"volume":42},"id":1}' http://127.0.0.1:8080/jsonrpc
# → {"id":1,"jsonrpc":"2.0","result":42} (返回值为设定后的音量)
$RPC '{"jsonrpc":"2.0","method":"Application.SetMute","params":{"mute":true},"id":1}' http://127.0.0.1:8080/jsonrpc
# → {"id":1,"jsonrpc":"2.0","result":true}
$RPC '{"jsonrpc":"2.0","method":"Application.GetProperties","params":{"properties":["volume","muted"]},"id":1}' http://127.0.0.1:8080/jsonrpc
# → {"id":1,"jsonrpc":"2.0","result":{"muted":true,"volume":42}} (muted 翻转生效)
$RPC '{"jsonrpc":"2.0","method":"Application.SetMute","params":{"mute":false},"id":1}' http://127.0.0.1:8080/jsonrpc
# → {"id":1,"jsonrpc":"2.0","result":false}
以上为实测序列(注释标注关键返回)。屏幕通知是自动化场景的反馈利器:
$RPC '{"jsonrpc":"2.0","method":"GUI.ShowNotification","params":{"title":"Ops Demo","message":"backup done via JSON-RPC","displaytime":4000},"id":1}' http://127.0.0.1:8080/jsonrpc
实测回显:
{"id":1,"jsonrpc":"2.0","result":"OK"}
系统信息标签(GetInfoLabels 取运行态信息;Network.IPAddress 取到 Busy 是因为该属性在读数瞬间未就绪——Kodi 对暂时取不到的 InfoLabel 会回 Busy,脚本里要做兜底):
$RPC '{"jsonrpc":"2.0","method":"XBMC.GetInfoLabels","params":{"labels":["System.BuildVersion","System.FriendlyName","Network.IPAddress"]},"id":1}' http://127.0.0.1:8080/jsonrpc
实测回显:
{"id":1,"jsonrpc":"2.0","result":{"Network.IPAddress":"Busy","System.BuildVersion":"21.2 Debian package version: 2:21.2+dfsg-4","System.FriendlyName":"Kodi (kodi-server)"}}
💡 技术拓展:
XBMC.GetInfoLabels里的XBMC是 Kodi 的曾用名——Kodi 21 的 JSON-RPC 同时保留XBMC.*旧命名空间与新的System.*/GUI.*系列,两者并存属向后兼容设计,脚本里任选其一即可(System.GetProperties的属性名是白名单枚举,不在枚举内的属性只能走 InfoLabels 通道)。
关机/重启权限:System.GetProperties 探测(实测两值均 false,headless 环境下 Kodi 无 systemd 关机授权,重启请直接 systemctl restart kodi):
$RPC '{"jsonrpc":"2.0","method":"System.GetProperties","params":{"properties":["canshutdown","canreboot"]},"id":1}' http://127.0.0.1:8080/jsonrpc
实测回显:
{"id":1,"jsonrpc":"2.0","result":{"canreboot":false,"canshutdown":false}}
3.5 媒体库域(VideoLibrary.* / AudioLibrary.*)
扫描与查询:
$RPC '{"jsonrpc":"2.0","method":"VideoLibrary.Scan","id":1}' http://127.0.0.1:8080/jsonrpc
# → {"id":1,"jsonrpc":"2.0","result":"OK"}
$RPC '{"jsonrpc":"2.0","method":"VideoLibrary.GetMovies","params":{"properties":["title","year","file"]},"id":1}' http://127.0.0.1:8080/jsonrpc
实测回显(4 部影片全部入库):
{"id":1,"jsonrpc":"2.0","result":{"limits":{"end":4,"start":0,"total":4},"movies":[{"file":"/srv/media/movies/Big Buck Bunny 2008.mp4","label":"Big Buck Bunny","movieid":1,"title":"Big Buck Bunny","year":2008},{"file":"/srv/media/movies/Kodi.Demo.Movie.One.2024.mp4","label":"Kodi Demo Movie One","movieid":2,"title":"Kodi Demo Movie One","year":2024},{"file":"/srv/media/movies/Kodi.Demo.Movie.Two.2024.mp4","label":"Kodi Demo Movie Two","movieid":3,"title":"Kodi Demo Movie Two","year":2024},{"file":"/srv/media/movies/Sintel 2010.mp4","label":"Sintel","movieid":4,"title":"Sintel","year":2010}]}}
最近添加:
$RPC '{"jsonrpc":"2.0","method":"VideoLibrary.GetRecentlyAddedMovies","params":{"limits":{"start":0,"end":2}},"id":1}' http://127.0.0.1:8080/jsonrpc
实测回显:
{"id":1,"jsonrpc":"2.0","result":{"limits":{"end":2,"start":0,"total":4},"movies":[{"label":"Kodi Demo Movie Two","movieid":3},{"label":"Kodi Demo Movie One","movieid":2}]}}
库导出(含权限排障实录):把库导出为 XML + 缩略图,做库迁移与备份介质:
mkdir -p /srv/backup/libexport
chown kodi:kodi /srv/backup/libexport
$RPC '{"jsonrpc":"2.0","method":"VideoLibrary.Export","params":{"options":{"path":"/srv/backup/libexport"}},"id":1}' http://127.0.0.1:8080/jsonrpc
sleep 6; find /srv/backup/libexport -type f
实测回显:
{"id":1,"jsonrpc":"2.0","result":"OK"}
/srv/backup/libexport/kodi_videodb_2026-10-28/videodb.xml
/srv/backup/libexport/kodi_videodb_2026-10-28/movies/Sintel_2010-thumb.jpg
/srv/backup/libexport/kodi_videodb_2026-10-28/movies/Kodi_Demo_Movie_One_2024-thumb.jpg
/srv/backup/libexport/kodi_videodb_2026-10-28/movies/Big_Buck_Bunny_2008-thumb.jpg
/srv/backup/libexport/kodi_videodb_2026-10-28/movies/Kodi_Demo_Movie_Two_2024-thumb.jpg
这里有个必踩的坑:VideoLibrary.Export 返回 OK 只表示任务受理,写不写得进去取决于运行用户 kodi 对目标目录的写权限。实测目录属主为 root 时,Kodi 在日志里报 Create - Error creating /srv/backup/libexport/kodi_videodb_2026-10-28/movies(chown kodi:kodi 后重跑即成功)——RPC 层和日志层要一起看,这正是 headless 排障的典型姿势。参数名用 path;exportpath 会报 Invalid params(枚举校验拒绝)。
音乐库扫描的现实:AudioLibrary.Scan 同样返回 OK,但在 headless 场景若音乐源未在 GUI 中设定内容类型,实测 4 分钟后曲库仍为 0——视频库可用 sqlite3 直写 path.strContent 兜底(见配置篇 5.6),音乐库建议走"前端 GUI 一次性配置"或接受文件浏览模式(Files.GetDirectory 列目录即可用)。
3.6 设置域(Settings.*)
$RPC '{"jsonrpc":"2.0","method":"Settings.GetSettingValue","params":{"setting":"services.webserverport"},"id":1}' http://127.0.0.1:8080/jsonrpc
# → {"id":1,"jsonrpc":"2.0","result":{"value":8080}}
$RPC '{"jsonrpc":"2.0","method":"Settings.SetSettingValue","params":{"setting":"services.webserverport","value":8090},"id":1}' http://127.0.0.1:8080/jsonrpc
# → {"id":1,"jsonrpc":"2.0","result":true}
两枚回显均实测。注意 services.webserverport 这类"落盘即时、挂载要重启"的参数——运行中改端口会导致 Web 管理面摘除,重启才挂新口,完整的 8080→8090→8080 闭环实录见《Kodi 21.2 配置参数详解》6.1。
四、kodi-send 事件推送(EventServer)
JSON-RPC 之外,Kodi 还有一条 UDP 9777 事件通道(EventServer),kodi-send 是官方事件客户端,适合按键模拟与轻量自动化。帮助输出(实测 kodi-send --help):
Usage
kodi-send [OPTION] --action=ACTION
kodi-send [OPTION] --button=BUTTON
Example
kodi-send --host=192.168.0.1 --port=9777 --action="Quit"
Options
-?, --help Will bring up this message
--host=HOST Choose what HOST to connect to (default=localhost)
--port=PORT Choose what PORT to connect to (default=9777)
--keymap=KEYMAP Choose which KEYMAP to use for key presses (default=KB)
--button=BUTTON Sends a key press event to Kodi, this option can be added multiple times to create a macro
--mouse=X,Y Sends the mouse position to Kodi
--log=MESSAGE Sends a log message to Kodi
--loglevel=LEVEL Sets the log level when using --log= (default=LOGDEBUG)
-a ACTION, --action=ACTION Sends an action to Kodi, this option can be added multiple times to create a macro
-d T, --delay=T Waits for T ms, this option can be added multiple times to create a macro
实战:用 kodi-send 静音,再用 JSON-RPC 读回状态验证(EventServer 无响应报文,用状态变化做效果验证):
kodi-send --host=127.0.0.1 --action="Mute"
sleep 1
$RPC '{"jsonrpc":"2.0","method":"Application.GetProperties","params":{"properties":["muted","volume"]},"id":1}' http://127.0.0.1:8080/jsonrpc
kodi-send --host=127.0.0.1 --action="Mute" # 再按一次恢复
实测回显(中间的 RPC 读数):
{"id":1,"jsonrpc":"2.0","result":{"muted":true,"volume":42}}
事件送达且生效(静音翻转)。常用动作速查:Mute、ShowSubtitles、Stop、PlayPause、Quit;按键模拟用 --button="select";多动作宏用 -a A -d 500 -a B(动作间延时 500ms)。与 JSON-RPC 的选型:要回执与结构化查询用 JSON-RPC;要按键级行为与 GUI 动作(如 Enter 确认、方向键导航)用 kodi-send。
五、备份与恢复
Kodi 的可备份资产就两块:~/.kodi/(配置 + 数据库)与媒体库本身。三招组合,按需取用。
5.1 全量热备:tar 打包 userdata
tar czf /srv/backup/kodi-home-$(date +%Y%m%d).tar.gz -C /home/kodi .kodi
ls -la /srv/backup/kodi-home-*.tar.gz
sha256sum /srv/backup/kodi-home-*.tar.gz | cut -c1-24
实测回显:
-rw-r--r-- 1 root root 2308399 Oct 28 16:39 /srv/backup/kodi-home-20261028.tar.gz
d2c6ff61a3b8b3144ab69f99783b3f76
2.3MB 热备一把梭。热备期间的库一致性由 SQLite WAL 机制兜底(写入仍在进行也只是快照略旧),精确一致见 5.2。
5.2 库级精确备份:sqlite3 .backup
SQLite 自带的在线备份 API 不需要停服务:
sqlite3 /home/kodi/.kodi/userdata/Database/MyVideos131.db ".backup /srv/backup/MyVideos131.online.bak"
ls -la /srv/backup/MyVideos131.online.bak
实测回显:
-rw-r--r-- 1 root root 401408 Oct 28 16:39 /srv/backup/MyVideos131.online.bak
392KB 的视频库精确快照。注意 MyVideos131.db 是 kodi 用户的文件,root 直接读没问题;改写库前务必先 systemctl stop kodi。
5.3 恢复演练
恢复 = 停服 → 还原 tar → 校验 → 起服:
systemctl stop kodi
mkdir -p /tmp/restore-test && tar xzf /srv/backup/kodi-home-20261028.tar.gz -C /tmp/restore-test
diff -r /tmp/restore-test/.kodi/userdata /home/kodi/.kodi/userdata >/dev/null && echo "restore dry-run: content identical"
rm -rf /tmp/restore-test
# 真恢复(覆盖现目录):
# rm -rf /home/kodi/.kodi && tar xzf /srv/backup/kodi-home-20261028.tar.gz -C /home/kodi && chown -R kodi:kodi /home/kodi/.kodi
systemctl start kodi
实测回显:
restore dry-run: content identical
干跑校验一致,真实恢复命令已注释在脚本位。恢复后起服,用 JSONRPC.Ping + VideoLibrary.GetMovies(total:4)确认库完整。
六、日志排障
6.1 日志位置与轮转
- 运行日志:
/home/kodi/.kodi/temp/kodi.log;每次重启 Kodi 把旧日志改名kodi.old.log(排障时先比对新旧两份); - systemd 侧:
journalctl -u kodi(stderr/stdout),实测取最近 3 行:
journalctl -u kodi -n 3 --no-pager
实测回显:
Oct 28 16:38:00 localhost systemd[1]: Starting Kodi Media Center (headless via Xvfb)...
Oct 28 16:38:00 localhost systemd[1]: Started Kodi Media Center (headless via Xvfb).
Oct 28 16:38:01 localhost systemd[1]: Started Xvfb Virtual Framebuffer X Server (for Kodi headless).
- 详细日志开关:
Settings.SetSettingValue改debug.extralogging(即时生效,见配置篇 6.2)或advancedsettings.xml的<loglevel>(重启生效,见配置篇 5.4)。
6.2 三类"假错误"与两类真错误
headless 服务器的 kodi.log 长年刷以下"假错误",确认环境无 GPU 无声卡后可直接忽略(实测日志原文):
libva error: vaGetDriverNames() failed with unknown libva error
Failed to open VDPAU backend libvdpau_nvidia.so: cannot open shared object file
CActiveAESink::OpenSink - no sink was returned
另有一类"看起来像错"的正常回显:扫描时 VideoInfoScanner: Skipping dir '/srv/media/movies/' due to no change (fasthash)——库对未变化目录做快速哈希跳过,不是扫描失败。
真错误一:影片扫不进库。 日志证据(实测原文):
WARNING: No information found for item '/srv/media/movies/Kodi.Demo.Movie.One.2024.mp4', it won't be added to the library.
排障路径:内容类型未设(path.strContent 为 NULL)→ sqlite3 打标记(配置篇 5.6);metadata.local 刮削器缺同名 NFO → 补 NFO 文件。
真错误二:RPC 返回 OK 但事情没发生。 例:库导出 OK 而目录无产物,日志里才有真凶:
error <general>: Create - Error creating /srv/backup/libexport/kodi_videodb_2026-10-28/movies
error <general>: Export failed exporting 'special://masterprofile/Thumbnails/1/1423119e.jpg' to '/srv/backup/libexport/kodi_videodb_2026-10-28/movies/Sintel_2010-thumb.jpg'
排障路径:chown kodi:kodi <目录> 后重跑。口诀:RPC 的 OK 只代表受理,成败去 kodi.log 里找。
6.3 进程级体检
ps -o pid,user,cmd -C kodi.bin
ss -ltnp | grep kodi.bin
systemctl status kodi --no-pager | head -5
实测回显(进程、监听、服务三件套):
PID USER CMD
2663 kodi /usr/lib/x86_64-linux-gnu/kodi/kodi.bin
LISTEN 0 4096 0.0.0.0:8080 0.0.0.0:* users:(("kodi.bin",pid=2663,fd=24))
LISTEN 0 10 127.0.0.1:9090 0.0.0.0:* users:(("kodi.bin",pid=2663,fd=31))
● kodi.service - Kodi Media Center (headless via Xvfb)
Loaded: loaded (/etc/systemd/system/kodi.service; enabled; preset: enabled)
Active: active (running) since Tue 2026-10-28 16:38:00 UTC; 1h 2min ago
七、升级与版本管理
7.1 升级流程(apt 路线)
apt-get update
apt-cache policy kodi | head -4
apt-get install -y kodi kodi-eventclients-kodi-send
kodi --version
实测回显(当前已装与候选版本一致,升级无动作):
kodi:
Installed: 2:21.2+dfsg-4
Candidate: 2:21.2+dfsg-4
Version table:
*** 2:21.2+dfsg-4 500
500 http://deb.debian.org/debian trixie/main amd64 Packages
升级只动包不动数据:~/.kodi/ 完全保留(这也是升级前先跑一遍 5.1 备份的意义)。若 systemd 单元被包更新改动,systemctl daemon-reload 后 systemctl restart kodi 即可。
7.2 版本锁定与解锁
自动化服务器怕 apt upgrade 意外升坏,用 apt-mark 锁定:
apt-mark hold kodi kodi-bin kodi-data # 锁定
apt-mark showhold # 核对
apt-mark unhold kodi kodi-bin kodi-data # 解锁
升级后验收三板斧:kodi --version、systemctl is-active kodi、JSONRPC.Version(对照 major/minor)。
八、常用命令速查表
| 场景 | 命令 |
|---|---|
| 探活 | JSONRPC.Ping → pong |
| 取版本 | kodi --version / Application.GetProperties |
| 点播(库内) | Player.Open + {"item":{"movieid":N}} |
| 点播(任意文件) | Player.Open + {"item":{"file":"…"}} |
| 播放状态 | Player.GetProperties(speed/time/percentage) |
| 暂停/停止 | Player.PlayPause / Player.Stop |
| 排队 | Playlist.Add / Playlist.Insert / Playlist.GetItems |
| 音量/静音 | Application.SetVolume / Application.SetMute |
| 屏幕通知 | GUI.ShowNotification |
| 扫描库 | VideoLibrary.Scan / AudioLibrary.Scan |
| 查库 | VideoLibrary.GetMovies / GetRecentlyAddedMovies |
| 库导出 | VideoLibrary.Export(options.path,先 chown kodi) |
| 改设置 | Settings.SetSettingValue(部分参数需重启) |
| 事件推送 | kodi-send --host=<IP> --action="Mute" |
| 全量备份 | tar czf … -C /home/kodi .kodi |
| 库精确备份 | sqlite3 MyVideos131.db ".backup <文件>" |
| 日志 | ~/.kodi/temp/kodi.log / journalctl -u kodi |
| 接口手册 | JSONRPC.Introspect(174 方法全在这) |
| 锁版本 | apt-mark hold kodi kodi-bin kodi-data |
九、常见问题
Q1:JSON-RPC 返回 401?
Basic 认证头缺失或密码错(实测无认证与错误密码均 401)。核对 services.webserverusername/password,或先用 Settings.GetSettingValue 读出当前值。
Q2:Method not found?
方法名大小写写错,或该方法不在 HTTP 通道白名单(如 System.SetLogLevel/Playlist.Create 实测不存在于 21.2 的 HTTP 通道)。先 JSONRPC.Introspect 确认方法存在与参数结构。
Q3:RPC 返回 OK 但库/文件没变化?
看 kodi.log。导出类操作常见权限问题(Create - Error creating …),chown kodi:kodi 目标目录重跑;扫描类操作先确认内容类型与 NFO(第六章两类真错误)。
Q4:kodi-send 没反应?
EventServer 是 UDP 且无回执,用 RPC 读状态变化验证(第四章手法);另确认 services.esenabled=true、端口 9777、--host 指对 IP。日志级别开 DEBUG 后 EventServer 收包有记录。
Q5:升级后数据库报错?
Kodi 大版本升级会自动迁移库 schema(MyVideos131 是 21.x 的版本号)。跨大版本前先跑 5.1 全量备份;迁移失败的极端情况用备份的 MyVideos*.db 回滚到同版本 Kodi。
十、参考链接
- 官方 Wiki:JSON-RPC API v13(21.x 对应) https://kodi.wiki/view/JSON-RPC_API/v13
- 官方 Wiki:EventServer 与 kodi-send https://kodi.wiki/view/EventServer
- 官方 Wiki:Media library 导出/导入 https://kodi.wiki/view/Import_and_export_library
- 官方 Wiki:日志文件与调试 https://kodi.wiki/view/Log_file
- 官方 Wiki:备份指南 https://kodi.wiki/view/Backing_up Kodi
- 本专栏相关篇目:《Kodi 介绍与选型指南》、《Kodi 安装实战(Debian 13 Headless 部署与远程控制)》、《Kodi 21.2 配置参数详解》