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,全部回显逐行照抄。

GerberaGerberaUPnPDLNA媒体服务器2026/10/28

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 时有三条路:

  1. 首启自动生成:不挂载任何配置直接启动,Gerbera 在运行数据目录自动生成一份默认 config.xml(SQLite 后端、免登录),部署篇 3.1 节用的就是这条路的产物。
  2. CLI 打印骨架:不启动服务,直接让 CLI 把标准骨架打到标准输出:
docker exec gerbera-3.3.0-main gerbera --create-config | wc -l

实测回显:

267
  1. 示例/进阶骨架:--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 &gt; "@last7"</filter>
  </container>
  <container location="/LastModified" title="Recently Modified" sort="-last_modified">
    <filter>upnp:class derivedfrom "object.item" and last_modified &gt; "@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 &gt; "@last7"</filter>
  </container>
</containers>

💡 技术拓展:这里的「动态文件夹」(UPnP 类名 object.container.dynamicFolder)既不是物理目录也不是虚拟布局节点——它是一条保存下来的搜索条件:每次有客户端浏览它时按 <filter> 现场查库生成内容。普通目录删了文件要重扫才消失,动态文件夹里则是查库即所得,永远最新。

三个默认框分别是「最近入库 / 最近改动 / 最近播放的音频」。要点:

  • <filter> 用 UPnP 搜索语法子集:derivedfrom 做类继承匹配,"@last7" 是相对时间字面量(近 7 天)。XML 里 > 必须写成 &gt;。
  • 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=8 JPEG 质量。依赖编译开关 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 传输模式
  1. extension-mimetype(31 条 <map>):按扩展名定 MIME,如 mp3 → audio/mpeg、mkv → video/x-matroska。ignore-unknown="no" 表示扩展名查不到时继续用其他手段识别而不是直接丢弃。表尾两行被注释的 avi 映射是为 PS3、D-Link 等老客户端准备的兼容开关,按需解开。
  2. mimetype-upnpclass:MIME 决定 UPnP 类,通配符写法 audio/* → object.item.audioItem.musicTrack 一条覆盖所有音频。
  3. mimetype-contenttype(21 条 <treat>):把 MIME 归并成 Gerbera 内部内容类型(contenttype),如 audio/mpeg as mp3、audio/x-mpegurl as playlist——播放列表、cue 表等特殊处理都靠这道归并触发。
  4. 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 与常见坑

把本次实测的经验压缩成一张改动流程清单:

  1. 改前备份:cp config/config.xml config/config.xml.bak。
  2. 改后离线校验:gerbera -c ... --check-config,看到 Configuration check succeeded. 再重启。
  3. 重启生效:docker restart gerbera-3.3.0-main(无热加载)。
  4. 复核三板斧:日志末尾出现 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)均为本次部署实例值,读者复现时请按自身环境替换。