Merge pull request #7031 from cwoac/mediatomb

Add MediaTomb service

lethalman dc560b5b 33fb8e2d

+285
+2
nixos/modules/misc/ids.nix
··· 212 uptimed = 184; 213 zope2 = 185; 214 ripple-data-api = 186; 215 216 # When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399! 217 ··· 401 #uptimed = 184; # unused 402 #zope2 = 185; # unused 403 #ripple-data-api = 186; #unused 404 405 # When adding a gid, make sure it doesn't match an existing 406 # uid. Users and groups with the same name should have equal
··· 212 uptimed = 184; 213 zope2 = 185; 214 ripple-data-api = 186; 215 + mediatomb = 187; 216 217 # When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399! 218 ··· 402 #uptimed = 184; # unused 403 #zope2 = 185; # unused 404 #ripple-data-api = 186; #unused 405 + mediatomb = 187; 406 407 # When adding a gid, make sure it doesn't match an existing 408 # uid. Users and groups with the same name should have equal
+1
nixos/modules/module-list.nix
··· 191 ./services/misc/gitlab.nix 192 ./services/misc/gitolite.nix 193 ./services/misc/gpsd.nix 194 ./services/misc/mesos-master.nix 195 ./services/misc/mesos-slave.nix 196 ./services/misc/nix-daemon.nix
··· 191 ./services/misc/gitlab.nix 192 ./services/misc/gitolite.nix 193 ./services/misc/gpsd.nix 194 + ./services/misc/mediatomb.nix 195 ./services/misc/mesos-master.nix 196 ./services/misc/mesos-slave.nix 197 ./services/misc/nix-daemon.nix
+282
nixos/modules/services/misc/mediatomb.nix
···
··· 1 + { config, lib, pkgs, ... }: 2 + 3 + with lib; 4 + 5 + let 6 + 7 + uid = config.ids.uids.mediatomb; 8 + gid = config.ids.gids.mediatomb; 9 + cfg = config.services.mediatomb; 10 + 11 + mtConf = pkgs.writeText "config.xml" '' 12 + <?xml version="1.0" encoding="UTF-8"?> 13 + <config version="2" xmlns="http://mediatomb.cc/config/2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://mediatomb.cc/config/2 http://mediatomb.cc/config/2.xsd"> 14 + <server> 15 + <ui enabled="yes" show-tooltips="yes"> 16 + <accounts enabled="no" session-timeout="30"> 17 + <account user="mediatomb" password="mediatomb"/> 18 + </accounts> 19 + </ui> 20 + <name>${cfg.serverName}</name> 21 + <udn>uuid:${cfg.uuid}</udn> 22 + <home>${cfg.dataDir}</home> 23 + <webroot>${pkgs.mediatomb}/share/mediatomb/web</webroot> 24 + <storage> 25 + <sqlite3 enabled="yes"> 26 + <database-file>mediatomb.db</database-file> 27 + </sqlite3> 28 + </storage> 29 + <protocolInfo extend="${if cfg.ps3Support then "yes" else "no"}"/> 30 + ${if cfg.dsmSupport then '' 31 + <custom-http-headers> 32 + <add header="X-User-Agent: redsonic"/> 33 + </custom-http-headers> 34 + 35 + <manufacturerURL>redsonic.com</manufacturerURL> 36 + <modelNumber>105</modelNumber> 37 + '' else ""} 38 + ${if cfg.tg100Support then '' 39 + <upnp-string-limit>101</upnp-string-limit> 40 + '' else ""} 41 + <extended-runtime-options> 42 + <mark-played-items enabled="yes" suppress-cds-updates="yes"> 43 + <string mode="prepend">*</string> 44 + <mark> 45 + <content>video</content> 46 + </mark> 47 + </mark-played-items> 48 + </extended-runtime-options> 49 + </server> 50 + <import hidden-files="no"> 51 + <scripting script-charset="UTF-8"> 52 + <common-script>/nix/store/cngbzn39vidd6jm4wgzxfafqll74ybfa-mediatomb-0.12.1/share/mediatomb/js/common.js</common-script> 53 + <playlist-script>/nix/store/cngbzn39vidd6jm4wgzxfafqll74ybfa-mediatomb-0.12.1/share/mediatomb/js/playlists.js</playlist-script> 54 + <virtual-layout type="builtin"> 55 + <import-script>/nix/store/cngbzn39vidd6jm4wgzxfafqll74ybfa-mediatomb-0.12.1/share/mediatomb/js/import.js</import-script> 56 + </virtual-layout> 57 + </scripting> 58 + <mappings> 59 + <extension-mimetype ignore-unknown="no"> 60 + <map from="mp3" to="audio/mpeg"/> 61 + <map from="ogx" to="application/ogg"/> 62 + <map from="ogv" to="video/ogg"/> 63 + <map from="oga" to="audio/ogg"/> 64 + <map from="ogg" to="audio/ogg"/> 65 + <map from="ogm" to="video/ogg"/> 66 + <map from="asf" to="video/x-ms-asf"/> 67 + <map from="asx" to="video/x-ms-asf"/> 68 + <map from="wma" to="audio/x-ms-wma"/> 69 + <map from="wax" to="audio/x-ms-wax"/> 70 + <map from="wmv" to="video/x-ms-wmv"/> 71 + <map from="wvx" to="video/x-ms-wvx"/> 72 + <map from="wm" to="video/x-ms-wm"/> 73 + <map from="wmx" to="video/x-ms-wmx"/> 74 + <map from="m3u" to="audio/x-mpegurl"/> 75 + <map from="pls" to="audio/x-scpls"/> 76 + <map from="flv" to="video/x-flv"/> 77 + <map from="mkv" to="video/x-matroska"/> 78 + <map from="mka" to="audio/x-matroska"/> 79 + ${if cfg.ps3Support then '' 80 + <map from="avi" to="video/divx"/> 81 + '' else ""} 82 + ${if cfg.dsmSupport then '' 83 + <map from="avi" to="video/avi"/> 84 + '' else ""} 85 + </extension-mimetype> 86 + <mimetype-upnpclass> 87 + <map from="audio/*" to="object.item.audioItem.musicTrack"/> 88 + <map from="video/*" to="object.item.videoItem"/> 89 + <map from="image/*" to="object.item.imageItem"/> 90 + </mimetype-upnpclass> 91 + <mimetype-contenttype> 92 + <treat mimetype="audio/mpeg" as="mp3"/> 93 + <treat mimetype="application/ogg" as="ogg"/> 94 + <treat mimetype="audio/ogg" as="ogg"/> 95 + <treat mimetype="audio/x-flac" as="flac"/> 96 + <treat mimetype="audio/x-ms-wma" as="wma"/> 97 + <treat mimetype="audio/x-wavpack" as="wv"/> 98 + <treat mimetype="image/jpeg" as="jpg"/> 99 + <treat mimetype="audio/x-mpegurl" as="playlist"/> 100 + <treat mimetype="audio/x-scpls" as="playlist"/> 101 + <treat mimetype="audio/x-wav" as="pcm"/> 102 + <treat mimetype="audio/L16" as="pcm"/> 103 + <treat mimetype="video/x-msvideo" as="avi"/> 104 + <treat mimetype="video/mp4" as="mp4"/> 105 + <treat mimetype="audio/mp4" as="mp4"/> 106 + <treat mimetype="application/x-iso9660" as="dvd"/> 107 + <treat mimetype="application/x-iso9660-image" as="dvd"/> 108 + </mimetype-contenttype> 109 + </mappings> 110 + <online-content> 111 + <YouTube enabled="no" refresh="28800" update-at-start="no" purge-after="604800" racy-content="exclude" format="mp4" hd="no"> 112 + <favorites user="mediatomb"/> 113 + <standardfeed feed="most_viewed" time-range="today"/> 114 + <playlists user="mediatomb"/> 115 + <uploads user="mediatomb"/> 116 + <standardfeed feed="recently_featured" time-range="today"/> 117 + </YouTube> 118 + </online-content> 119 + </import> 120 + <transcoding enabled="${if cfg.transcoding then "yes" else "no"}"> 121 + <mimetype-profile-mappings> 122 + <transcode mimetype="video/x-flv" using="vlcmpeg"/> 123 + <transcode mimetype="application/ogg" using="vlcmpeg"/> 124 + <transcode mimetype="application/ogg" using="oggflac2raw"/> 125 + <transcode mimetype="audio/x-flac" using="oggflac2raw"/> 126 + </mimetype-profile-mappings> 127 + <profiles> 128 + <profile name="oggflac2raw" enabled="no" type="external"> 129 + <mimetype>audio/L16</mimetype> 130 + <accept-url>no</accept-url> 131 + <first-resource>yes</first-resource> 132 + <accept-ogg-theora>no</accept-ogg-theora> 133 + <agent command="ogg123" arguments="-d raw -o byteorder:big -f %out %in"/> 134 + <buffer size="1048576" chunk-size="131072" fill-size="262144"/> 135 + </profile> 136 + <profile name="vlcmpeg" enabled="no" type="external"> 137 + <mimetype>video/mpeg</mimetype> 138 + <accept-url>yes</accept-url> 139 + <first-resource>yes</first-resource> 140 + <accept-ogg-theora>yes</accept-ogg-theora> 141 + <agent command="vlc" arguments="-I dummy %in --sout #transcode{venc=ffmpeg,vcodec=mp2v,vb=4096,fps=25,aenc=ffmpeg,acodec=mpga,ab=192,samplerate=44100,channels=2}:standard{access=file,mux=ps,dst=%out} vlc:quit"/> 142 + <buffer size="14400000" chunk-size="512000" fill-size="120000"/> 143 + </profile> 144 + </profiles> 145 + </transcoding> 146 + </config> 147 + ''; 148 + 149 + in { 150 + 151 + 152 + ###### interface 153 + 154 + options = { 155 + 156 + services.mediatomb = { 157 + 158 + enable = mkOption { 159 + type = types.bool; 160 + default = false; 161 + description = '' 162 + Whether to enable the mediatomb DLNA server. 163 + ''; 164 + }; 165 + 166 + serverName = mkOption { 167 + type = types.string; 168 + default = "mediatomb"; 169 + description = '' 170 + How to identify the server on the network. 171 + ''; 172 + }; 173 + 174 + ps3Support = mkOption { 175 + type = types.bool; 176 + default = false; 177 + description = '' 178 + Whether to enable ps3 specific tweaks. 179 + WARNING: incompatible with DSM 320 support. 180 + ''; 181 + }; 182 + 183 + dsmSupport = mkOption { 184 + type = types.bool; 185 + default = false; 186 + description = '' 187 + Whether to enable D-Link DSM 320 specific tweaks. 188 + WARNING: incompatible with ps3 support. 189 + ''; 190 + }; 191 + 192 + tg100Support = mkOption { 193 + type = types.bool; 194 + default = false; 195 + description = '' 196 + Whether to enable Telegent TG100 specific tweaks. 197 + ''; 198 + }; 199 + 200 + transcoding = mkOption { 201 + type = types.bool; 202 + default = false; 203 + description = '' 204 + Whether to enable transcoding. 205 + ''; 206 + }; 207 + 208 + dataDir = mkOption { 209 + type = types.path; 210 + default = "/var/lib/mediatomb"; 211 + description = '' 212 + The directory where mediatomb stores its state, data, etc. 213 + ''; 214 + }; 215 + 216 + user = mkOption { 217 + default = "mediatomb"; 218 + description = "User account under which mediatomb runs."; 219 + }; 220 + 221 + group = mkOption { 222 + default = "mediatomb"; 223 + description = "Group account under which mediatomb runs."; 224 + }; 225 + 226 + port = mkOption { 227 + default = 49152; 228 + description = '' 229 + The network port to listen on. 230 + ''; 231 + }; 232 + 233 + uuid = mkOption { 234 + default = "fdfc8a4e-a3ad-4c1d-b43d-a2eedb03a687"; 235 + description = '' 236 + A unique (on your network) to identify the server by. 237 + ''; 238 + }; 239 + 240 + customCfg = mkOption { 241 + type = types.bool; 242 + default = false; 243 + description = '' 244 + Allow mediatomb to create and use its own config file inside ${cfg.dataDir}. 245 + ''; 246 + }; 247 + }; 248 + }; 249 + 250 + 251 + ###### implementation 252 + 253 + config = mkIf cfg.enable { 254 + systemd.services.mediatomb = { 255 + description = "MediaTomb media Server"; 256 + after = [ "local-fs.target" "network.target" ]; 257 + wantedBy = [ "multi-user.target" ]; 258 + path = [ pkgs.mediatomb ]; 259 + serviceConfig.ExecStart = "${pkgs.mediatomb}/bin/mediatomb -p ${toString cfg.port} ${if cfg.customCfg then "" else "-c ${mtConf}"} -m ${cfg.dataDir}"; 260 + serviceConfig.User = "${cfg.user}"; 261 + }; 262 + 263 + users.extraGroups = optionalAttrs (cfg.group == "mediatomb") (singleton { 264 + name = "mediatomb"; 265 + gid = gid; 266 + }); 267 + 268 + users.extraUsers = optionalAttrs (cfg.user == "mediatomb") (singleton { 269 + name = "mediatomb"; 270 + isSystemUser = true; 271 + group = cfg.group; 272 + home = "${cfg.dataDir}"; 273 + createHome = true; 274 + description = "Mediatomb DLNA Server User"; 275 + }); 276 + 277 + networking.firewall = { 278 + allowedUDPPorts = [ 1900 cfg.port ]; 279 + allowedTCPPorts = [ cfg.port ]; 280 + }; 281 + }; 282 + }