This plugin has been developed to offer a modern API for other developers to communicate with the VDR.
The plugin supports the following outputs formats: xml, json and html.
It also supports the following input formats: json and html.
It would not exist without the help of the following people:
- Klaus Schmidinger: Of course because of the VDR itself. Thank you also for the nice and clean layout for the
API-Documentation which I "borrowed" from your PLUGINS.html.
- Gerald Dachs: Thank you for the intial idea and the initial jsonapi-Plugin.
- Volker Richert: Thank you for fixing the UTF8-Support.
- Tommi Mäkitalo: Thank you for implementing the Regex-Support in cxxtools which allows RESTful web services.
- Holger Schvestka: Thank you for improving the package structure.
- All other yaVDR-Members who I haven't already mentioned, just because you are who you are and do your best to
improve the VDR experience.
- The developers of the live and vnsisserver Plugins which helped me to learn a lot about the API of VDR.
- The developers of the live plugin where I borrowed parts of the epgsearch-implementation :-)
- Daniel Kuschny: Thank you for fixing my broken regular expressions. Will pay you a beer! :-)
- Keine_Ahnung@vdr-portal for the VDR 1.6 compatibility patch
This document describes the API and how to use it. It contains a lot of examples for the different formats and
services but there is still a lot more to discover if you simply try to make a few simple requests.
Someone who wants to install the plugin on his/her VDR needs following applications and libraries:
- VDR 1.7.18
- libcxxtools Rev. >= 1231, which is available as package for Ubuntu in the yavdr-PPA's
Someone who wants to develop an application which uses this API:
- XML or JSON Parser (Depends on which format you want to use! - You can also use the html-format, but that one is
more a proof for the restful concept and does not show all information!)
- URL Decoder or JSON Serializer (to send data to the webservice, required e.g. to create timers, searchtimers
etc...) e.g. POSTMan REST Client. There is a wide variety of REST clients available on the web.
Create a new file called plugin.restfulapi.conf in /etc/vdr/plugins/ respectively /etc/vdr/conf.avail (don't forget to create a symlink in /etc/vdr/conf.d/).
#
# Command line parameters for vdr-plugin-restfulapi
#
--port=8002
--ip=0.0.0.0
--epgimages=/var/cache/vdr/epgimages
--channellogos=/usr/share/vdr/channel-logos
--webapp=/var/lib/vdr/plugins/restfulapi/webapp,/var/lib/vdr/plugins/restfulapi/a-second-webapp
This service returns a list of channels.
GET
GET http://<ip>:<port>/channels/.<format>
GET http://<ip>:<port>/channels/<channelid>.<format>
GET http://<ip>:<port>/channels/.<format>?start=<int>&limit=<int>
- <format> - The requested format: json, xml or html.
- <channelid> - Id of the requested channel.
- start, limit - These values are used to control the whole list. Start ist the first element you want to
retrieve. Limit...
GET http://127.0.0.1:8002/channels.xml?start=0&limit=1
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<channels xmlns="http://www.domain.org/restfulapi/2011/channels-xml">
<channel>
<param name="name"<ORF1 HD</param>
<param name="number">1</param>
<param name="channel_id">C-71-71-61920</param<
<param name="image">true</param>
<param name="group">hd</param>
<param name="transponder">330</param>
<param name="stream">C-71-71-61920.ts</param>
<param name="is_atsc">false</param>
<param name="is_cable">true</param>
<param name="is_sat">false</param>
<param name="is_terr">false</param>
<param name="is_radio">false</param>
</channel>
<count>1</count>
<total>259</total>
</channels>
GET http://127.0.0.1:8002/channels.json?start=0&limit=1
{
"channels": [
{
"name":"ORF1 HD",
"number":1,
"channel_id":"C-71-71-61920",
"image":true,
"group":"hd",
"transponder":330,
"stream":"C-71-71-61920.ts",
"is_atsc":false,
"is_cable":true,
"is_terr":false,
"is_sat":false,
"is_radio": false
}
],
"count":1,
"total":259
}
This service will return a list containing all channel groups.
GET
GET http://<ip>:<port>/channels/groups.<format>
GET http://<ip>:<port>/channels/groups.<format>?start=<int>&limit=<int>
GET http://<ip>:<port>/channels.<format>?group=<group>
- <group> - returns the channels of the requested group
- <format> - json | xml | html
GET http://<ip>:<port>/channels/groups.xml?start=0&limit=3
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<groups xmlns="http://www.domain.org/restfulapi/2011/groups-xml">
<group>hd</group>
<group>main</group>
<group>stuff</group>
<count>3</count>
<total>3</total>
</groups>
GET http://<ip>:<port>/channels/groups.json?start=0&limit=3
{
"groups": [
"hd",
"main",
"stuff"
],
"count":3,
"total":3
}
This service returns the requested channel-logo.
GET
GET http://<ip>:<port>/channels/image/<channelid>
- <channelid> - id of channel
This service returns the epg information.
Since Version 0.2.0 the API returns additional media if a scraper plugin is available.
The data is available within additional_media node and contains additional information about the event such as actors etc.
Images can be retrieved using ScraperImages service.
GET
GET http://<ip>:<port>/events.<format>?chevents=1
GET http://<ip>:<port>/events/<channelid>.<format>?chevents=1&from=<from>
GET http://<ip>:<port>/events/<channelid>.<format>?timespan=<timespan>
GET http://<ip>:<port>/events/<channelid>/<eventid>.<format>
GET http://<ip>:<port>/events/<channelid>.<format>?timespan=<timespan>&from=<from>&start=<int>&limit=<int>
- <format> - The requested format: json, xml or html.
- <channelid> - (optional) id of the channel, if not set the plugin will return the whole epg sorted by your
channel list
- <timespan> - the timespan from which you want to know the event-details, if set to 0 - all events in the
future will be returned
- <from> - (optional) time in the future when the requested events should end/start (default-value: now)
- <eventid> - (optional) if you only want the details of a specific event
- <chevents> - (optional) the count of events for each channel
- <chfrom> - (optional) start number of the channel, from where events will be returned
- <chto> - (optional) end number of the channel, through events will be returned
- <only_count> - (optional) if you just want to know the amount of available epg items
- <format> - The requested format: json, xml or html.
GET http://<ip>:<port>/events/C-1-1079-11110.xml?chevents=1&from=1432577700
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<events xmlns="http://www.domain.org/restfulapi/2011/events-xml">
<event>
<param name="id">588333</param>
<param name="title">Title</param>
<param name="short_text">Humor (D 2010)</param>
<param name="description">Description Text</param>
<param name="channel">C-1-1079-11110</param>
<param name="channel_name">ZDF HD</param>
<param name="start_time">1432577700</param>
<param name="duration">5400</param>
<param name="table_id">80</param>
<param name="version">25</param>
<param name="parental_rating">0</param>
<param name="vps">1432577700</param>
<param name="details"></param>
<param name="images">3</param>
<param name="components">
<component stream="2" type="3" language="deu" description="Stereo" />
<component stream="2" type="3" language="mis" description="Audiodeskription" />
<component stream="2" type="3" language="mul" description="ohne Originalton" />
<component stream="3" type="32" language="deu" description="DVB-Untertitel" />
<component stream="4" type="66" language="deu" description="Dolby Digital 2.0" />
<component stream="5" type="11" language="deu" description="HDTV" />
</param>
<param name="contents"></param>
<param name="raw_contents"></param>
<param name="timer_exists">false</param>
<param name="timer_active">false</param>
<param name="timer_id"></param>
<param name="additional_media" type="movie">
<movie_id>329933</movie_id>
<title>Title</title>
<original_title>Original Title</original_title>
<overview>Overview Text</overview>
<adult>false</adult>
<genres>Komödie , Lovestory</genres>
<release_date>2010-06-01</release_date>
<runtime>90</runtime>
<poster path="movies/329933/poster.jpg" width="500" height="750" />
<fanart path="movies/329933/fanart.jpg" width="1280" height="720" />
<actor name="Name" role="Role" thumb="movies/actors/actor_49104.jpg"/>
</param>
</event>
<count>1</count>
<total>257</total>
</events>
GET http://<ip>:<port>/events/C-1-1079-11110.json?chevents=1&from=1432577700
{
"events": [
{
"id": 588333,
"title": "Title",
"short_text": "Short Title",
"description": "Description Text",
"start_time": 1432577700,
"channel": "C-1-1079-11110",
"channel_name": "ZDF HD",
"duration": 5400,
"table_id": 80,
"version": 25,
"images": 3,
"timer_exists": false,
"timer_active": false,
"timer_id": "",
"parental_rating": 0,
"vps": 1432577700,
"components": [
{
"stream": 2,
"type": 3,
"language": "deu",
"description": "Stereo"
},
{
"stream": 2,
"type": 3,
"language": "mis",
"description": "Audiodeskription"
},
{
"stream": 2,
"type": 3,
"language": "mul",
"description": "ohne Originalton"
},
{
"stream": 3,
"type": 32,
"language": "deu",
"description": "DVB-Untertitel"
},
{
"stream": 4,
"type": 66,
"language": "deu",
"description": "Dolby Digital 2.0"
},
{
"stream": 5,
"type": 11,
"language": "deu",
"description": "HDTV"
}
],
"contents": [],
"raw_contents": [],
"details": [],
"additional_media": {
"type": "movie",
"movie_id": 329933,
"title": "Title",
"original_title": "Original Title",
"tagline": "",
"overview": "Overview Text",
"adult": false,
"collection_name": "",
"budget": 0,
"revenue": 0,
"genres": "Komödie , Lovestory",
"homepage": "",
"release_date": "2010-06-01",
"runtime": 90,
"popularity": 0,
"vote_average": 0,
"poster": "movies/329933/poster.jpg",
"fanart": "movies/329933/fanart.jpg",
"collection_poster": "",
"collection_fanart": "",
"actors": [
{
"name": "Name",
"role": "Role",
"thumb": "movies/actors/actor_49104.jpg"
}
]
}
}
],
"count": 1,
"total": 257
}
This service returns the requested epg image.
GET
GET http://<ip>:<port>/events/image/<eventid>/<imagenumber>
- <eventid> - Id of the event
- <imagenumber> - the number of the image, in the above mentioned examples it would be 0,1 or 2
This service allows you to search for events.
Since Version 0.2.4.0 it is possible to perform a search similar to Searchtimers.
POST
POST http://<ip>:<port>/events/search.<format>?limit=5&start=0;
- <limit> - (optional) number of searchresults
- <start> - (required if limit is set) start at result
- <date_limit> - (optional) UNIX timestamp until events are returned (since 0.2.4.1)
Name |
Type |
Required |
Value Range / Example |
search |
string |
yes |
|
mode |
int |
yes |
0=phrase, 1=all words, 2=at least one word, 3=match exactly, 4=regex, 5=fuzzy |
tolerance |
int |
if mode == 5 |
|
match_case |
boolean |
|
|
use_title |
boolean |
at least one of use_title, use_subtitle, use_description |
|
use_subtitle |
boolean |
at least one of use_title, use_subtitle, use_description |
|
use_description |
boolean |
at least one of use_title, use_subtitle, use_description |
|
content_descriptors |
string |
no |
concatted string of content descriptor ids |
use_ext_epg_info |
boolean |
no |
|
ext_epg_info |
array |
|
[1#2,2#test] |
use_time |
boolean |
no |
|
start_time |
int |
no |
|
stop_time |
int |
no |
|
use_channel |
boolean |
no |
0=no, 1=interval, 2=channel group, 3=only FTA |
channel_min |
string |
no |
channel id |
channel_max |
string |
no |
channel id |
channels |
string |
if use_channel > 0 |
channel group name |
use_duration |
boolean |
no |
|
duration_min |
int |
if use_duration == true |
|
duration_max |
int |
if use_duration == true |
|
use_dayofweek |
boolean |
no |
|
dayofweek |
int |
if use_dayofweek == true |
-127 - 6 |
blacklist_mode |
int |
no |
0=global, 1=Selection, 2=all, 3=none |
blacklist_ids |
array |
if blacklist_mode == 1 |
array of blacklist ids |
POST http://<ip>:<port>/events/search.<format>?limit=5&start=0;
- <limit> - (optional) number of searchresults
- <start> - (required if limit is set) start at result
- query - (required)
- mode - (required) 0=phrase, 1=and, 2=or, 3=exact, 4=regex, 5=fuzzy
- channelid - (optional) if id invalid, the plugin will search on every channel
- use_title - (optional, default) search in the title
- use_subtitle - (optional)
- use_description - (optional)
{"query":"Asterix", "mode":0, "channelid":0,"use_title":true}
GET
GET http://<ip>:<port>/events/contentdescriptors.<format>
{
"content_descriptors": [
{
"id": "10",
"name": "Film/Drama",
"is_group": true
},
{
"id": "11",
"name": "Detektiv/Thriller",
"is_group": false
},
{
"id": "12",
"name": "Abenteuer/Western/Krieg",
"is_group": false
},
.
.
.
],
"count": 79,
"total": 79
}
General Information about the plugin and vdr.
Since version 0.2.6.0 basic femon data is available.
SNR, STR, BER, UNC and Status.
The status field contains a colon seperated list of available status in following order:
- Locked
- Signal
- Carrier
- Viterbi
- Sync
If a status is false the list contains a minus sign instead.
GET
GET http://<ip>:<port>/info.<format>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<info xmlns="http://www.domain.org/restfulapi/2011/info-xml">
<version>0.0.1</version>
<time>1432551206</time>
<services>
<service path="/info" version="1" internal="true" />
<service path="/channels" version="1" internal="true" />
<service path="/channels/groups" version="1" internal="true" />
<service path="/channels/image" version="1" internal="true" />
<service path="/events" version="1" internal="true" />
<service path="/events/image" version="1" internal="true" />
<service path="/events/search" version="1" internal="false" />
<service path="/recordings" version="1" internal="true" />
<service path="/recordings/cut" version="1" internal="true" />
<service path="/recordings/marks" version="1" internal="true" />
<service path="/remote" version="1" internal="true" />
<service path="/timers" version="1" internal="true" />
<service path="/osd" version="1" internal="true" />
<service path="/searchtimers" version="1" internal="false" />
<service path="/scraper" version="1" internal="true" />
<service path="/wirbelscan" version="1" internal="true" />
<service path="/wirbelscan/countries" version="1" internal="true" />
<service path="/webapp" version="1" internal="true" />
<service path="/femon" version="1" internal="true" />
</services>
<channel>C-61441-10009-10331</channel>
<diskusage>
<free_mb>3491143</free_mb>
<free_minutes>98218</free_minutes>
<used_percent>67</used_percent>
<description_localized>Disk 67% - 1636:58 frei</description_localized>
</diskusage>
<vdr>
<plugins>
<plugin name="dvbapi" version="2.2.0-GIT-5fdb21e" />
<plugin name="wirbelscan" version="0.0.9" />
<plugin name="svdrposd" version="1.0.0" />
<plugin name="vnsiserver" version="1.3.0" />
<plugin name="epgsearchonly" version="0.0.1" />
<plugin name="femon" version="2.2.1" />
<plugin name="markad" version="0.1.5pre" />
<plugin name="svdrpservice" version="1.0.0" />
<plugin name="restfulapi" version="0.2.3.1" />
<plugin name="epgsearch" version="1.0.1.beta5" />
<plugin name="conflictcheckonly" version="0.0.1" />
<plugin name="scraper2vdr" version="0.1.13" />
<plugin name="epg2vdr" version="0.1.12" />
<plugin name="quickepgsearch" version="0.0.1" />
<plugin name="live" version="0.3.0" />
<plugin name="streamdev-server" version="0.6.1-git" />
</plugins>
</vdr>
<devices>
<device>
<dvb_c>true</dvb_c>
<dvb_s>false</dvb_s>
<dvb_t>false</dvb_t>
<atsc>false</atsc>
<primary>false</primary>
<has_decoder>false</has_decoder>
<name>Philips TDA10023 DVB-C</name>
<number>0</number>
<channel_id>C-61441-10011-50059</channel_id>
<channel_name>n-tv HD</channel_name>
<channel_nr>17</channel_nr>
<live>false</live>
<has_ci>true</has_ci>
<signal_strength>63</signal_strength>
<signal_quality>5</signal_quality>
<signal_str>65535</signal_str>
<signal_snr>380</signal_snr>
<signal_ber>0</signal_ber>
<signal_unc>0</signal_unc>
<signal_status>LOCKED:SIGNAL:CARRIER:VITERBI:SYNC</signal_status>
<adapter>0</adapter>
<frontend>0</frontend>
<type>DVB-C</type>
</device>
<device>
<dvb_c>true</dvb_c>
<dvb_s>false</dvb_s>
<dvb_t>true</dvb_t>
<atsc>false</atsc>
<primary>false</primary>
<has_decoder>false</has_decoder>
<name>DRXK DVB-C DVB-T</name>
<number>1</number>
<channel_id>C-61441-10003-53604</channel_id>
<channel_name>VOX</channel_name>
<channel_nr>1011</channel_nr>
<live>false</live>
<has_ci>false</has_ci>
<signal_strength>0</signal_strength>
<signal_quality>5</signal_quality>
<signal_str>65535</signal_str>
<signal_snr>380</signal_snr>
<signal_ber>0</signal_ber>
<signal_unc>0</signal_unc>
<signal_status>LOCKED:SIGNAL:CARRIER:VITERBI:SYNC</signal_status>
<adapter>1</adapter>
<frontend>0</frontend>
<type>DVB-C</type>
</device>
<device>
<dvb_c>true</dvb_c>
<dvb_s>false</dvb_s>
<dvb_t>true</dvb_t>
<atsc>false</atsc>
<primary>false</primary>
<has_decoder>false</has_decoder>
<name>DRXK DVB-C DVB-T</name>
<number>2</number>
<channel_id>C-61441-10011-50059</channel_id>
<channel_name>n-tv HD</channel_name>
<channel_nr>17</channel_nr>
<live>false</live>
<has_ci>false</has_ci>
<signal_strength>0</signal_strength>
<signal_quality>5</signal_quality>
<signal_str>65535</signal_str>
<signal_snr>380</signal_snr>
<signal_ber>0</signal_ber>
<signal_unc>0</signal_unc>
<signal_status>LOCKED:SIGNAL:CARRIER:VITERBI:SYNC</signal_status>
<adapter>2</adapter>
<frontend>0</frontend>
<type>DVB-C</type>
</device>
</devices>
</info>
{
"version": "0.0.1",
"time": 1432551355,
"services": [
{
"path": "/info",
"version": 1
},
{
"path": "/channels",
"version": 1
},
{
"path": "/channels/groups",
"version": 1
},
{
"path": "/channels/image",
"version": 1
},
{
"path": "/events",
"version": 1
},
{
"path": "/events/image",
"version": 1
},
{
"path": "/events/search",
"version": 1
},
{
"path": "/recordings",
"version": 1
},
{
"path": "/recordings/cut",
"version": 1
},
{
"path": "/recordings/marks",
"version": 1
},
{
"path": "/remote",
"version": 1
},
{
"path": "/timers",
"version": 1
},
{
"path": "/osd",
"version": 1
},
{
"path": "/searchtimers",
"version": 1
},
{
"path": "/scraper",
"version": 1
},
{
"path": "/wirbelscan",
"version": 1
},
{
"path": "/wirbelscan/countries",
"version": 1
},
{
"path": "/webapp",
"version": 1
},
{
"path": "/femon",
"version": 1
}
],
"channel": "C-61441-10009-10331",
"eventid": -1,
"start_time": -1,
"duration": -1,
"title": "",
"diskusage": {
"free_mb": 3491143,
"used_percent": 67,
"free_minutes": 98218,
"description_localized": "Disk 67% - 1636:58 frei"
},
"vdr": {
"plugins": [
{
"name": "wirbelscan",
"version": "0.0.9"
},
{
"name": "svdrposd",
"version": "1.0.0"
},
{
"name": "vnsiserver",
"version": "1.3.0"
},
{
"name": "epgsearchonly",
"version": "0.0.1"
},
{
"name": "femon",
"version": "2.2.1"
},
{
"name": "markad",
"version": "0.1.5pre"
},
{
"name": "svdrpservice",
"version": "1.0.0"
},
{
"name": "restfulapi",
"version": "0.2.3.1"
},
{
"name": "epgsearch",
"version": "1.0.1.beta5"
},
{
"name": "conflictcheckonly",
"version": "0.0.1"
},
{
"name": "scraper2vdr",
"version": "0.1.13"
},
{
"name": "epg2vdr",
"version": "0.1.12"
},
{
"name": "quickepgsearch",
"version": "0.0.1"
},
{
"name": "live",
"version": "0.3.0"
},
{
"name": "streamdev-server",
"version": "0.6.1-git"
}
],
"devices": [
{
"name": "Philips TDA10023 DVB-C",
"dvb_c": true,
"dvb_s": false,
"dvb_t": false,
"atsc": false,
"primary": false,
"has_decoder": false,
"number": 0,
"channel_id": "C-1-1051-11100",
"channel_name": "Das Erste HD",
"channel_nr": 1,
"live": false,
"has_ci": true,
"signal_strength": 81,
"signal_quality": 5,
"str": 65535
"snr": 378
"ber": 0
"unc": 0
"status": "LOCKED:SIGNAL:CARRIER:VITERBI:SYNC"
"adapter": 2,
"frontend": 0,
"type": "DVB-C"
"adapter": 0,
"frontend": 0,
"type": "DVB-C"
},
{
"name": "DRXK DVB-C DVB-T",
"dvb_c": true,
"dvb_s": false,
"dvb_t": true,
"atsc": false,
"primary": false,
"has_decoder": false,
"number": 1,
"channel_id": "C-61441-10011-50059",
"channel_name": "n-tv HD",
"channel_nr": 17,
"live": false,
"has_ci": false,
"signal_strength": 0,
"signal_quality": 5,
"str": 65535
"snr": 378
"ber": 0
"unc": 0
"status": "LOCKED:SIGNAL:CARRIER:VITERBI:SYNC"
"adapter": 2,
"frontend": 0,
"type": "DVB-C"
"adapter": 1,
"frontend": 0,
"type": "DVB-C"
},
{
"name": "DRXK DVB-C DVB-T",
"dvb_c": true,
"dvb_s": false,
"dvb_t": true,
"atsc": false,
"primary": false,
"has_decoder": false,
"number": 2,
"channel_id": "C-61441-10011-50059",
"channel_name": "n-tv HD",
"channel_nr": 17,
"live": false,
"has_ci": false,
"signal_strength": 0,
"signal_quality": 5,
"str": 65535
"snr": 378
"ber": 0
"unc": 0
"status": "LOCKED:SIGNAL:CARRIER:VITERBI:SYNC"
"adapter": 2,
"frontend": 0,
"type": "DVB-C"
}
]
}
}
Instead of the channel it can also contain the currently playing video file:
<video name="Asterix in Amerika">/var/lib/video.00/Asterix_in_Amerika/2011-06-19.12.40.1-0.rec</video>
Since Version 0.2.2.2 node "vdr" also contains info about the TV-Cards attached to the system
This Service delivers current OSD contents
GET
GET http://<ip>:<port>/osd.<format>
{
"TextOsd" : {
"type" : "TextOsd",
"title" : "VDR - Disk 68% - 57:53 free",
"message" : "",
"red" : "",
"green" : "Audio",
"yellow" : "",
"blue" : "Stop",
"items" : [
{
"content" : " 1 Schedule",
"is_selected":true
},
{
"content":" 2 Channels",
"is_selected":false
},
{
"content":" 3 Timers",
"is_selected":false
},
{
"content":" 4 Recordings",
"is_selected":false
},
{
"content":" 5 Search",
"is_selected":false
},
{
"content":" 6 Media Player",
"is_selected":false
},
{
"content":" 7 Program guide",
"is_selected":false
},
{
"content":" 8 Quick search",
"is_selected":false
},
{
"content":" 9 Timer conflicts",
"is_selected":false
},
{
"content":" 10 Setup",
"is_selected":false
},
{
"content":" 11 Commands",
"is_selected":false
},
{
"content":" Stop replaying",
"is_selected":false
}
]
}
}
{
"ProgrammeOsd" : {
"present_time":1311710264,
"present_title":"Der letzte Bulle",
"present_subtitle":"Ich hab sie alle gehabt",
"following_time":1311713161,
"following_title":"direkt - das magazin",
"following_subtitle":""
}
}
This service can move/delete recordings and can also return all the recordings as a list.
Since Verions 0.2.0 the API returns additional media if a scraper plugin is available.
The data is available within leaf additional_media and contains additional information about the event such as actors etc.
Please have a look at the data or the JSDoc Examples to get an idea about the additional structure.
Images can be retrieved using ScraperImages service.
Since Version 0.2.5 one can fetch Recordings either by its full file name or by number.
It is not safe to use the recording number for e.g. deleting recordings because it is not guaranteed that the numbers don't change during runtime.
Hence it is recommended to use the <file_name> as parameter. Due to backwards compatibility reasons the recording number is still supported
but may be removed in future versions.
To use the file name as parameter it could be necessary to url encode the path parts.
http://<ip>:<port>/recordings/path/to/videodir/my_recording/YYYY-MM-DD.hh.mm.ss-0.rec.<format>
Since Version 0.2.5 it is also possible to request restfulapi to write a sync file in its cache directory.
Simply add the <syncId> parameter with a value of of your choice to the url whithin a request to the full recording list.
This sync file can be checked against the current recordings or a list of recordings sent by the client.
Future requests to the /recordings/updates service with the same id can fetch a list of new, deleted or updated recordings since the last full or updates request.
Don't forget to add the syncId parameter to delete requests aswell. Restfulapi can than delete it from your clients sync list.
Additionally the /recordings/sync service has been added. You can send an array named recordings with each member containing a comma seperated
file_name, hash pair. The hash is a new property of each recording that will be added if the full recording list was requested.
Restfulapi will then respond with a list of recordings that have been added, deleted or changed
The updates response contains a list of recordings with a <sync_action> property that contains either add, delete or update.
One can use this feature to store the recordings in a client side database and keep it in sync without requesting the full list every time.
GET, DELETE, POST
GET http://<ip>:<port>/recordings/.<format>?syncId=my-client-id
GET http://<ip>:<port>/recordings/<file_name|recordingnumber>.<format>?marks=true
GET http://<ip>:<port>/recordings/updates.<format>?syncId=my-client-id
POST http://<ip>:<port>/recordings/sync.<format>?syncId=my-client-id
DELETE http://<ip>:<port>/recordings/<file_name|recordingnumber>?syncId=my-client-id
POST http://<ip>:<port>/recordings/move.<format>
- <format> - The requested format: json, xml or html.
- <number> - The number of the recording which you want to delete. (The first recordings has the number 0.)
- <file_name> - The full file system path of the recording. Everything url encoded except slashes (directory seperator)
- <recordingnumber> - The number of the recording you want to retrieve.
- <source> - The full (url encoded) source path of the recording.
- <target> - The relative (url encoded) target path of the recording.
- <syncId> - (optional) client id for sync map file name
- <recordings[]> - <file_name>,<hash> (Form Data)
- marks=true - add the cutting marks by reading the marks file from the recording directory
- start, limit - These values are used to control the whole list. Start ist the first element you want to
retrieve. Limit...
GET http://127.0.0.1:8002/recordings.xml?start=0&limit=1
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<recordings xmlns="http://www.domain.org/restfulapi/2011/recordings-xml">
<recording>
<param name="number">0</param>
<param name="name">Asterix in Amerika</param>
<param name="filename">/var/lib/video.00/Asterix_in_Amerika/2011-06-19.12.40.1-0.rec</param>
<param name="is_new">false</param>
<param name="is_edited">false</param>
<param name="is_pes_recording">false</param>
<param name="duration">-1</param>
<param name="frames_per_second">50</param>
<param name="marks"><0:03:17.10><1:43:07.24></param>
<param name="event_title">Asterix in Amerika</param>
<param name="event_short_text"></param>
<param name="event_description">(Zeichentrickfilm, DEU 1994)</param>
<param name="event_start_time">1308480705</param>
<param name="event_duration">4611</param>
<param name="sync_action"></param>
<param name="hash"></param>
</recording>
<count>2</count><total>2</total>
</recordings>
GET http://127.0.0.1:8002/recordings.json?start=0&limit=1&marks=true
{
"recordings": [
{
"number":0,
"name":"Asterix in Amerika",
"file_name":"\/var\/lib\/video.00\/Asterix_in_Amerika\/2011-06-19.12.40.1-0.rec",
"is_new":false,
"is_edited":false,
"is_pes_recording":false,
"duration":-1,
"frames_per_second":50,
"marks":[
"0:03:17.10",
"1:43:07.24"
],
"event_title":"Asterix in Amerika",
"event_short_text":"",
"event_description":"(Zeichentrickfilm, DEU 1994)",
"event_start_time":1308480705,
"event_duration":4611
"sync_action":""
"hash":""
}
],
"count":1,
"total":2
}
POST "http://127.0.0.1:8002/recordings/move.json"
- source=/path/to/videodir/my_recording/YYYY-MM-DD.hh.mm.ss-0.rec
- target=relative/path/to/renamed%20recording
GET "http://127.0.0.1:8002/recordings/updates.json"
GET http://127.0.0.1:8002/recordings/updates.json?syncId=a-string-identifying-my-client
{
"recordings": [
{
"number":0,
"name":"Asterix in Amerika",
"file_name":"\/var\/lib\/video.00\/Asterix_in_Amerika\/2011-06-19.12.40.1-0.rec",
"is_new":false,
"is_edited":false,
"is_pes_recording":false,
"duration":-1,
"frames_per_second":50,
"marks":[
"0:03:17.10",
"1:43:07.24"
],
"event_title":"Asterix in Amerika",
"event_short_text":"",
"event_description":"(Zeichentrickfilm, DEU 1994)",
"event_start_time":1308480705,
"event_duration":4611
"sync_action":"add"
"hash":"8324fe9b80873947c9d0963d83378232"
}
],
"count":1,
"total":2
}
POST "http://127.0.0.1:8002/recordings/sync.json?syncId=a-string-identifying-my-client"
- recordings[]=/path/to/videodir/my_recording/YYYY-MM-DD.hh.mm.ss-0.rec,8324fe9b80873947c9d0963d83378232
- recordings[]=/path/to/videodir/my_recording/YYYY-MM-DD.hh.mm.ss-0.rec,d4da05b1e99df60d3cd0ef72b6093db3
- recordings[]=/path/to/videodir/my_recording/YYYY-MM-DD.hh.mm.ss-0.rec,e3f29839c38c74bab63ab02d0dffd6a6
- ⋮
- recordings[]=/path/to/videodir/my_recording/YYYY-MM-DD.hh.mm.ss-0.rec,46a26b76f5c8c7361d33367dcc86ced0
POST http://127.0.0.1:8002/recordings/updates.json?syncId=a-string-identifying-my-client
{
"recordings": [
{
"number":0,
"name":"Asterix in Amerika",
"file_name":"\/var\/lib\/video.00\/Asterix_in_Amerika\/2011-06-19.12.40.1-0.rec",
"is_new":false,
"is_edited":false,
"is_pes_recording":false,
"duration":-1,
"frames_per_second":50,
"marks":[
"0:03:17.10",
"1:43:07.24"
],
"event_title":"Asterix in Amerika",
"event_short_text":"",
"event_description":"(Zeichentrickfilm, DEU 1994)",
"event_start_time":1308480705,
"event_duration":4611
"sync_action":"add"
"hash":"8324fe9b80873947c9d0963d83378232"
}
],
"count":1,
"total":2
}
This service tells your VDR to cut a recording or can tell the client if the vdr cutter is currently cutting a recording:
GET, POST
POST http://<ip>:<port>/recordings/cut/<file_name|recordingnumber> # do it! (cut the recording)
GET http://<ip>:<port>/recordings/cut.<format> # this will return the status of the VDR Cutter
This service can save and delete marks. To retrieve them use the parameter "marks=true" in the request url for the recordings.
Delete Cutting Marks:
DELETE
DELETE http://<ip>:<port>/recordings/marks/<file_name|recordingnumber>
Create new Cutting Marks:
POST
POST http://<ip>:<port>/recordings/marks/<file_name|recordingnumber>
{
'marks' : [
'0:02:18.10',
'0:34:08.24'
]
}
This service tells your VDR to play or rewind a recording:
GET, POST
GET http://<ip>:<port>/recordings/play/<file_name|recordingnumber>
POST http://<ip>:<port>/recordings/play/<file_name|recordingnumber>
- <file_name> - (recommended) The full file name of the recording.
- <number> - (deprecated) The number of the recording.
This service retrieves remote commands and sends them to VDR:
POST
POST http://<ip>:<port>/remote/<key>
POST http://<ip>:<port>/remote/switch/<channelid>
POST http://<ip>:<port>/remote/kbd
-
Up, Down, Menu, Ok, Back, Left, Right, Red, Green, Yellow, Blue, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, Info, Play, Pause, Stop,
Record, FastFwd, FastRew, Next, Prev, Power, ChanUp, ChanDn, ChanPrev, VolUp, VolDn, Mute, Audio, Subtitles, Schedule,
Channels, Timers, Recordings, Setup, Commands, User0, User1, User2, User3, User4, User5, User6, User7, User8, User9,
None, Kbd
The second address allows to directly switch to a specific channel.
The third address allows to send strings that are interpreted as keyboard input for e.g. usage in search
The fourth address allows to send to send a sequence of keypresses
Send keyboard input:
POST
POST http://<ip>:<port>/remote/kbd
{'kbd':'Asterix'}
Send sequence of keypresses:
POST
POST http://<ip>:<port>/remote/seq
{
'seq': [
'Down',
'Down',
'Right'
]
}
This service returns a list of timers.
GET, DELETE
GET http://<ip>:<port>/timers.<format>
GET http://<ip>:<port>/timers/<timerid>.<format>
GET http://<ip>:<port>/timers.<format>?start=<int>&limit=<int>
DELETE http://<ip>:<port>/timers/<timerid>
- <format> - The requested format: json, xml or html.
- <timerid> - Id of the timer if you want to delete one.
- start, limit - These values are used to control the whole list. Start ist the first element you want to retrieve. Limit...
GET http://127.0.0.1:8002/timers.xml?start=0&limit=1
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<timers xmlns="http://www.domain.org/restfulapi/2011/timers-xml">
<timer>
<param name="id">C-71-71-61920:0:1309039200:2013:2200</param>
<param name="start">2013</param>
<param name="stop">2200</param>
<param name="start_timestamp">2011-12-24 19:00:00</param>
<param name="stop_timestamp">2011-12-24 20:00:00</param>
<param name="priority">50</param>
<param name="lifetime">99</param>
<param name="event_id">27312</param>
<param name="weekdays">-------</param>
<param name="day">2011-06-26</param>
<param name="channel">C-71-71-61920</param>
<param name="is_recording">false</param>
<param name="is_pending">false>/param>
<param name="filename">Mad Money>/param>
<param name="channel_name">ORF1 HD>/param>
<param name="is_active">true>/param>
</timer>
<count>1</count><total>2</total>
</timers>
GET http://127.0.0.1:8002/timers.json?start=0&limit=1
{
"timers": [
{
"id": "C-61441-10011-50059:0:1432504800:1108:1210",
"flags": 1,
"start": 1108,
"start_timestamp": "2015-05-25 11:08:00",
"stop_timestamp": "2015-05-25 12:10:00",
"stop": 1210,
"priority": 50,
"lifetime": 0,
"event_id": -1,
"weekdays": "-------",
"day": "2015-05-25",
"channel": "C-61441-10011-50059",
"filename": "Serie~Das Universum: Planeten~Mo. 25.05.15 11:10",
"channel_name": "n-tv HD",
"is_pending": false,
"is_recording": false,
"is_active": true,
"aux": "<epgsearch><channel>17 - n-tv HD</channel><searchtimer>das universum</searchtimer><start>1432544880</start><stop>1432548600</stop><s-id>79</s-id><eventid>5938</eventid></epgsearch>"
"index": 1
}
],
"count": 1,
"total": 20
}
Bulk delete Timers
Deletes multiple Timers at once
DELETE
DELETE http:/<ip>:<port>/timers/bulkdelete.json
{
"timers" : [
"C-61441-10004-50101:0:1432504800:1923:2025",
"C-61441-10013-50001:0:1432504800:2013:2110",
"C-61441-10012-50008:0:1432591200:2013:2230"
]
}
{
"timers" : [
{
"id" : "C-61441-10004-50101:0:1432504800:1923:2025",
"deleted" : true
},
{
"id" : "C-61441-10013-50001:0:1432504800:2013:2110",
"deleted" : true
},
{
"id" : "C-61441-10012-50008:0:1432591200:2013:2230",
"deleted" : true
}
],
"count" : 3,
"total" : 3
}
This service can create new timers.
POST
POST http:/<ip>:<ip>/timers
- flags - set it to 1 for an active timer
- file - name of the recording (use an url-encoder for this text if you special characters)
- stop - the time when the recording should be start - in the 24 hour system, f.e. 2015 means quarter past ten in
the evening
- start - the time when the recording sholud be stoped, f.e. 2230 (half past ten in the evening)
- day - YYYY-MM-DD, f.e. 2011-12-24 -> christmas :-)
- channel - ID of the channel
- weekdays - MTWTFSS, used for repeating timers -> just use '-' if you don't want the timer to run on the
specific day
- minpre, minpost can be used together with a channel and eventid to create a timer without giving the other
information to the api
POST /timers HTTP/1.1
Content-Length: 98
Connection: close
file=Ein%20Film&flags=1&start=1400&stop=1615&day=2011-12-24&channel=C-71-71-61920&weekdays=-------
HTTP/1.1 200 OK
Content-Length: 0
Server: cxxtools-Http-Server 2.0
Connection: close
Date: Sun, 26 Jun 2011 19:03:48 GMT
This service can update the previously created timers.
PUT
PUT http://<ip>:<port>/timers
- timer_id - the id of the timer
Optional Body Parameters are the ones you use to create the timer and now want to update.
PUT /timers HTTP/1.1
Content-Length: 81
Connection: close
timer_id=C-71-71-61920:0:1324681200:1400:1615&start=2015&stop=2230
HTTP/1.1 200 OK
Content-Length: 0
Server: cxxtools-Http-Server 2.0
Connection: close
Date: Sun, 26 Jun 2011 19:20:03 GMT
This Service returns SearchTimers and can create, delete or update them. It's also possible to perform a search.
POST
POST http://<ip>:<port>/searchtimers
Name |
Type |
Required |
Value Range / Example |
id |
int |
no |
|
search |
string |
yes |
|
mode |
int |
yes |
0=phrase, 1=all words, 2=at least one word, 3=match exactly, 4=regex, 5=fuzzy |
tolerance |
int |
if mode == 5 |
|
match_case |
boolean |
|
|
use_title |
boolean |
at least one of use_title, use_subtitle, use_description |
|
use_subtitle |
boolean |
at least one of use_title, use_subtitle, use_description |
|
use_description |
boolean |
at least one of use_title, use_subtitle, use_description |
|
content_descriptors |
string |
no |
concatted string of content descriptor ids |
use_ext_epg_info |
boolean |
no |
|
ext_epg_info |
array |
|
[1#2,2#test] |
use_in_favorites |
boolean |
no |
|
use_time |
boolean |
no |
|
start_time |
int |
no |
|
stop_time |
int |
no |
|
use_channel |
boolean |
no |
0=no, 1=interval, 2=channel group, 3=only FTA |
channel_min |
string |
no |
channel id |
channel_max |
string |
no |
channel id |
channels |
string |
if use_channel > 0 |
channel group name |
use_duration |
boolean |
no |
|
duration_min |
int |
if use_duration == true |
|
duration_max |
int |
if use_duration == true |
|
use_dayofweek |
boolean |
no |
|
dayofweek |
int |
if use_dayofweek == true |
-127 - 6 |
use_as_searchtimer |
int |
no |
0=no, 1=yes, 2=user defined |
use_as_searchtimer_from |
int |
if use_as_searchtimer == 2 |
unix timestamp |
use_as_searchtimer_til |
int |
no |
unix timestamp |
search_timer_action |
int |
no |
|
use_series_recording |
boolean |
no |
|
directory |
string |
no |
|
del_recs_after_days |
int |
no |
|
keep_recs |
int |
no |
|
pause_on_recs |
int |
no |
|
blacklist_mode |
int |
no |
0=global, 1=Selection, 2=all, 3=none |
blacklist_ids |
array |
if blacklist_mode == 1 |
array of blacklist ids |
switch_min_before |
int |
no |
|
avoid_repeats |
boolean |
no |
|
allowed_repeats |
int |
no |
|
repeats_within_days |
int |
no |
|
compare_title |
boolean |
no |
|
compare_subtitle |
boolean |
no |
|
compare_summary |
boolean |
no |
|
compare_categories |
int |
no |
|
priority |
int |
no |
|
lifetime |
int |
no |
|
margin_start |
int |
no |
|
margin_stop |
int |
no |
|
use_vps |
boolean |
no |
|
del_mode |
int |
no |
0 = no, 1 = recordings count, 2 = days count |
del_after_count_recs |
int |
if del_mode == 1 |
|
del_after_days_of_first_rec |
int |
id del_mode == 2 |
|
ignore_missing_epg_cats |
boolean |
no |
|
unmute_sound_on_switch |
boolean |
no |
|
summary_match |
int |
no |
0 - 100, default 90 |
compare_time |
int |
no |
0 = no, 1 = same day, 2 = same week, 3 = same month |
DELETE
DELETE http://<ip>:<port>/searchtimers/<id>
GET
GET http://<ip>:<port>/searchtimers/search/<id>.<format>
GET
GET http://<ip>:<port>/searchtimers/blacklists.<format>
GET
GET http://<ip>:<port>/searchtimers/recordingdirs.<format>
GET
GET http://<ip>:<port>/searchtimers/channelgroups.<format>
GET
GET http://<ip>:<port>/searchtimers/extepginfo.<format>
GET
GET http://<ip>:<port>/searchtimers/conflicts.<(json|xml|html)>
Retrieve Images from additional media.
GET
GET http://<ip>:<port>/scraper/image/<path>/<provided>/<within>/<additional>/<media>.jpg
GET http://<ip>:<port>/scraper/image/size/360/240/<path>/<provided>/<within>/<additional/<media>.jpg
GET http://<ip>:<port>/scraper/image/width/360/<path>/<provided>/<within>/<additional/<media>.jpg
GET http://<ip>:<port>/scraper/image/heigh/240/<path>/<provided>/<within>/<additional/<media>.jpg
This service gets the state of the Wirbelscan plugin.
GET
GET http://<ip>:<port>/wirbelscan/getStatus.json
{
"status":2
}
{
"status":1,
"currentDevice":"CXD2837 DVB-C DVB-T/T2",
"progress":1,"strength":0,
"transponder":"DVB-C 113.000MHz M2 SR6900",
"numChannels":552,"newChannels":0,"nextTransponder":0
}
- 0 = no status information available, try again later.
- 1 = scan in progress.
- 2 = no scan in progress (not started, finished or stopped).
- 3 = plugin is busy, try again later.
This service retrieves the list of countries from the Wirbelscan plugin.
GET
GET http://<ip>:<port>/wirbelscan/countries.json
{"countries":
[
{"id":0,"shortName":"AF","fullName":"AFGHANISTAN"},
{"id":1,"shortName":"AX","fullName":"\ufffdLAND ISLANDS"},
{"id":2,"shortName":"AL","fullName":"ALBANIA"},
{"id":3,"shortName":"DZ","fullName":"ALGERIA"},
...
{"id":246,"shortName":"ZM","fullName":"ZAMBIA"},
{"id":247,"shortName":"ZW","fullName":"ZIMBABWE"}
],
"count":0,
"total":248
}
This service retrieves the list of satellites from the Wirbelscan plugin.
GET
GET http://<ip>:<port>/wirbelscan/satellites.json
{"satellites":
[
{"id":0,"shortName":"S180E0","fullName":"180.0 east Intelsat 18"},
{"id":1,"shortName":"S172E0","fullName":"172.0 east GE 23"},
{"id":2,"shortName":"S169E0","fullName":"169.0 east Intelsat 5"},
{"id":3,"shortName":"S166E0","fullName":"166.0 east Intelsat 8"},
...
{"id":131,"shortName":"S139W0","fullName":"135.0 west AMC 8"},
{"id":132,"shortName":"S177W0","fullName":"177.0 west NSS 9"}
],
"count":0,
"total":133
}
This service retrieves the current setup of the Wirbelscan plugin.
GET
GET http://<ip>:<port>/wirbelscan/getSetup.json
{
"verbosity":5,
"logFile":2,
"DVB_Type":2,
"DVBT_Inversion":0,
"DVBC_Inversion":0,
"DVBC_Symbolrate":0,
"DVBC_QAM":0,
"CountryId":82,
"SatId":6,
"scanflags":31,
"ATSC_type":0
}
- verbosity - 0 (errors only) .. 5 (extended debug); default = 3 (messages)
- logFile - 0 = off, 1 = stdout, 2 = syslog
- DVB_Type - DVB-T = 0, DVB-C = 1, DVB-S/S2 = 2, PVRINPUT = 3, PVRINPUT(FM Radio) = 4, ATSC = 5, TRANSPONDER = 999
- DVBT_Inversion - AUTO/OFF = 0, AUTO/ON = 1
- DVBC_Inversion - AUTO/OFF = 0, AUTO/ON = 1
- DVBC_Symbolrate - careful here - may change. AUTO = 0, 6900 = 1, 6875 = 2 (...) 14 = 5483, 15 = ALL
- DVBC_QAM - AUTO = 0,QAM64 = 1, QAM128 = 2, QAM256 = 3, ALL = 4
- CountryId - the id according to country, found in country list, see wirbelscan_GetCountry
- SatId - the id according to satellite, found in list, see wirbelscan_GetSat
- scanflags - bitwise flag of TV=1, RADIO=2, FTA=4, SCRAMBLED=8, HDTV=16 (default 31 -> TV + Radio, SD + HDTV, FTA
+ Scrambled)
- ATSC_type - VSB = 0, QAM = 1, both VSB+QAM = 2
This service changes the current setup of the Wirbelscan plugin and returns the updated setup.
PUT
PUT http://<ip>:<port>/wirbelscan/setSetup.json
For a description of the setup values see Get the current setup
{
"verbosity": 3,
"logFile": 1,
"DVB_Type": 3,
"DVBT_Inversion": 0,
"DVBC_Inversion": 0,
"DVBC_Symbolrate": 0,
"DVBC_QAM": 0,
"CountryId": 82,
"SatId": 67,
"scanflags": 31,
"ATSC_type": 0
}
This service launches a command with the Wirbelscan plugin.
POST
POST http://<ip>:<port>/wirbelscan/doCommand.json
- 0 = start scanning
- 1 = stop scanning
- 2 = store current setup
{
"replycode":true
}
This service can deliver files from configured folders. Multiple webapps can be defined within config file. Seperate paths with a comma. Specified paths must exist for the service to be initialized.
Known file types are defined in <plugin_conf_dir>/webapp_file_types.conf
GET
GET http://<ip>:<port>/<webapp>/<path>/<to>/<file>
Specify folder in plugin settings file (--webapp=/var/lib/vdr/plugins/restfulapi/webapp,/var/lib/vdr/plugins/restfulapi/a-second-webapp)
Retrieve Femon data
GET
GET http://<ip>:<port>/femon.json
/**
* @typedef {{}} recordingData
* @property {number} number
* @property {string} name
* @property {string} file_name
* @property {string} relative_file_name
* @property {string} inode
* @property {boolean} is_new
* @property {boolean} is_edited
* @property {boolean} is_pes_recording
* @property {number} duration
* @property {number} filesize_mb
* @property {string} channel_id
* @property {number} frames_per_second
* @property {Array.<string>} marks
* @property {string} event_title
* @property {string} event_short_text
* @property {string} event_description
* @property {number} event_start_time
* @property {number} event_duration
* @property {additionalMediaMovie|additionalMediaEpisode} additional_media
* @property {string} sync_action
*/
/**
* @typedef {{}} broadcastData
* @property {string} channel
* @property {string} channel_name
* @property {Array.<component>} components
* @property {Array} contents
* @property {string} description
* @property {Array} details
* @property {Number} duration
* @property {Number} id
* @property {Number} images
* @property {Number} parental_rating
* @property {Array} raw_contents
* @property {string} short_text
* @property {Number} table_id
* @property {boolean} timer_active
* @property {boolean} timer_exists
* @property {Number} timer_id
* @property {string} title
* @property {Number} version
* @property {Number} vps
* @property {Number} start_time
* @property {Number} end_time
* @property {Date} start_date
* @property {Date} end_date
*/
/**
* @typedef {{}} component
* @property {String} description
* @property {String} language
* @property {Number} stream
* @property {Number} type
*/
/**
* @typedef {{}} actor
* @property {String} name
* @property {String} role
* @property {String} thumb
*/
/**
* @typedef {{}} banners
* @property {Number} width
* @property {Number} height
* @property {String} path
*/
/**
* @typedef {{}} fanarts
* @property {Number} width
* @property {Number} height
* @property {String} path
*/
/**
* @typedef {{}} posters
* @property {Number} width
* @property {Number} height
* @property {String} path
*/
/**
* @typedef {{}} additionalMediaMovie
* @property {Array.<actor>} actors
* @property {Boolean} adult
* @property {String} collection_fanart
* @property {String} collection_name
* @property {String} collection_poster
* @property {String} fanart
* @property {String} genres
* @property {String} homepage
* @property {Number} movie_id
* @property {String} original_title
* @property {String} overview
* @property {Number} popularity
* @property {String} poster
* @property {String} release_date
* @property {Number} revenue
* @property {Number} runtime
* @property {String} tagline
* @property {String} title
* @property {String} type
* @property {Number} vote_average
*/
/**
* @typedef {{}} additionalMediaEpisode
* @property {Array.<banners>} banners
* @property {String} episode_first_aired
* @property {String} episode_guest_stars
* @property {Number} episode_id
* @property {String} episode_image
* @property {String} episode_name
* @property {Number} episode_number
* @property {String} episode_overview
* @property {Number} episode_rating
* @property {Number} episode_season
* @property {Array.<fanarts>} fanarts
* @property {String} first_aired
* @property {String} genre
* @property {String} name
* @property {String} network
* @property {String} overview
* @property {Array.<posters>} posters
* @property {Number} rating
* @property {Number} series_id
* @property {String} status
* @property {String} type
*/
/**
* @typedef {{}} infoData
* @property {infoDiskUsage} diskusage
* @property {infoService[]} services
* @property {number} time
* @property {infoVDR} vdr
* @property {string} version
*
*/
/**
* @typedef {{}} infoVDR
* @property {infoPlugin[]} plugins
* @property {infoDevice[]} devices
*/
/**
* @typedef {{}} infoDevice
* @property {number} adapter
* @property {boolean} atsc
* @property {string} channel_id
* @property {string} channel_name
* @property {number} channel_nr
* @property {boolean} dvb_c
* @property {boolean} dvb_s
* @property {boolean} dvb_t
* @property {number} frontend
* @property {boolean} has_ci
* @property {boolean} has_decoder
* @property {boolean} live
* @property {string} name
* @property {number} number
* @property {boolean} primary
* @property {number} signal_quality
* @property {number} signal_strength
* @property {number} snr
* @property {number} str
* @property {number} ber
* @property {number} unc
* @property {string} status
* @property {string} type
*/
/**
* @typedef {{}} infoPlugin
* @property {string} name
* @property {string} version
*/
/**
* @typedef {{}} infoService
* @property {string} name
* @property {number} version
*/
/**
* @typedef {{}} infoDiskUsage
* @property {string} description_localized
* @property {number} free_mb
* @property {number} free_minutes
* @property {number} used_percent
*/
/**
* @typedef {{}} conflictResult
* @property {number} count
* @property {number} total
* @property {Array.<timerConflict|string>} conflicts
* @property {boolean} check_advised
*/
/**
* @typedef {{}} searchTimerData
* @property {number} id
* @property {string} search
* @property {number} mode
* @property {number} tolerance
* @property {boolean} match_case
* @property {boolean} use_title
* @property {boolean} use_subtitle
* @property {boolean} use_description
* @property {string} content_descriptors
* @property {boolean} use_ext_epg_info
* @property {Array.<string>} ext_epg_info
* @property {boolean} use_in_favorites
* @property {boolean} use_time
* @property {number} start_time
* @property {number} stop_time
* @property {number} use_channel
* @property {string} channel_min
* @property {string} channel_max
* @property {string} channels
* @property {boolean} use_duration
* @property {number} duration_min
* @property {number} duration_max
* @property {boolean} use_dayofweek
* @property {number} dayofweek
* @property {number} use_as_searchtimer
* @property {number} use_as_searchtimer_from
* @property {number} use_as_searchtimer_til
* @property {number} searchtimer_action
* @property {boolean} use_series_recording
* @property {string} directory
* @property {number} del_recs_after_days
* @property {number} keep_recs
* @property {number} pause_on_recs
* @property {number} blacklist_mode
* @property {Array.<number>} blacklist_ids
* @property {number} switch_min_before
* @property {boolean} avoid_repeats
* @property {number} allowed_repeats
* @property {number} repeats_within_days
* @property {boolean} compare_title
* @property {number} compare_subtitle
* @property {boolean} compare_summary
* @property {number} compare_categories
* @property {number} priority
* @property {number} lifetime
* @property {number} margin_start
* @property {number} margin_stop
* @property {boolean} use_vps
* @property {number} del_mode
* @property {number} del_after_count_recs
* @property {number} del_after_days_of_first_rec
* @property {boolean} ignore_missing_epg_cats
* @property {boolean} unmute_sound_on_switch
* @property {number} summary_match
* @property {number} compare_time
*/
/**
* @typedef {{}} timerData
* @property {number} event_id
* @property {number} flags
* @property {number} index
* @property {number} lifetime
* @property {number} priority
* @property {number} start
* @property {number} stop
* @property {boolean} is_active
* @property {boolean} is_pending
* @property {boolean} is_recording
* @property {string} aux
* @property {string} channel
* @property {string} day
* @property {string} filename
* @property {string} id
* @property {string} start_timestamp
* @property {string} stop_timestamp
* @property {string} weekdays
* @property {string} channel_name
*/