Kodi 常用命令与运维实战(核心篇)

Kodi 21.2 运维核心篇:JSON-RPC 五域实战(Player 播放/Playlist 播放列表/Application 音量静音/VideoLibrary 扫描导出/Settings 改值,174 方法 Introspect 自查)、kodi-send UDP 事件推送与状态验证、tar+sqlite .backup 双层备份与恢复演练、三类假错误(libva/VDPAU/AESink)与两类真错误定位、apt 升级与版本锁定,命令速查表收尾。

KodiKodi流媒体自托管媒体服务器2026/10/29

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 UDP 9777;
  • 数据目录 /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。

十、参考链接