Gerbera 配置参数详解
Gerbera 3.3.0 config.xml 逐节实测详解:server/import/transcoding 三大节全参数、--create-config/--check-config/--print-options CLI 辅助、name 与 accounts 两处改值联动验证、存储三后端互斥与校验警告、autoscan 静态声明不落 mt_autoscan、boxlayout 虚拟布局 45 框、映射四表链路与转码三 profile,全部回显逐行照抄。
Gerbera 配置参数详解
本文在真实服务器实测环境(Gerbera 3.3.0 + MariaDB 11.8,2026-10-28)下,对 Gerbera 主配置 config.xml 逐节拆解:server / import / transcoding 三大节的全部参数、CLI 配置辅助命令(--create-config / --check-config / --print-options / --set-option)、name 与 accounts 两处改值的联动验证、存储三后端互斥关系与校验警告、autoscan 静态声明、boxlayout 虚拟布局 45 个框、映射四表链路与转码三 profile。全部配置样例与命令回显均为实测逐行照抄。
前置阅读:本文所用 config.xml 的生成与最小定制过程见 《Gerbera Docker Compose 部署实战》(以下简称部署篇),组件定位与选型见 《Gerbera 介绍与选型指南》;改完配置后的日常运维动作(备份、查库、排障)见本专栏《Gerbera 常用命令与运维实战(核心篇)》。
一、配置体系总览
Gerbera 的全部运行时行为由一份 XML 主配置驱动,不读注册表、不读环境变量表(少数启动变量除外)。本章先看清这份配置的骨架、生成方式与生效规则,再逐节展开。
1.1 文件骨架与加载路径
config.xml 是带命名空间校验的 XML,顶层固定三大节:
<?xml version="1.0" encoding="UTF-8"?>
<config version="2" xmlns="http://gerbera.io/config/2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://gerbera.io/config/2 http://gerbera.io/config/2.xsd">
<server>...</server> <!-- 网络、Web UI、存储、扩展运行时 -->
<import>...</import> <!-- 扫库、虚拟布局、映射表 -->
<transcoding>...</transcoding> <!-- 转码 -->
</config>
version="2" 是配置格式版本(对应 Gerbera 2.x 以来的 schema,3.3.0 仍沿用),xsi:schemaLocation 指向在线 XSD,编辑器可据此做自动补全。本次部署把宿主的 /opt/data/quzuo/tmp/gerbera/config/config.xml 以只读方式挂到实例内 /var/run/gerbera/config.xml,启动日志里打印的加载路径是 /run/gerbera/config.xml——二者是同一个文件,大多数现代 Linux 发行版中 /var/run 是指向 /run 的符号链接:
2026-10-28 20:37:12 info: Loading configuration from: /run/gerbera/config.xml
1.2 配置的三种生成方式
手头没有 config.xml 时有三条路:
- 首启自动生成:不挂载任何配置直接启动,Gerbera 在运行数据目录自动生成一份默认 config.xml(SQLite 后端、免登录),部署篇 3.1 节用的就是这条路的产物。
- CLI 打印骨架:不启动服务,直接让 CLI 把标准骨架打到标准输出:
docker exec gerbera-3.3.0-main gerbera --create-config | wc -l
实测回显:
267
- 示例/进阶骨架:
--create-example-config与--create-advanced-config打印带更多注释和高级段的版本,适合研究参数时对照(命令存在性见--help回显,本文第七章)。
三条路产出的都是「全量骨架」——267 行里包含未启用的后端与被注释的备选行,拿到手后按需要裁剪即可,Gerbera 对「骨架里存在但未启用的节」宽容度很高(见 2.3 的校验警告实测)。
1.3 生效规则与 CLI 辅助命令
三条硬规则,全部经实测确认:
- 改配置必须重启。config.xml 只在启动时被读取,日志里固定走
Parsing configuration...→Validating configuration...两段,运行期间改文件不会热生效。本次所有改值实验都靠docker restart gerbera-3.3.0-main生效。 - 启动参数覆盖配置文件。分发包启动变量
IMAGE_PORT=4949最终转成--port参数,覆盖 config.xml 的<port>,两边必须一致(部署篇第二章)。 - 校验可以离线做。改完先校验再重启,不影响在跑服务:
docker exec gerbera-3.3.0-main gerbera -c /var/run/gerbera/config.xml --check-config
实测回显(对当前生产配置校验通过):
2026-10-28 23:03:38 info: Loading configuration from: /run/gerbera/config.xml
2026-10-28 23:03:38 info: Parsing configuration...
2026-10-28 23:03:38 warning: Error in configuration, could not find command "ffmpeg" in $PATH for '/config/attribute::command'
2026-10-28 23:03:38 warning: Error in configuration, could not find command "vlc" in $PATH for '/config/attribute::command'
2026-10-28 23:03:38 info: Configuration load succeeded.
2026-10-28 23:03:38 info: Validating configuration...
2026-10-28 23:03:38 warning: Found extra config file entry '/config/server/storage/postgres/database'
2026-10-28 23:03:38 warning: Found extra config file entry '/config/server/storage/sqlite3/backup'
2026-10-28 23:03:38 info: Configuration check succeeded.
另有两条与配置相关的 CLI 组合:--print-options 打印全部「简单选项」的编号清单,--set-option 编号=值 可在命令行临时覆盖某项而不改文件。编号清单节选(全文见运维篇):
0 [/server/port] : Number = 0
3 [/server/name] : String = Gerbera
13 [/server/udn] : String = grb_udn_auto
18 [/server/alive] : Number = 180
23 [/server/ui/attribute::enabled] : Boolean = yes
29 [/server/ui/accounts/attribute::enabled] : Boolean = no
106 [/import/attribute::hidden-files] : Boolean = no
137 [/import/autoscan/attribute::use-inotify] : Boolean = auto
172 [/transcoding/attribute::enabled] : Boolean = no
编号对应 XPath 风格的路径(如 /server/ui/accounts/attribute::enabled 对应 <ui><accounts enabled=...>),看路径就知道该去 config.xml 的哪个位置改。注意这份清单打印的是内置默认值(如 29 号 accounts 默认 no、172 号 transcoding 默认 no),与当前生效值可能不同。
二、server 节:网络、界面与存储
<server> 节管「服务自身」:监听什么地址、Web UI 怎么认证、数据存哪里。本文实测配置的这一节全文如下,逐块拆解。
2.1 网络与设备身份
<server>
<port>4949</port>
<virtualURL>http://192.168.146.128:8136/</virtualURL>
<name>Gerbera</name>
<udn>uuid:389848a0-d60d-4fe1-a83f-cdfc2bcd5a99</udn>
<home>/var/run/gerbera/</home>
<webroot>/usr/local/share/gerbera/web</webroot>
<alive>180</alive>
<port>4949:HTTP 服务端口,Web UI、UPnP 描述文档、媒体流传输三合一。默认骨架没有此行(内置默认 0 = 自动选择,UPnP 规范推荐落在 49152 以上临时端口段);--help里-p选项也标注must be >=49152,但实测 4949 绑定正常——规范建议未被强制。CLI 的-i/--ip、-e/--interface可进一步限定绑定地址或网卡,多网卡机器用得上。<virtualURL>:所有对外 URL 的基准。不配时 Gerbera 用实例内地址(本栈为10.89.56.10:4949)生成 SSDP 宣告与媒体流 URL,桥接网络下局域网客户端够不到;显式填宿主地址后,CDS Browse 返回的每条媒体 URL 都是http://192.168.146.128:8136/...形态(部署篇 6.3 有回显)。桥接部署必配。<name>:服务器显示名,直接成为 UPnP 描述文档的<friendlyName>——局域网客户端列表里看到的就是它。实测改值验证:把<name>改为QuzuoLab-Gerbera并重启后拉描述文档:
docker restart gerbera-3.3.0-main
curl -s http://192.168.146.128:8136/upnp/description.xml | grep -i friendlyName
实测回显:
<friendlyName>QuzuoLab-Gerbera</friendlyName>
改回 Gerbera 重启后再查,回显恢复 <friendlyName>Gerbera</friendlyName>。除 name 外,print-options 清单 4~11 号还有 manufacturer / modelName / modelNumber 等「设备名片」字段,都会进描述文档,一般保持默认。
<udn>:UPnP 设备唯一标识,首启随机生成一次后不要再动——客户端靠它判断「还是不是原来那台服务器」,改了等于换设备,已收藏的内容会失效。<home>/<webroot>:运行数据目录与 Web UI 静态资源目录,分发包内默认即正确,勿改。<alive>180:SSDP 存活宣告周期(秒)。骨架自带注释把算法写得很清楚:每 (A/2)-30 秒发一次 ssdp:alive,缓存期 max-age=A;A=180 即每 60 秒宣告一次,最小可配 62。
💡 技术拓展:ssdp:alive 里的「alive」不是 TCP keepalive。UPnP 发现是「宣告-缓存」模型:服务周期性向组播地址 239.255.255.250:1900 喊「我还活着」,客户端收到后记入本地缓存并按 max-age 过期。alive 值越小客户端感知越灵敏,但组播流量越密;180 秒是局域网场景的均衡点。
2.2 Web UI 与账号(ui / accounts)
<ui enabled="yes" show-tooltips="yes">
<accounts enabled="yes" session-timeout="30">
<account user="admin" password="q1w2e3r4" />
</accounts>
</ui>
ui enabled="yes":Web UI 总开关。关掉后 HTTP 端口仍在(UPnP 要用),但管理界面不可用。accounts enabled="yes":账号保护开关。默认骨架是enabled="no"——免登录,任何能摸到端口的人都能管理媒体库,公网或多人环境务必打开。打开后登录走「get_sid → get_token → login」三步挑战-应答握手(完整实测见部署篇 4.3)。session-timeout="30":会话空闲 30 分钟失效。<account>可写多行配多个账号;密码明文存放,config.xml 本身要管好权限(本次以只读挂载,实例内也改不了它)。
实测改值验证:把 accounts enabled 改为 no 重启后,未登录直接取会话即返回已登录态:
curl -s 'http://192.168.146.128:8136/interface?req_type=auth&action=get_sid'
enabled="no" 时回显:
{
"GerberaSID" : "ffdc17a6-626f-4639-9e19-bc79394aadb0",
"logged_in" : true,
"sid_was_valid" : false,
"success" : true
}
改回 enabled="yes" 重启后再取,同一会话接口返回 "logged_in" : false,必须走完三步握手才放行。两组回显对照,开关行为一目了然。
print-options 清单里还有几个 UI 微调项(24~36 号):poll-interval=2(界面轮询秒数)、items-per-page=25、show-thumbnail=yes、show-video=no(界面里是否显示视频节)等,按需在 config.xml 的 <ui> 上以同名属性补写。
2.3 存储三后端(storage)
<storage>
<sqlite3 enabled="no">
<database-file>gerbera.db</database-file>
<backup enabled="yes" interval="600" />
</sqlite3>
<mysql enabled="yes">
<host>10.89.56.20</host>
<port>3306</port>
<username>gerbera</username>
<password>q1w2e3r4</password>
<database>gerbera</database>
</mysql>
<postgres enabled="no">
<host>localhost</host>
<username>gerbera</username>
<database>gerbera</database>
</postgres>
</storage>
三个后端并列声明、用 enabled 互斥开关,同时只能启用一个:
- sqlite3:默认启用。
database-file相对<home>解析;<backup enabled interval>是 SQLite 专属的内置定时备份(每 600 秒把库文件复制一份)——MySQL/PostgreSQL 没有对应物,外部数据库的备份交给 mariadb-dump / pg_dump(运维篇第三章)。 - mysql:本文启用。五字段之外,print-options 61~73 号给出隐藏默认值:
socket(本机 Unix socket 连接时用)、engine=MyISAM、charset=utf8、collation=utf8_general_ci。建库后可在mt_internal_setting表里看到这些值落盘为永久记录。 - postgres:结构与 mysql 节相同,编译开关 WITH_PGSQL ON,按需启用。
启用 MySQL 后,sqlite3/postgres 两节的子键就成了「多余条目」,启动校验逐条点名警告:
2026-10-28 20:37:12 warning: Found extra config file entry '/config/server/storage/postgres/database'
2026-10-28 20:37:12 warning: Found extra config file entry '/config/server/storage/postgres/host'
2026-10-28 20:37:12 warning: Found extra config file entry '/config/server/storage/sqlite3/backup'
2026-10-28 20:37:12 warning: Found extra config file entry '/config/server/storage/sqlite3/database-file'
这是提示而非错误——校验器只是告诉你这些节不参与运行,留着它们方便随时切后端。真正的硬错误(如数据库连不上)会在 Configuration check succeeded. 之后才暴露,部署篇第七章的崩溃循环就是例证。
<host> 的取值是本次部署最大的坑位:必须填数据库实例在栈内网络的真实地址(固定 IP 10.89.56.20 或服务名 db),写错一个不存在地址会让 Gerbera 启动即崩(mysql_error 2002,完整复盘见部署篇第七章)。
2.4 动态文件夹(containers)
<containers enabled="yes">
<container location="/LastAdded" title="Recently Added" sort="-last_updated">
<filter>upnp:class derivedfrom "object.item" and last_updated > "@last7"</filter>
</container>
<container location="/LastModified" title="Recently Modified" sort="-last_modified">
<filter>upnp:class derivedfrom "object.item" and last_modified > "@last7"</filter>
</container>
<container location="/LastPlayed" title="Music Recently Played" sort="-upnp:lastPlaybackTime" upnp-shortcut="MUSIC_LAST_PLAYED">
<filter>upnp:class derivedfrom "object.item.audioItem" and upnp:lastPlaybackTime > "@last7"</filter>
</container>
</containers>
💡 技术拓展:这里的「动态文件夹」(UPnP 类名
object.container.dynamicFolder)既不是物理目录也不是虚拟布局节点——它是一条保存下来的搜索条件:每次有客户端浏览它时按<filter>现场查库生成内容。普通目录删了文件要重扫才消失,动态文件夹里则是查库即所得,永远最新。
三个默认框分别是「最近入库 / 最近改动 / 最近播放的音频」。要点:
<filter>用 UPnP 搜索语法子集:derivedfrom做类继承匹配,"@last7"是相对时间字面量(近 7 天)。XML 里>必须写成>。sort="-last_updated":属性值前缀减号表示降序。upnp-shortcut="MUSIC_LAST_PLAYED":把该框登记为 UPnP 快捷方式,部分客户端会直接把它放进侧栏。
实测 CDS Browse 根目录,7 个顶级框里末尾三个就是它们(前四个来自虚拟布局,见 3.2):
object.container PC Directory
object.container Audio
object.container Photos
object.container Video
object.container.dynamicFolder Music Recently Played
object.container.dynamicFolder Recently Modified
object.container.dynamicFolder Recently Added
新增自定义视图就是照葫芦画瓢加一节 <container>:改 location(URL 路径)、title(显示名)、filter(筛选条件)三处即可。
2.5 扩展运行时(extended-runtime-options)
<extended-runtime-options>
<ffmpegthumbnailer enabled="yes">
<thumbnail-size>160</thumbnail-size>
<seek-percentage>5</seek-percentage>
<filmstrip-overlay>no</filmstrip-overlay>
<image-quality>8</image-quality>
</ffmpegthumbnailer>
<mark-played-items enabled="no" suppress-cds-updates="yes">
<string mode="prepend">*</string>
<mark>
<content>video</content>
</mark>
</mark-played-items>
</extended-runtime-options>
- ffmpegthumbnailer:视频缩略图。
thumbnail-size=160像素、seek-percentage=5在影片 5% 处取帧、image-quality=8JPEG 质量。依赖编译开关 WITH_FFMPEGTHUMBNAILER(本编译 ON,运维篇--compile-info可查)。 - mark-played-items:已播标记。启用后播放过的条目标题前会被加上
<string>指定的前缀(默认*,mode="prepend"也可改 append);<mark><content>video</content></mark>限定只对视频生效。suppress-cds-updates="yes"表示标记变化时不向客户端推送 CDS 更新事件,避免播放进度刷屏。
print-options 94~104 号还有 lastfm 子节(WITH_LASTFM ON 但默认关闭),用于把播放记录上报 Last.FM,此处从略。
三、import 节:扫库、布局与映射
<import> 节管「内容怎么进来、进来后怎么摆」:监视哪些目录、按什么规则识别类型、在客户端眼里摆成什么树。这是三大节里最长的一节。
3.1 autoscan 自动扫描
<import hidden-files="no">
<autoscan use-inotify="auto">
<directory location="/mnt/content" mode="inotify" recursive="yes" hidden-files="no" media-type="Any" />
</autoscan>
use-inotify="auto":内核支持 inotify 就启用(本编译 WITH_INOTIFY ON)。<directory>五属性:location实例内路径(本次挂 media 目录到/mnt/content)、mode="inotify"实时模式、recursive="yes"递归子目录、hidden-files="no"跳过点开头文件、media-type="Any"全类型。- 外层
hidden-files="no"是 import 全局开关,与 directory 级属性可分别控制。
静态声明的扫描行为已在部署篇实测:首启全量扫出 74 个条目,inotify 模式下 cp 一个新文件 4 秒后条目数 74 → 85(1 条实体 + 10 条虚拟布局引用),全程零干预。
一个容易误判的事实:config.xml 静态声明的 autoscan 不落 mt_autoscan 表。实测该表 0 行:
docker exec gerbera-3.3.0-mariadb mariadb -ugerbera -pq1w2e3r4 gerbera \
-e 'SELECT COUNT(*) AS autoscan_rows FROM mt_autoscan;'
autoscan_rows
0
只有 Web UI 里手动添加的目录才会写这张表(并带 persistent 标记)。两种来源并存时的冲突行为(静态配置压回动态修改)在运维篇第四章有完整实测。
3.2 脚本化导入与虚拟布局(scripting / virtual-layout)
<scripting script-charset="UTF-8">
<script-folder>
<common>/usr/local/share/gerbera/js</common>
<custom>/mnt/customization/js</custom>
</script-folder>
<import-function>
<playlist>importPlaylist</playlist>
<meta-file>importMetadata</meta-file>
<cuesheet>importCuesheet</cuesheet>
<audio-file>importAudio</audio-file>
<video-file>importVideo</video-file>
<image-file>importImage</image-file>
</import-function>
<virtual-layout type="js">
<boxlayout>
<box key="Audio/allAlbums" title="Albums" class="object.container" upnp-shortcut="MUSIC_ALBUMS" />
<box key="Audio/allArtists" title="Artists" class="object.container" upnp-shortcut="MUSIC_ARTISTS" />
...
</boxlayout>
</virtual-layout>
</scripting>
💡 技术拓展:boxlayout 的「box」不是播放列表也不是物理目录,而是虚拟布局里的一个归口框——每个文件入库时,JS 导入脚本读取它的元数据(艺术家、专辑、年代……),按 boxlayout 里声明的框把引用分别挂进各个归口。所以一个文件在「按艺术家」「按专辑」「按年代」里各出现一次,数据库里就是 1 条实体 + N 条引用(
ref_id指回实体),部署篇 5.1 的 8 文件变 74 条目正是这个机制。
Gerbera 3.3.0 默认 boxlayout 共 45 个 <box>,按 key 的路径式命名分为几大族:
- Audio 族(11 框):Albums / Artists / All Audio / Composers / Directories / Genres / All Songs / allTracks / Year / artistChronology 等;
- AudioInitial / AudioStructured 族(9 框):按首字母、按前缀分组(
size="6"表示每 6 个一组)的增强音频视图; - Video / Image / ImageDetail 族(12 框):按年份、日期、目录归口;
- Topic / Playlist 族(5 框):播客类主题与播放列表;
- Root / PCDirectory(2 框):根与物理目录树。
upnp-shortcut 属性把框登记为 UPnP 标准快捷方式(如 MUSIC_ALBUMS),支持快捷方式的客户端会直接生成「专辑」侧栏入口。custom 脚本目录(本次挂到 /mnt/customization/js)可放自定义 JS 覆盖默认导入逻辑,是进阶改造的入口。
虚拟布局的效果已在部署篇 6.3 实测印证——CDS Browse 递归遍历可见「Audio → Albums → Synth Lab → 曲目」正是 boxlayout 里 Audio/allAlbums 框的产物。
3.3 映射四表(mappings)
文件从磁盘到客户端眼里要过四道映射,全部集中在 <mappings> 节:
扩展名 ──extension-mimetype──▶ MIME 类型 ──mimetype-upnpclass──▶ UPnP 类
MIME 类型 ──mimetype-contenttype──▶ 内部内容类型 ──contenttype-dlnaprofile──▶ DLNA profile
MIME 类型 ──mimetype-dlnatransfermode──▶ DLNA 传输模式
- extension-mimetype(31 条
<map>):按扩展名定 MIME,如mp3 → audio/mpeg、mkv → video/x-matroska。ignore-unknown="no"表示扩展名查不到时继续用其他手段识别而不是直接丢弃。表尾两行被注释的 avi 映射是为 PS3、D-Link 等老客户端准备的兼容开关,按需解开。 - mimetype-upnpclass:MIME 决定 UPnP 类,通配符写法
audio/* → object.item.audioItem.musicTrack一条覆盖所有音频。 - mimetype-contenttype(21 条
<treat>):把 MIME 归并成 Gerbera 内部内容类型(contenttype),如audio/mpeg as mp3、audio/x-mpegurl as playlist——播放列表、cue 表等特殊处理都靠这道归并触发。 - mimetype-dlnatransfermode + contenttype-dlnaprofile:给 DLNA 客户端的两张声明表,前者标传输模式(音频视频
Streaming、字幕文本Background、图片Interactive),后者标 DLNA profile 名(如mp3 → MP3、jpg → JPEG_LRG)。
💡 技术拓展:DLNA profile(如
JPEG_LRG、AVC_MP4_EU)不是 config.xml 里转码节的 profile,而是 DLNA 协议给「一类编码参数组合」起的标准名字——客户端报自己支持哪些 profile,服务器按这两张表在 protocolInfo 里标注每条媒体的 profile,双方对得上才播。名字撞车是 Gerbera 配置里最常见的阅读障碍。
实测入库结果印证映射链。查实体条目(ref_id IS NULL 排除虚拟布局引用):
docker exec gerbera-3.3.0-mariadb mariadb -ugerbera -pq1w2e3r4 gerbera \
-e "SELECT id,dc_title,mime_type,upnp_class FROM mt_cds_object WHERE object_type=2 AND ref_id IS NULL ORDER BY id;"
实测回显:
id dc_title mime_type upnp_class
3 tone660 audio/mpeg object.item.audioItem.musicTrack
32 photo image/jpeg object.item.imageItem
46 tone990 audio/mpeg object.item.audioItem.musicTrack
57 tone880 audio/mpeg object.item.audioItem.musicTrack
68 tone440 audio/mpeg object.item.audioItem.musicTrack
79 tone220 audio/mpeg object.item.audioItem.musicTrack
90 clip video/mp4 object.item.videoItem
97 tone audio/flac object.item.audioItem.musicTrack
133 tone1100 audio/mpeg object.item.audioItem.musicTrack
注意 97 号 tone.flac:flac 不在 extension-mimetype 的 31 条里,它的 audio/flac 是 <magic-file> 指向的 libmagic 内容嗅探兜底识别的(本编译 WITH_MAGIC ON;<magic-file></magic-file> 留空即用系统默认 magic 库),再走 audio/* 通配归入 musicTrack。扩展名表与 magic 是「先查表、后嗅探」的两级识别。
3.4 字符集与杂项
print-options 106~117 号给出 import 的默认行为参数,需要时在 <import> 上以同名子键/属性补写:
- 四套字符集默认全 UTF-8:
filesystem-charset(文件名)、metadata-charset(标签内文本)、playlist-charset、script-charset。老旧 GBK 标签的中文曲库才把metadata-charset改成 GBK。 follow-symlinks=yes:跟随符号链接扫库;nomedia-file=.nomedia:目录里出现该文件即整目录跳过(与 Android 同名机制一致)。
四、transcoding 节:转码
<transcoding enabled="yes">
<mimetype-profile-mappings>
<transcode mimetype="application/ogg" using="vlcmpeg" />
<transcode mimetype="audio/ogg" using="ogg2mp3" />
<transcode mimetype="audio/x-flac" using="int2mp3" />
<transcode mimetype="video/x-flv" using="vlcmpeg" />
</mimetype-profile-mappings>
<profiles>
<profile name="int2mp3" enabled="yes" type="internal">
<mimetype>audio/mpeg</mimetype>
<accept-url>no</accept-url>
<first-resource>yes</first-resource>
<accept-ogg-theora>yes</accept-ogg-theora>
<encoder format="mp3" acodec="mp3" afilter="anull" />
</profile>
<profile name="ogg2mp3" enabled="no" type="external">
...
<agent command="ffmpeg" arguments="-y -i %in -f mp3 %out" />
<buffer size="1048576" chunk-size="131072" fill-size="262144" timeout="10" retry-count="4" />
</profile>
<profile name="vlcmpeg" enabled="no" type="external">
...
<agent command="vlc" arguments="-I dummy %in --sout #transcode{...}:standard{...} vlc://quit" />
<buffer size="14400000" chunk-size="512000" fill-size="120000" timeout="2" retry-count="2" />
</profile>
</profiles>
</transcoding>
💡 技术拓展:DLNA 语境的「转码」(transcoding)是把媒体流实时换成另一种编码再发给客户端,与「转封装」(remux,只换容器不换编码)和「直通」(passthrough,原样发)是三件事。Gerbera 的转码分两种形态:internal 用编译进进程的 libav* 编解码库(WITH_AVCODEC ON,零外部依赖);external fork 一个外部命令(ffmpeg/vlc)通过管道喂流。
结构是「映射 + 定义」两层:mimetype-profile-mappings 按 MIME 指派用哪个 profile,profiles 里定义每个 profile。默认骨架给了三个样例:
- int2mp3(internal,enabled=yes):FLAC → MP3 进程内转码。
encoder format="mp3" acodec="mp3" afilter="anull"是 libav 参数;first-resource=yes表示转码结果作为首选资源发给客户端。这就是本次<transcoding enabled="yes">下唯一真正生效的转码路径——客户端拉 flac 时拿到的是 MP3 流。 - ogg2mp3(external,enabled=no):ffmpeg 命令行样例,
%in/%out是管道占位符;<buffer>五参数控制管道缓冲与超时重试。 - vlcmpeg(external,enabled=no):vlc 的 sout 串转视频为 MPEG-PS。
external profile 引用的命令必须在 PATH 里找得到,否则启动校验报警告:
2026-10-28 20:37:12 warning: Error in configuration, could not find command "ffmpeg" in $PATH for '/config/attribute::command'
2026-10-28 20:37:12 warning: Error in configuration, could not find command "vlc" in $PATH for '/config/attribute::command'
本分发包未预装 ffmpeg/vlc 命令,两条警告因此常驻;profile 处于 enabled="no" 时这只是提示。真要启用 external 转码,需换用带ffmpeg 的分发包或自行加装——工作量不小,优先考虑 internal 转码或在客户端侧解决兼容性。
最后注意 <transcoding enabled> 是总开关:骨架默认 no,本文显式开成 yes;总开关关掉时整节失效,连 internal profile 也不工作。
五、改动 checklist 与常见坑
把本次实测的经验压缩成一张改动流程清单:
- 改前备份:
cp config/config.xml config/config.xml.bak。 - 改后离线校验:
gerbera -c ... --check-config,看到Configuration check succeeded.再重启。 - 重启生效:
docker restart gerbera-3.3.0-main(无热加载)。 - 复核三板斧:日志末尾出现
Server bound to+ Web UI 链接两行;curl description.xml看 friendlyName/UDN;curl get_sid看登录态是否符合 accounts 设置。
高频坑位:
<host>写错 → 启动即崩、自动重启放大成崩溃循环(部署篇第七章完整复盘)。- IMAGE_PORT 与
<port>不一致 → Web UI 与 UPnP 端口分叉,客户端能看到描述文档却拉不到流。 - 改
<udn>→ 客户端视为全新设备,收藏与「继续播放」全部失效。 - external 转码引用未安装命令 → 校验警告常驻,启用后拉流才真失败;先看 PATH 再 enable。
- 静态 autoscan 与 Web UI 动态添加混用 → 冲突时静态配置优先,动态修改被拒(运维篇第四章实测)。
六、参考链接
- 官方文档配置章节:
https://docs.gerbera.io/en/stable/config-server.html(及同站 config-import / config-transcode 页) - 配置 schema 在线 XSD:
http://gerbera.io/config/2.xsd - GitHub 主仓库(含 default config 模板):
https://github.com/gerbera/gerbera - 本专栏部署篇:《Gerbera Docker Compose 部署实战》
- 本专栏认知篇:《Gerbera 介绍与选型指南》
免责声明:本文全部配置样例与回显于 2026-10-28 在 Gerbera v3.3.0 + MariaDB 11.8 环境实测,文中路径、地址、账号(admin/q1w2e3r4)均为本次部署实例值,读者复现时请按自身环境替换。