Homepage: https://github.com/flensrocker/vdr-plugin-avahi4vdr

What is it:
It's a helper, so you can easily announce network services of your vdr and its 
plugins to your LAN via avahi (a Zeroconf
implementation) or retrieve information about other network services (not 
limited to vdr such as nfs mounts etc.).
Please read the README at

I'm trying very hard to keep my README up-to-date. If there are questions 
please let me know.
Please get familiar with Avahi, the avahi-tools like avahi-browse, 
avahi-publish and their manpages.

How does it work:
The "static way" is using a file "services.conf" in the plugin's config 
directory. For an example please look at

 Please forgive my long post... :)

Server-Example: How to announce streamdev-server
 (aka announcing a static network service with fixed port)
# line in services.conf, for syntax and escaping see README
name=vdr-streamdev-server on 

name: is something to display to the user (%h will be replaced with the 
type: is the service type, there are standards, look at 
port: the port the service is listening on (handy for dynamic ports, since you 
can update the service on the fly and
reannounce a new port, but sadly not in this static example, you have to use 
the plugin's SVDRPCommand "CreateService"
for more control)
subtype: you can specify details of the service, streamdev is on the lowest 
level a webserver, hence the type
_http._tcp, but will publish special services with another "protocol", I 
suggest "_vdr_<plugin's name>.sub.<service
type>" if it's for a vdr plugin. You can specify as many subtypes as you want.
txt: you can add as many txt records to a service with service specific data 
(not used in this example, if you know
avahi, you'll understand).

On vdr startup, avahi4vdr connects to the avahi-daemon and will announce the 
streamdev-server. What for? Read next. :)

Example: How to find streamdev-server
 (suggestion as extension to streamdev-client, feel free to implement)
I will create a patch as soon as I can find time and really do need this 
fetaure at streamdev...

You can call avahi4vdr's SVDRPCommand directly for registering a browser for 

  int replyCode = 0;
  cString browserId; // remember this!
  cPlugin *avahi4vdr = cPluginManager::GetPlugin("avahi4vdr");
  if (avahi4vdr != NULL)
     browserId = avahi4vdr->SVDRPCommand("CreateBrowser",

If you don't need the browser anymore you can delete it anytime (will be done 
automatically on vdr-exit).
  if (avahi4vdr != NULL)
     avahi4vdr->SVDRPCommand("DeleteBrowser", *browserId, replyCode);

Your plugin's Service function will be called if the browser raises an event:
  bool cPluginDbus2vdr::Service(const char *Id, void *Data)
    if (strcmp(Id, "avahi4vdr-event") == 0) {
       cAvahiHelper options(Data);
       const char *event = options.Get("event");
       const char *browser_id = options.Get("id");
       if (strcmp(event, "browser-service-resolved") == 0) {
          const char *name = options.Get("name");
          const char *host = options.Get("host");
          const char *protocol = options.Get("protocol");
          const char *address = options.Get("address");
          const char *port = options.Get("port");
          const char *local = options.Get("local");
          const char *txt = NULL;
          int txt_nr = 0;
          while (true) {
                txt = options.Get("txt", txt_nr);
                if (txt == NULL)
       else if (strcmp(event, "browser-service-removed") == 0) {
          const char *name = options.Get("name");
          const char *protocol = options.Get("protocol");
          const char *local = options.Get("local");
       return true;
    return false;

cAvahiHelper is located at 
It's a helper class for parsing parameters, only header is needed, so just copy 
it to your plugin.

caller: (at CreateBrowser) the name of the plugin which should be called. You 
needn't to take your plugin's name. It's
possible to create browsers for other plugins. It's not a bug, it's a feature. 

Whenever the browser detects a new service, an event "browser-service-resolved" 
is emitted. streamdev-client should
instantiate a new device for each detected server (or reuse an unconnected 
device, multi-device support should be added
first to streamdev-client) and if a server shuts down (event 
"browser-service-removed") the corresponding device can be
"deactivated" (e.g. set to -none-).

No more editing ips or ports in config files... :)

For now there is just one "user" of the feature "dynamic publishing of 
services": dbus2vdr
It starts a dbus-daemon listening on a dynamic tcp port and publishes it as 
subtype "_vdr_dbus2vdr._sub._dbus._tcp". On
this separate dbus-daemon dbus2vdr just offers some read-only objects and 
methods like listing the timers or recordings.
Listing channels will be added soon.
I want to use these "dbus2vdr"-daemons to collect all timers from the stations 
on the LAN. I will add some simple logic
(will be announced next month or so) and then all vdrs will record every thing 
they want. Timer conflict check is not
yet planned, first incarnation will be "record everything I find important". 
Each vdr will decide on its own if it wants
to record the timer of the remote vdr. Please be patient, project is at 
planning/documentation state, I have nothing
coded yet.

 What would you like to do with avahi4vdr? Please let me know...

 Have fun!


vdr mailing list

Reply via email to