This binding acts as a UPnP control point to control UPnP AV media servers and media renderers as defined by the [UPnP Forum](https://openconnectivity.org/developer/specifications/upnp-resources/upnp/).
It discovers UPnP media servers and renderers in the local network.
UPnP AV media servers generally allow selecting content from a content directory.
UPnP AV media renderers take care of playback of the content.
You can select a renderer to play the media served from a server.
The full content hierarchy of the media on the server can be browsed hierarchically.
Searching the media library is also supported using UPnP search syntax.
Two thing types are supported, a server thing, `upnpserver`, and a renderer thing, `upnprenderer`.
The binding has been tested with the AV Media Server and AV Media Renderer from Intel Developer Tools for UPnP Technology, available [here](https://www.meshcommander.com/upnptools).
A second test set included a [TVersity Media Server](http://tversity.com/).
It complies with part of the UPnP AV Media standard, but has not been verified to comply with the full specification.
Tests have focused on the playback of audio, but if the server and renderer support it, other media types should play as well.
Both also have `refresh` configuration parameter. This parameter defines a polling interval for polling the state of the `upnprenderer` or `upnpserver`.
The default polling interval is 60s.
0 turns off polling.
An advanced configuration parameter `responseTimeout` permits tweaking how long the `upnprenderer` and `upnpserver` will wait for GENA events from the UPnP device.
This timeout is checked when there is a dependency between an action invocation and an event with expected result.
*`sortCriteria`: sort criteria for the titles in the selection list and when sending for playing to a renderer.
The criteria are defined in UPnP sort criteria format, examples: `+dc:title`, `-dc:creator`, `+upnp:album`.
Support for sort criteria will depend on the media server.
The default is to sort ascending on title, `+dc:title`.
*`browseDown`: when browse or search results in exactly one container entry, iteratively browse down until the result contains multiple container entries or at least one media entry, default is `true`.
*`searchFromRoot`: always start search from root instead of the current id, default is `false`.
A `upnprenderer` has the following optional configuration parameters:
*`seekStep`: step in seconds when sending fast forward or rewind command on the player control, default 5s.
*`notificationVolumeAdjustment`: volume adjustment from current volume in percent (range -100 to +100) for notifications when no volume is set in `playSound` command, default 10.
*`maxNotificationDuration`: maximum duration for notifications (default 15s), no maximum duration when set to 0s.
The `upnpserver` has the following channels (item type and access mode indicated in brackets):
*`upnprenderer` (String, RW): The renderer to receive media content for playback.
The channel allows selecting from all discovered media renderers.
This list is dynamically adjusted as media renderers are being added/removed.
*`currenttitle` (String, R): Current title of media container or entry ready for playback.
*`browse` (String, RW): Browse and serve media content, current ID of media container or entry ready for playback.
The browsing will start at the top of the content directory tree and allows you to go down and up (represented by ..) in the tree.
The list of containers (directories) and media entries for selection in the content hierarchy is updated dynamically when selecting a container or entry.
This channel can also be used to skip to a specific container or entry in the content directory.
Setting it to 0 will reposition to the top of the content hierarchy.
All media in the selection list, playable on the currently selected `upnprenderer` channel, are automatically queued to the renderer as next media for playback.
The `browseDown` configuration parameter influences the result in such a way that, for `browseDown = true`, if the result only contains exactly one container entry, the result will be the content of the container and not the container itself.
*`search` (String, W): Search for media content on the server.
Search criteria are defined in UPnP search criteria format.
The search, by default, starts at the value of the `currentid` and searches down from there unless the `searchfromroot` thing configuration parameter is set to `true`.
The result (media and containers) will be available in the `browse` command option list.
The `currentid` channel will be put to the id of the top container where the search started.
All media in the search result list, playable on the current selected `upnprenderer` channel, are automatically queued to the renderer as next media for playback.
The `browseDown` configuration parameter influences the result in such a way that, for `browseDown = true`, if the result only contains exactly one container entry, the result will be the content of the container and not the container itself.
*`playlistselect` (String, W): Select a playlist from the available playlists currently saved on disk.
This will also update `playlist` with the selected value.
*`playlist` (String, RW): Name of existing or new playlist.
*`playlistaction` (String, W): action to perform with `playlist`.
Possible command options are:
*`RESTORE`: restore the playlist from `playlist`.
If the restored playlist contains content from the current server, this content will update the `browse` command option list.
Note that playlists can contain a mix of media entries and container references.
All media in the result list, playable on the current selected `upnprenderer` channel, are automatically queued to the renderer as next media for playback.
*`SAVE`: save the current `browse` command option list into `playlist`.
If `playlist` already exists, it will be overwritten.
*`APPEND`: append the current `browse` command option list to `playlist`.
If `playlist` does not exist yet, a new playlist will be created.
*`DELETE`: delete `playlist` from disk and remove from `playlistselect` command option list.
A number of convenience channels replicate the basic control channels from the `upnprenderer` thing for the currently selected renderer on the `upnprenderer` channel.
These channels are `volume`, `mute` and `control`.
### `upnprenderer`
The `upnprenderer` has the following default channels:
| Channel Type ID | Item Type | Access Mode | Description |
Two audio sinks are registered for each media renderer.
`playSound` and `playStream` commands can be used in rules to play back audio fragments or audio streams to a renderer.
The first audio sink has the renderer id as a name.
It is used for normal playback of a sound or stream.
The second audio sink has `-notify` appended to the renderer id for its name, and has a special behavior.
This audio sink is used to play notifications.
When setting the volume parameter in the `playSound` command, the volume of the renderer will only change for the duration of playing the notification.
The `maxNotificationDuration` configuration parameter of the renderer will limit the notification duration the value of the parameter in seconds.
Normal playing will resume after the notification has played or when the maximum notification duration has been reached, whichever happens first.
Longer sounds or streams will be cut off.
## Managing a Playback Queue
There are multiple ways to serve content to a renderer for playback.
* Directly provide a URI on the `URI` channel or through `playSound` or `playStream` actions:
Playing will start immediately, interrupting currently playing media.
No metadata for the media is available, therefore will be provided in the media channels for metadata (e.g. `title`, `album`, ...).
* Content served from one or multiple `upnpserver` servers:
This is done on the `upnpserver` thing with the `upnprenderer` set the the renderer for playback.
The media at any point in time in the `upnpserver browse` option list (result from browse, search or restoring a playlist), will be queued to the `upnprenderer` for playback.
Playback does not start automatically if not yet playing.
When already playing a queue, the first entry of the new queue will be playing as the next entry.
When playing an URI or media provided through an action, playback will immediately switch to the new queue.
The `upnprenderer` will use that queue until it is replaced by another queue from the same or another `upnpserver`.
Note that querying the content hierarchy on the `upnpserver` will update the `upnpserver browse` option list each time, and therefore the queue on the `upnprenderer` will be updated each time as long as `upnprenderer` is selected on `upnpserver`.
* Selecting a favorite or playlist on the renderer.
Playback of the favorite or playlist will start immediately.
When playing from a directly provided URI, at the end of the media, the renderer will try to move to the next entry in a queue previously provided by a server.
Playing will stop when no such entry is available.
Multiple renderers can be sent the same or different playback queue from the same server sequentially.
Select content on the server and select the first renderer for playback.
The content queue will be served to the renderer, a play command on the renderer will start playing the queue.
Select another renderer on the server.
The same or new (after another content selection) queue will be served to the second renderer.
Both renderers will keep on playing the full queue they received.
When serving a queue from a server, the renderer can be put in "only play one" mode by putting the `onlyplayone` channel to true.
A subsequent play command will only play one media entry from the queue while respecting `shuffle` and `repeat`.
To play the next media from the queue, a new play command will be required after the player stopped.
An example of usage could be playing a single random sound from a playlist when you are away from home and an intrusion is detected.
A script could put the player in `shuffle` and `onlyplayone` mode and serve a playlist.
Only one random sound from the playlist would be played.
### Favorites
Currently playing media can be saved as favorites on the renderer.
This is especially useful when playing streams, such as online radio, but is valid for any media.
If the currently playing media has metadata, it will be saved with the favorite.
A favorite only contains one media item.
Selecting the favorite will only play that one item.
The favorite will start playing immediately.
Playing the server queue will resume after playing the favorite.
### Playlists
Playlists provide a way to define lists of server content for playback.
A new playlist can be created on a server thing from the selection in the `upnpserver browse` selection list.
When restoring a playlist on the server, the media in the playlist from the `upnpserver` thing used for restoring, will be put in the `upnpserver browse` selection list.
The current selection of media playable on the currently selected renderer will automatically be stored as a playlist with name `current`.
A playlist can contain media from different servers.
Only the media from the current server will be visible in the server when restoring.
It is possible to append content to a playlist that already contains content from a different server.
That way, it is possible to combine multiple sources for playback.
When selecting a playlist on a renderer, the playlist will be queued for playback, replacing the current queue.
Playback will start immediately.
## Using Search
Searching content on a media server may take a lot of time, depending on the functionality and the performance of the media server.
Therefore, it may very well be that media server searches time out.
Rather than searching for individual items, it is therefore often better to search for containers or playlists.
For example:
*`upnp:class derivedfrom "object.item.audioItem.musicTrack" and dc:title contains "Fight For Your Right"` would search for all music tracks with "Fight For Your Right" in the title.
This search is potentially slow.
*`dc:title contains "Evening" and upnp:class = "object.container.playlistContainer"` would search for all playlists with "Evening" in the name.
*`dc:title = "Donnie Darko" and upnp:class = "object.container.playlistContainer"` would search for a playlist with a specific name.
With the last example, if the `browseDown` configuration parameter is `true`, the result will not be the playlist, but the content of the playlist.
This allows immediately starting a play command without having to browse down to the first result of the list (the unique container).
This is especially useful when doing searches and starting to play in scripts, as the play command can immediately follow the search for a unique container, without a need to browse down to a media ID that is hidden in the browse option list.
For interactive use through a UI, you may opt to switch the `browseDown` configuration parameter to `false` to see all levels in the browsing hierarchy.
The `searchfromroot` configuration parameter always forces searching to start from the directory root.
This will also always reset the `browse` channel to the root.
This option is helpful if you do not want to limit search to a selected container in the directory.
BasicUI has a number of limitations that impact the way some of the channels can be used from it:
* BasicUI does not support dynamic refreshing of the selection list in the `upnpserver` channels `renderer`, `browse`, `playlistselect` and in the `upnprenderer` channel `favoriteselect`.
A refresh of the browser will be required to show the adjusted selection list.
* The `upnpserver search` channel requires input of a string to trigger a search.
The `upnpserver playlist` channel and `upnprenderer favorite` channel require input of a string to set a playlist or favorite.
This cannot be done with BasicUI, but can be achieved with rules.
* The player control in BasicUI does not support fast forward or rewind.
None of these are limitations when using the main UI.