Epgdb » History » Revision 22
Revision 21 (Dave Chapman, 2012-11-13 09:45) → Revision 22/23 (Adam Sutton, 2012-11-13 18:06)
h1. EPG database structure
Tvheadend maintains an internal (in memory) EPG database for the purpose of providing This page is a viewable programming schedule and scheduling recordings etc.
This work-in-progress to document describes the basic structures (and connections) that make up the database.
h2. On-disk format
The internal EPG database is written out to disk on shutdown and loaded in on startup. This avoids having to wait for the various grabbers to re-populate it.
The details of the on-disk structure are not covered here (yet), though in essence its just a serialised representation of the in-memory format. tvh.
Should you wish to convert the binary format into a human readable format then you can use epgdump script provided in the source package:
<pre>
./support/epgdump PATH_TO_DB
</pre>
Note: in most cases PATH_TO_DB will be ~TVH_USER/.hts/epgdb.v2
h2. Memory format
All objects have an _id_ field that is internally generated within Tvheadend and is an auto-incrementing number that is global across all object types. This is generally the ID that is also used for referencing object within the HTSP API.
The tables below provide detailed information about each object.
* The _HTSP_ "HTSP" column indicates the name of the field in the HTSP event messages (see "eventAdd":https://www.lonelycoder.com/redmine/projects/tvheadend/wiki/HTSP#eventAdd-Added-in-version-6) message.
* The _Grabber_ "Populated from" columns indicate which grabbers support the fields. Though it should be noted whether a specific field is actually filled in will depend on the upstream EPG source data.
* Fields marked NA are either internally generated, represent linkages or are not in use within the object.
* Some fields may be supported by the grabber protocols but simply not (yet) processed by TVH, in this case the fields are marked _N_.
h3. Object URIs
The object unique references provided by the grabbers (URIs) are used to help differentiate between data can populate that represents the same thing. This can be very useful for DVR operations where you need to be able to detect a set of broadcasts to record and eliminate duplicates content etc... field.
Not all grabbers provide such IDs, however for all EPG object (except broadcast and episode_number) they are required within TVH. Therefore if no URI is provided by the grabber TVH will generate one internally. This will have the format: {{toc}}
<pre>
tvh://channel-CHANID/bcast-BCASTID/episode
</pre>
Within the grabber types the presence of unique IDs will depend a lot on the upstream data source. For example EIT only has support for systems using CRIDs (e.g. Freesat or Freeview in the UK), XMLTV only has support for systems using dd_progid (Note: this will change in future as other systems exist).
h3. h2. Brand object - epg_brand_t
Brands can be seen as analogous to a TV Show.
Examples might include _The Simpsons_, _24_, _Eastenders_, etc.
|\4=. | |\4=.Grabbers| |\4=.Populated from|
|_.Field|_.Type|_.Description|_.HTSP| |_.DVB EIT|_.OpenTV|_.XMLTV|_.PyEPG| EIT|_.OpenTV|_.XML TV|_.PyEPG|
|id|uint32_t|Internal ID|brandId| |\4=. NA| | | | | |
|uri|char*|Unique ID (from grabber)| | |=. N|=. N|=. N|=. Y| | | | | |
|title|lang_str_t*|Brand name| | |=. N|=. N|=. N|=. Y| | | | | |
|summary|lang_str_t*|Brand summary| | |=. N|=. N|=. N|=. Y| | | | | |
|season_count|uint16_t|Total number of seasons| | |=. N|=. N|=. N|=. Y| | | | | |
|image|char*|Brand image| | | | | |=. N|=. N|=. N|=. Y| Yes |
|seasons|epg_season_list_t|Season list| ||\4=. NA| | | | | | |
|episodes|epg_episode_list_t|Episode list| ||\4=. NA| | | | | | |
Note: At present the XMLTV standard does not allow for proper brand identification, however some custom extensions exist that will eventually be supported.
h3. h2. Season object - epg_season_t
A Season represents a single season of a TV Show.
Examples might include _The Simpsons - Season 10_, _24 - Season 2_, etc.
|\4=. | |\4=.Grabbers| |\4=.Populated from|
|_.Field|_.Type|_.Description|_.HTSP| |_.DVB EIT|_.OpenTV|_.XMLTV|_.PyEPG| EIT|_.OpenTV|_.XML TV|_.PyEPG|
|id|uint32_t|Internal ID|seasonId| |\4=. NA| | | | | |
|uri|char*|Unique ID (from grabber)| | |=. N|=. N|=. N|=. Y| | | | | |
|summary|lang_str_t*|Season summary| | |=. N|=. N|=. N|=. Y| | | | | |
|number|uint16_t|The season number| | |=. N|=. N|=. N|=. Y| | | | | |
|episode_count|uint16_t|Total number of episodes| | |=. N|=. N|=. N|=. Y| | | | | |
|image|char*|Season image| | | | | |=. N|=. N|=. N|=. Y| Yes |
|brand|epg_brand_t|Parent brand| | |\4=. NA| | | | | |
|episodes|epg_episode_list_t|Episode list| | |\4=. NA|
Note: At present the XMLTV standard does not allow for proper season identification, however some custom extensions exist that will eventually be supported.
h3. | | | | |
h2. Episode object - epg_episode_t
An episode represents the information that is shared between broadcasts of the same content.
|\4=. | |\4=.Grabbers| |\4=.Populated from|
|_.Field|_.Type|_.Description|_.HTSP| |_.DVB EIT|_.OpenTV|_.XMLTV|_.PyEPG| EIT|_.OpenTV|_.XML TV|_.PyEPG|
|id|uint32_t|Internal ID|episodeId| |\4=. NA| | | | | |
|uri|char*|Unique ID (from grabber)| | |=. Y^1|=. N|=. Y^2|=. Y| Yes | |=. Yes |=. Yes |
|title|lang_str_t*|Title|title| |=. Y|=. Y|=. Y|=. Y| Yes |=. Yes |=. Yes |=. Yes |
|subtitle|lang_str_t*|Sub-title| | | | |=. N|=. N|=. Y|=. Y| Yes |=. Yes |
|summary|lang_str_t*|Summary|summary^3| |summary|lang_str_t*|Summary|summary*| | | |=. Y|=. N|=. Y|=. Y| Yes |=. Yes |
|description|lang_str_t*|An extended description|description^3| description|description*| | | |=. Y|=. N|=. Y|=. Y| Yes |=. Yes |
|image|char*|URL of episode image|image| | | | |=. N|=. N|=. N|=. Y| Yes |
|genre|epg_genre_list_t|Episode genre(s)|contentType^4| genre(s)|contentType*| |=. Y|=. Y|=. Y|=. Y| Yes |=. Yes |=. Yes |=. Yes |
|epnum|epg_episode_num_t|Episode numbering| | |\4=. NA (see below)| | | |=. Yes | |
|is_bw|uint8_t|Is black and white| | |=. Y|=. N|=. Y|=. Y| Yes | |=. Yes |=. Yes |
|star_rating|uint8_t|Star rating|starRating| | | |=. N|=. N|=. Y|=. N| Yes | |
|age_rating|uint8_t|Age certificate|ageRating| |=. Y|=. N|=. N|=. N| Yes | | | |
|first_aired|time_t|Original airdate|firstAired| | | |=. N|=. N|=. N|=. N| Yes | |
|brand|epg_brand_t*|(Grand-)Parent brand| | |\4=. NA| | | | | |
|season|epg_season_t*|Parent season| | |\4=. NA| | | |=. Yes |=. Yes |
|broadcasts|epg_broadcast_list_t|Broadcast list| | |\4=. NA| |=. Yes |=. Yes |=. Yes |=. Yes |
* ^1 This is only provided by EIT systems supporting the CRID system.
* ^2 This is only currently provided by XMLTV systems using the dd_progid namespace.
* ^3 Summary/description summary/description will be replaced with the versions in the specific broadcast, if they differ.
* ^4 contentType contains only the first genre in the case where multiple genres are stored.
h4. h3. Episode numbering object - epg_episode_num_t:
The This is for some back-compat and also to allow episode number can contains both episode and season numbering. Season information is duplicated here to remove the requirement be "collated" into easy to create "dummy" season objects simply to support a season number. use object
|\4=. | |\4=.Grabbers| |\4=.Populated from|
|_.Field|_.Type|_.Description|_.HTSP| |_.DVB EIT|_.OpenTV|_.XMLTV|_.PyEPG| EIT|_.OpenTV|_.XML TV|_.PyEPG|
|s_num|uint16_t|Series number|seasonNumber| | | |=. N|=. N|=. Y|=. Y| Yes | |
|s_cnt|uint16_t|Series count|seasonCount| | | |=. N|=. N|=. Y|=. Y| Yes | |
|e_num|uint16_t|Episode number|episodeNumber| | | |=. N|=. N|=. Y|=. Y| Yes | |
|e_cnt|uint16_t|Episode count|episodeCount| | | |=. N|=. N|=. Y|=. Y| Yes | |
|p_num|uint16_t|Part number|partNumber| | | |=. N|=. N|=. Y|=. Y| Yes | |
|p_cnt|uint16_t|Part count|partCount| | | |=. N|=. N|=. Y|=. Y| Yes | |
|text|char*|Arbitary text description of episode num|episodeOnscreen| | | |=. N|=. N|=. Y|=. N|
h3. Yes | |
h2. Broadcast object - epg_broadcast_t
This object contains the details of a specific airing (channel & time) of an episode.
|\4=. |\3=. | |\4=.Grabbers| |\4=.Populated from|
|_.Field|_.Type|_.Description|_.HTSP| |_.DVB EIT|_.OpenTV|_.XML TV|_.PyEPG|
|id|uint32_t|Internal ID|eventId| | |\4=. NA| | | | |
|uri|char*|Unique ID (from grabber)| | |\4=. NA| | | | | |
|dvb_eid|uint16_t|DVB Event ID| | |=. Y|=. N|=. N|=. N| Yes | | | |
|start|time_t|Start time (UTC)|start| |=. Y|=. Y|=. Y|=. Y| Yes |=. Yes |=. Yes |=. Yes |
|stop|time_t|Stop time (UTC)|stop| |=. Y|=. Y|=. Y|=. Y| Yes |=. Yes |=. Yes |=. Yes |
|is_widescreen|uint8_t|Is widescreen| | |=. Y|=. N|=. Y|=. Y| Yes | |=. Yes |=. Yes |
|is_hd|uint8_t|Is HD| | |=. Y|=. N|=. Y|=. Y| Yes | |=. Yes |=. Yes |
|lines|uint16_t|Lines in image (quality)| | | | |=. Y|=. N|=. Y|=. N| Yes | |
|aspect|uint16_t|Aspect ratio (*100)| | | | |=. Y|=. N|=. Y|=. N| Yes | |
|is_deafsigned|uint8_t|In screen signing| | |=. Y|=. N|=. Y|=. N| Yes | |=. Yes | |
|is_subtitled|uint8_t|Teletext subtitles| | |=. Y|=. N|=. Y|=. N| Yes | |=. Yes | |
|is_audio_desc|uint8_t|Audio description| | |=. Y|=. N|=. Y|=. N| Yes | |=. Yes | |
|is_new|uint8_t|New series / film premiere| | | | |=. N|=. N|=. Y|=. Y| Yes |=. Yes |
|is_repeat|uint8_t|Repeat screening| | | | |=. N|=. N|=. Y|=. Y| Yes |=. Yes |
|summary|lang_str_t*|Summary|summary^1| |summary|lang_str_t*|Summary|summary*| |=. Y|=. Y|=. Y|=. Y| Yes |=. Yes | |=. Yes |
|description|lang_str_t*|An extended description|description^1| description|description*| |=. Y|=. Y|=. Y|=. Y| Yes |=. Yes |=. Yes |=. Yes |
|episode|epg_episode_t*|Link to tvheadend episode object| | |\4=. NA| |=. Yes |=. Yes |=. Yes |=. Yes |
|serieslink|epg_serieslink_t*|SeriesLink| |serieslink|epg_serieslink_t*|SeriesLink|serieslinkid| |=. Yes |=. Yes |=. Yes |=. Yes | |\4=. NA|
|channel|struct channel*|Channel being broadcast on|channelId| |\4=. NA| |=. Yes |=. Yes |=. Yes |=. Yes |
^1 * summary/description will override the versions in the episode object
h3. h2. SeriesLink object - epg_serieslink_t
This object represents a related set of broadcasts intended to be automatically recorded by a DVR. DVR
|\4=. |\3=. | |\4=.Populated from|
|_.Field|_.Type|_.Description|_.HTSP| |_.DVB EIT|_.OpenTV|_.XML TV|_.PyEPG|
|id|uint32_t|Internal ID|serieslinkId| |\4=. NA| ID|eventId| | | | | |
|uri|char*|Unique ID (from grabber)| | |=. Y|=. Y|=. Y|=. N| Yes |=. Yes | | |
|broadcasts|epg_broadcast_list_t|List of broadcasts| | |\4=. NA| | | | | |
Tvheadend maintains an internal (in memory) EPG database for the purpose of providing This page is a viewable programming schedule and scheduling recordings etc.
This work-in-progress to document describes the basic structures (and connections) that make up the database.
h2. On-disk format
The internal EPG database is written out to disk on shutdown and loaded in on startup. This avoids having to wait for the various grabbers to re-populate it.
The details of the on-disk structure are not covered here (yet), though in essence its just a serialised representation of the in-memory format. tvh.
Should you wish to convert the binary format into a human readable format then you can use epgdump script provided in the source package:
<pre>
./support/epgdump PATH_TO_DB
</pre>
Note: in most cases PATH_TO_DB will be ~TVH_USER/.hts/epgdb.v2
h2. Memory format
All objects have an _id_ field that is internally generated within Tvheadend and is an auto-incrementing number that is global across all object types. This is generally the ID that is also used for referencing object within the HTSP API.
The tables below provide detailed information about each object.
* The _HTSP_ "HTSP" column indicates the name of the field in the HTSP event messages (see "eventAdd":https://www.lonelycoder.com/redmine/projects/tvheadend/wiki/HTSP#eventAdd-Added-in-version-6) message.
* The _Grabber_ "Populated from" columns indicate which grabbers support the fields. Though it should be noted whether a specific field is actually filled in will depend on the upstream EPG source data.
* Fields marked NA are either internally generated, represent linkages or are not in use within the object.
* Some fields may be supported by the grabber protocols but simply not (yet) processed by TVH, in this case the fields are marked _N_.
h3. Object URIs
The object unique references provided by the grabbers (URIs) are used to help differentiate between data can populate that represents the same thing. This can be very useful for DVR operations where you need to be able to detect a set of broadcasts to record and eliminate duplicates content etc... field.
Not all grabbers provide such IDs, however for all EPG object (except broadcast and episode_number) they are required within TVH. Therefore if no URI is provided by the grabber TVH will generate one internally. This will have the format: {{toc}}
<pre>
tvh://channel-CHANID/bcast-BCASTID/episode
</pre>
Within the grabber types the presence of unique IDs will depend a lot on the upstream data source. For example EIT only has support for systems using CRIDs (e.g. Freesat or Freeview in the UK), XMLTV only has support for systems using dd_progid (Note: this will change in future as other systems exist).
h3. h2. Brand object - epg_brand_t
Brands can be seen as analogous to a TV Show.
Examples might include _The Simpsons_, _24_, _Eastenders_, etc.
|\4=. | |\4=.Grabbers| |\4=.Populated from|
|_.Field|_.Type|_.Description|_.HTSP| |_.DVB EIT|_.OpenTV|_.XMLTV|_.PyEPG| EIT|_.OpenTV|_.XML TV|_.PyEPG|
|id|uint32_t|Internal ID|brandId| |\4=. NA| | | | | |
|uri|char*|Unique ID (from grabber)| | |=. N|=. N|=. N|=. Y| | | | | |
|title|lang_str_t*|Brand name| | |=. N|=. N|=. N|=. Y| | | | | |
|summary|lang_str_t*|Brand summary| | |=. N|=. N|=. N|=. Y| | | | | |
|season_count|uint16_t|Total number of seasons| | |=. N|=. N|=. N|=. Y| | | | | |
|image|char*|Brand image| | | | | |=. N|=. N|=. N|=. Y| Yes |
|seasons|epg_season_list_t|Season list| ||\4=. NA| | | | | | |
|episodes|epg_episode_list_t|Episode list| ||\4=. NA| | | | | | |
Note: At present the XMLTV standard does not allow for proper brand identification, however some custom extensions exist that will eventually be supported.
h3. h2. Season object - epg_season_t
A Season represents a single season of a TV Show.
Examples might include _The Simpsons - Season 10_, _24 - Season 2_, etc.
|\4=. | |\4=.Grabbers| |\4=.Populated from|
|_.Field|_.Type|_.Description|_.HTSP| |_.DVB EIT|_.OpenTV|_.XMLTV|_.PyEPG| EIT|_.OpenTV|_.XML TV|_.PyEPG|
|id|uint32_t|Internal ID|seasonId| |\4=. NA| | | | | |
|uri|char*|Unique ID (from grabber)| | |=. N|=. N|=. N|=. Y| | | | | |
|summary|lang_str_t*|Season summary| | |=. N|=. N|=. N|=. Y| | | | | |
|number|uint16_t|The season number| | |=. N|=. N|=. N|=. Y| | | | | |
|episode_count|uint16_t|Total number of episodes| | |=. N|=. N|=. N|=. Y| | | | | |
|image|char*|Season image| | | | | |=. N|=. N|=. N|=. Y| Yes |
|brand|epg_brand_t|Parent brand| | |\4=. NA| | | | | |
|episodes|epg_episode_list_t|Episode list| | |\4=. NA|
Note: At present the XMLTV standard does not allow for proper season identification, however some custom extensions exist that will eventually be supported.
h3. | | | | |
h2. Episode object - epg_episode_t
An episode represents the information that is shared between broadcasts of the same content.
|\4=. | |\4=.Grabbers| |\4=.Populated from|
|_.Field|_.Type|_.Description|_.HTSP| |_.DVB EIT|_.OpenTV|_.XMLTV|_.PyEPG| EIT|_.OpenTV|_.XML TV|_.PyEPG|
|id|uint32_t|Internal ID|episodeId| |\4=. NA| | | | | |
|uri|char*|Unique ID (from grabber)| | |=. Y^1|=. N|=. Y^2|=. Y| Yes | |=. Yes |=. Yes |
|title|lang_str_t*|Title|title| |=. Y|=. Y|=. Y|=. Y| Yes |=. Yes |=. Yes |=. Yes |
|subtitle|lang_str_t*|Sub-title| | | | |=. N|=. N|=. Y|=. Y| Yes |=. Yes |
|summary|lang_str_t*|Summary|summary^3| |summary|lang_str_t*|Summary|summary*| | | |=. Y|=. N|=. Y|=. Y| Yes |=. Yes |
|description|lang_str_t*|An extended description|description^3| description|description*| | | |=. Y|=. N|=. Y|=. Y| Yes |=. Yes |
|image|char*|URL of episode image|image| | | | |=. N|=. N|=. N|=. Y| Yes |
|genre|epg_genre_list_t|Episode genre(s)|contentType^4| genre(s)|contentType*| |=. Y|=. Y|=. Y|=. Y| Yes |=. Yes |=. Yes |=. Yes |
|epnum|epg_episode_num_t|Episode numbering| | |\4=. NA (see below)| | | |=. Yes | |
|is_bw|uint8_t|Is black and white| | |=. Y|=. N|=. Y|=. Y| Yes | |=. Yes |=. Yes |
|star_rating|uint8_t|Star rating|starRating| | | |=. N|=. N|=. Y|=. N| Yes | |
|age_rating|uint8_t|Age certificate|ageRating| |=. Y|=. N|=. N|=. N| Yes | | | |
|first_aired|time_t|Original airdate|firstAired| | | |=. N|=. N|=. N|=. N| Yes | |
|brand|epg_brand_t*|(Grand-)Parent brand| | |\4=. NA| | | | | |
|season|epg_season_t*|Parent season| | |\4=. NA| | | |=. Yes |=. Yes |
|broadcasts|epg_broadcast_list_t|Broadcast list| | |\4=. NA| |=. Yes |=. Yes |=. Yes |=. Yes |
* ^1 This is only provided by EIT systems supporting the CRID system.
* ^2 This is only currently provided by XMLTV systems using the dd_progid namespace.
* ^3 Summary/description summary/description will be replaced with the versions in the specific broadcast, if they differ.
* ^4 contentType contains only the first genre in the case where multiple genres are stored.
h4. h3. Episode numbering object - epg_episode_num_t:
The This is for some back-compat and also to allow episode number can contains both episode and season numbering. Season information is duplicated here to remove the requirement be "collated" into easy to create "dummy" season objects simply to support a season number. use object
|\4=. | |\4=.Grabbers| |\4=.Populated from|
|_.Field|_.Type|_.Description|_.HTSP| |_.DVB EIT|_.OpenTV|_.XMLTV|_.PyEPG| EIT|_.OpenTV|_.XML TV|_.PyEPG|
|s_num|uint16_t|Series number|seasonNumber| | | |=. N|=. N|=. Y|=. Y| Yes | |
|s_cnt|uint16_t|Series count|seasonCount| | | |=. N|=. N|=. Y|=. Y| Yes | |
|e_num|uint16_t|Episode number|episodeNumber| | | |=. N|=. N|=. Y|=. Y| Yes | |
|e_cnt|uint16_t|Episode count|episodeCount| | | |=. N|=. N|=. Y|=. Y| Yes | |
|p_num|uint16_t|Part number|partNumber| | | |=. N|=. N|=. Y|=. Y| Yes | |
|p_cnt|uint16_t|Part count|partCount| | | |=. N|=. N|=. Y|=. Y| Yes | |
|text|char*|Arbitary text description of episode num|episodeOnscreen| | | |=. N|=. N|=. Y|=. N|
h3. Yes | |
h2. Broadcast object - epg_broadcast_t
This object contains the details of a specific airing (channel & time) of an episode.
|\4=. |\3=. | |\4=.Grabbers| |\4=.Populated from|
|_.Field|_.Type|_.Description|_.HTSP| |_.DVB EIT|_.OpenTV|_.XML TV|_.PyEPG|
|id|uint32_t|Internal ID|eventId| | |\4=. NA| | | | |
|uri|char*|Unique ID (from grabber)| | |\4=. NA| | | | | |
|dvb_eid|uint16_t|DVB Event ID| | |=. Y|=. N|=. N|=. N| Yes | | | |
|start|time_t|Start time (UTC)|start| |=. Y|=. Y|=. Y|=. Y| Yes |=. Yes |=. Yes |=. Yes |
|stop|time_t|Stop time (UTC)|stop| |=. Y|=. Y|=. Y|=. Y| Yes |=. Yes |=. Yes |=. Yes |
|is_widescreen|uint8_t|Is widescreen| | |=. Y|=. N|=. Y|=. Y| Yes | |=. Yes |=. Yes |
|is_hd|uint8_t|Is HD| | |=. Y|=. N|=. Y|=. Y| Yes | |=. Yes |=. Yes |
|lines|uint16_t|Lines in image (quality)| | | | |=. Y|=. N|=. Y|=. N| Yes | |
|aspect|uint16_t|Aspect ratio (*100)| | | | |=. Y|=. N|=. Y|=. N| Yes | |
|is_deafsigned|uint8_t|In screen signing| | |=. Y|=. N|=. Y|=. N| Yes | |=. Yes | |
|is_subtitled|uint8_t|Teletext subtitles| | |=. Y|=. N|=. Y|=. N| Yes | |=. Yes | |
|is_audio_desc|uint8_t|Audio description| | |=. Y|=. N|=. Y|=. N| Yes | |=. Yes | |
|is_new|uint8_t|New series / film premiere| | | | |=. N|=. N|=. Y|=. Y| Yes |=. Yes |
|is_repeat|uint8_t|Repeat screening| | | | |=. N|=. N|=. Y|=. Y| Yes |=. Yes |
|summary|lang_str_t*|Summary|summary^1| |summary|lang_str_t*|Summary|summary*| |=. Y|=. Y|=. Y|=. Y| Yes |=. Yes | |=. Yes |
|description|lang_str_t*|An extended description|description^1| description|description*| |=. Y|=. Y|=. Y|=. Y| Yes |=. Yes |=. Yes |=. Yes |
|episode|epg_episode_t*|Link to tvheadend episode object| | |\4=. NA| |=. Yes |=. Yes |=. Yes |=. Yes |
|serieslink|epg_serieslink_t*|SeriesLink| |serieslink|epg_serieslink_t*|SeriesLink|serieslinkid| |=. Yes |=. Yes |=. Yes |=. Yes | |\4=. NA|
|channel|struct channel*|Channel being broadcast on|channelId| |\4=. NA| |=. Yes |=. Yes |=. Yes |=. Yes |
^1 * summary/description will override the versions in the episode object
h3. h2. SeriesLink object - epg_serieslink_t
This object represents a related set of broadcasts intended to be automatically recorded by a DVR. DVR
|\4=. |\3=. | |\4=.Populated from|
|_.Field|_.Type|_.Description|_.HTSP| |_.DVB EIT|_.OpenTV|_.XML TV|_.PyEPG|
|id|uint32_t|Internal ID|serieslinkId| |\4=. NA| ID|eventId| | | | | |
|uri|char*|Unique ID (from grabber)| | |=. Y|=. Y|=. Y|=. N| Yes |=. Yes | | |
|broadcasts|epg_broadcast_list_t|List of broadcasts| | |\4=. NA| | | | | |