go install github.com/anacrolix/dms@latest
Go must be installed and $GOPATH/bin (or $HOME/go/bin) must be in your PATH.
docker pull ghcr.io/anacrolix/dms:latest
docker run -d --network host -v /path/to/media:/dmsdir ghcr.io/anacrolix/dms:latest--network host is required for SSDP/UPnP discovery to work.
A sample service file is provided at helpers/systemd/dms.service. Copy it to /etc/systemd/system/ and adjust the ExecStart path and media directory as needed.
Install the service file at helpers/bsd/dms to /etc/rc.d or /usr/local/etc/rc.d, then add to /etc/rc.conf:
dms_enable="YES"
dms_root="/path/to/my/media" # optional
dms_user="myuser" # optional
Pre-built binaries use dynamic linking that doesn't work on NixOS. Install from source instead:
go install github.com/anacrolix/dms@latest
Pass -config /path/to/config.json. Example:
{
"path": "/path/to/media",
"friendlyName": "My Media Server",
"noTranscode": true,
"deviceIcon": "/path/to/icon.png",
"deviceIconSizes": ["48:512", "128:512"]
}Config file keys match the flag names (camelCase). Note: allowedIps in config files was broken before v1.7.2 — upgrade if you see issues.
dms serves a single root path. To serve multiple directories, create a parent directory and use symlinks:
mkdir ~/media
ln -s /path/to/movies ~/media/movies
ln -s /path/to/music ~/media/music
dms -path ~/mediaUse -allowedIps with a comma-separated list of IPs or CIDR ranges:
dms -allowedIps 192.168.1.0/24,10.0.0.1
Use -http :8080 (default is :1338). To listen on IPv6 only: -http [::]:1338. To listen on all interfaces including IPv6: -http [::]:1338.
dms -friendlyName "Living Room Server"
How do I ignore hidden files and dot-directories?
dms -ignoreHidden -ignoreUnreadable
dms -ignore thumbnails,thumbs,.git
dms -notifyInterval 60s
Default is 30s.
dms -ifname eth0
ffmpeg (or avconv) is optional. Without it, dms serves files directly. With it, dms can:
- Transcode video to mpeg2 PAL-DVD or WebM/VP8 (e.g. for Chromecast)
- Generate thumbnails (requires
ffmpegthumbnailerseparately)
dms -noTranscode
Or in config: "noTranscode": true
dms -forceTranscodeTo chromecast # WebM/VP8
dms -forceTranscodeTo vp8 # VP8
dms -noProbe
This disables bitrate/duration metadata but improves startup time on large libraries.
dms scans directories on demand rather than at startup, but older versions had a bug where childCount triggered a full recursive scan. This was fixed — upgrade to v1.7.0 or later.
Subtitle files are served, but client support varies. Most DLNA renderers need to handle subtitle loading themselves. This is a known limitation — see issue #140.
Yes, audio files are served directly. If they're not appearing, check that the files have standard media extensions and are readable. Run with -logHeaders to see what the client is requesting.
dms prefers ffmpeg/ffprobe and falls back to avconv/avprobe. Ensure ffmpeg is in your PATH and it will be used automatically.
Enable dynamic streams with -allowDynamicStreams and create a .dms.json file in your media directory:
{
"Title": "My Camera",
"Resources": [
{
"MimeType": "video/webm",
"Command": "ffmpeg -i rtsp://camera-ip:554/stream -c:v copy -c:a copy -f matroska -"
}
]
}- Panasonic Viera TVs
- BubbleUPnP and AirWire (Android)
- Chromecast
- VLC (desktop and mobile)
- LG Smart TVs (with varying success)
- Roku devices
- Apple TV 4K (via VLC or 8player)
- iOS VLC and 8player
Samsung TVs can be picky about DLNA conformance. Try:
- Running without transcoding:
dms -noTranscode - If pause/seek doesn't work, this is a known issue (#165) — Samsung requires specific DLNA headers for transport control.
- For Samsung Frame TVs, ensure you're on v1.6.0 or later (#110).
Try the -stallEventSubscribe workaround:
dms -stallEventSubscribe
This was added specifically for older LG TVs that send malformed event subscription requests.
Windows 10's DLNA discovery uses UPnP multicast. Make sure:
- Your firewall allows UDP port 1900 (SSDP) and TCP port 1338 (HTTP)
- dms is bound to the correct network interface (
-ifname) - You're on the same subnet (DLNA does not cross routers by default)
DLNA relies on multicast which doesn't cross network boundaries. Use dlna-proxy to bridge between segments.
With very large libraries (e.g. 26k+ tracks), each browse triggers ffprobe on new files, which accumulates processes. Use -noProbe to disable ffprobe entirely, or use -noTranscode -noProbe if you don't need transcoding features. See issue #105.
- Ensure dms is running and listening:
curl http://localhost:1338/rootDesc.xml - Check that UDP port 1900 is not blocked by a firewall
- Try specifying the interface:
dms -ifname eth0 - On multi-homed hosts, try each interface name until one works
- If using Docker, ensure
--network hostis set
This is normal — it happens when a client stops playback before the transcode is finished. The errors are benign. See issue #129.
This was fixed in a recent version. Upgrade to the latest release. If still broken, ensure the symlink target is readable by the user running dms.
Always use an absolute path with -path:
dms -path /home/user/media # correct
dms -path ~/media # may not work in all shells
There is no -verbose flag currently (#126). Run with -logHeaders to see HTTP request/response headers. Transcode logs go to ~/.dms/log/ by default; change with -transcodeLogPattern.
dms -transcodeLogPattern /dev/null
A close of closed channel panic on Close() was fixed in v1.7.0. Upgrade if you're hitting this.