(formally called DLNAtoad but it now also does other stuff, code renaming will happen gradually)
A minimal media server in a single jar. On start up it will index the working directory and make any media found available via a web interface (defaults to port 8192) and via DLNA. Additional features like user management and tagging are optional and enabled via CLI flags.
It compiles to a runnable jar. Run it in the top directory you want to share.
Your DLNA device should magically detect it on your LAN. DLNA is magical like
that. Media files are identified purely on file extension. Known extensions are
in the src/main/java/com/vaguehope/dlnatoad/media/MediaFormat.java
file.
It's a Java Maven project.
$ mvn clean install
$ java -jar target/mediatoad-1-SNAPSHOT-jar-with-dependencies.jar
You can include multiple specific root directories instead of defaulting to the current directory:
$ java -jar mediatoad.jar foo/ bar/
Instead of listing paths on the command line a text file of directories can be
given using the --tree
pointing to a file with one path per line.
Ideally it should not have write access to any of the media directories, it will never be needed as data is only ever stored in the DB.
If you want the web interface to show thumbnails the --thumbs
flag must point
to a directory where they can be written to. Thumbnails for images will be
generated as part of scanning for files on start up and whenever new files are
found.
Thumbnails for videos can be enabled per-directory, though this is very experimental. Users with +editdirprefs can find this option at the bottom of each directory page. This uses ffmpeg which much be available in PATH.
If you want metadata to be collected and used, use --db
to specify where this
data should be stored. It will be created if it does not exist. This sqlite DB
will also be used for storing any tags added to files.
All files will be hashed so that metadata can be reassociated when a file is moved or renamed. Metadata will be preserved so long as file content and name do not change at the same time - leave sufficient time for each change to be fully observed.
If a DB is provided to store it, media info like duration etc will be read using
ffprobe
. If ffprobe can not be found on PATH
this will be skipped.
WARNING: this auth system is BEST EFFORT, do not trust it to protect anything important. Auth changes are only loaded on startup and are not dynamically updated. The process must be restarted after any auth changes.
Directories can be restricted to specific users and users must have explicit permission to edit item tags. Any directory protected with an AUTH file will not be exported via DLNA, since that has no concept of permissions.
Uses are listed in a text file specified by the --userfile
flag in the format
described below. Additionally --sessiondir
must point to an empty writable
directory where session tokens can be stored. For obvious security reasons no
other processes on the system should be able to read or write to the directory.
The users file has the following format:
$username $bcrypt_hash $permissions
For example this specifies 2 users. user1 has permission to edit tags in directories where they have permission. user2 has read-only access irrespective of per-direction permissions.
user1 $2a$10$su3ctfwMCULBeBvk0WDffuyGV/rJki4IZrFHrqs8XjtCXykMs5wii +edittags +editdirprefs
user2 $2a$10$wV3v3YKOS4Iy8IFoA.ucnugDRrDMWdx2yv3Jx5rc0JCgtEWHmQMNi
Currently there is no sign-up page in the UI, but users can be added on the command line with the following command. Alternatively just ask them to generate and send a bcrypt hash :3.
$ java -jar target/mediatoad-1-SNAPSHOT-jar-with-dependencies.jar --userfile $path_to_file --adduser
Directories are protected by placing AUTH files in them listing one username per line. Each name may be followed by permissions. In the following example, user1 has permission to view and to add and remove tags. user2 has read-only access. No other users have any access.
user1 +edittags +editdirprefs
user2
If a subdirectory has its own AUTH file a user must appear in all AUTH files in parent directories to have access. Permissions are taken from the first AUTH file found going back up the directory tree.
Tag determiners (TD) are a mechanism to use external processes (such as ML
models) to automatically add tags to content. A TD implements the simple RPC
service in src/main/proto/tagdeterminer.proto
. The TD will be send the file
content and mimetype, and returns a list of tags that will be added to the item.
Which files have already been send to the TD is tracked by added a hidden tag (a
tag with a class starting with a '.'), which the TD returns from About
RPC in
the tag_cls
field.
To connect to a TD use the --tagdeterminer
flag, which specifies the URL of
the service and which content should be sent to it in the format URL|query
:
--tagdeterminer 'https://my-service.example.com|f~/mnt/photos/ OR f~/mnt/pictures/'
The query syntax is the same as used in the web UI. Multiple TDs can be configured by repeating the flag.
There are 2 query engines depending on if a DB is used or not. If there is no DB, then it is a simple substring search of filenames. If DB is enabled, there is the syntax described below.
NOTE This syntax is somewhat work-in-progress and may change. This
documentation may be incomplete, see DbSearchParserTest
for tested examples.
query | what it matches |
---|---|
foo |
file path or tags containing foo |
f~foo |
file path containing foo |
f~^/foo |
file path starting with /foo |
f~foo$ |
file path ends with foo |
-f~foo |
file path does not contain foo |
t=foo |
exact tag foo |
-t=foo |
not exact tag foo |
t~foo |
tag containing foo |
t~^foo |
tag starts with foo |
t~foo$ |
tag ends with foo |
-t~foo |
tag not containing foo |
t>3 |
has 4 or more tags |
t<3 |
has 2 or fewer tags |
w=1920 h>1080 |
width exactly 1920 pixels and height is more than 1080 pixels |
w>=2000 h<=1000 |
width is 2000 pixels or more, height is 1000 pixels or less |
type=image |
mimetype starts with image/ |
type=image/jpeg |
mimetype is exactly image/jpeg |
dupes>0 |
has 1 or more duplicates, based on file hash |
t="foo bar" |
exact tag foo bar |
t="foo\"bar" |
exact tag foo"bar |
t=foo OR t~bar |
exact tag foo or tag containing bar |
t=foo OR (f~bar t=baz) |
exact tag foo or both file path contains bar and exact tag baz |
"
or '
can be used.t=fo"o b"ar
is the same as
t="foo bar"
.\
to escape things.(
must be preceded by whitespace and close brackets )
must
be followed by whitespace, eg a(bcd)e
will be searched for as is.See the systemd
directory for an example unit file.
To make working on HTML/JS/CSS files easier, there are flags to override where static files and templates are read from so refreshing the page shows changes immediately.
$ java -jar target/mediatoad-1-SNAPSHOT-jar-with-dependencies.jar --accesslog --webroot src/main/resources/wui --templateroot src/main/resources/templates