HTSP is a TCP based protocol primarily intended for streaming of live TV and related meta data such as channels, group of channels (called tags in HTSP) and electronic program guide (EPG) information.

The transmission and reception of a channel over HTSP is referred to as a subscription. A single HTSP session can handle as many concurrent subscriptions as the bandwidth and CPU permits.

The HTSP server in tvheadend has a payload-aware scheduler for prioritizing more important packets (such as I-frames) before less important ones (such as B-frames). This makes HTSP suitable for long-distance transmissions and/or paths with non-perfect delivery.(It has been tested with a server in Stockholm and the client in Berlin).

There is a normal RPC way of doing things. I.e. the client sends a request and the server responds with a reply. All the RPC methods are listed below as the 'Client to Server' methods. Apart from all message fields listed within each message type the client can add an additional field:

RPC request extra fields:

seq int optional Sequence number. This field will be echoed back by the server in the reply.
username str optional Username, in combination with 'digest' this can be used to raise the privileges
for the session in combination with invocation of a method.
digest bin optional Used to raise privileges.

The followings field should be used by the client to match the reply with the request.All replies are guaranteed to arrive in the same order as the requests.Even so, probably the best way to implement the request-reply client is by taking advantage of the 'seq' field.

RPC reply extra fields:

seq int optional Sequence number. Same as in the request.
error str optional If present an error has occurred and the text describes the error.
noaccess int optional If present and set to '1' the user is prohibited from invoking the method due to
access restrictions.

For streaming of live TV and various related messages the server will continuously push data to the client.These messages are referred to as asynchronous messages and always have the 'method' field set and never have the 'seq' field set.Also, the client can enable an additional asyncMetadata mode and by doing so it will be notified by the server when meta data changes. (EPG updates, creation of channels and tags, etc).

In Tvheadend, each method has an associated access restriction. Currently there is only one restriction (Streaming). However, this may change in the future.

Privileges for these restrictions may be granted in two ways: Username + Password and/or Source IP address.Therefore it is possible to gain permissions to the system without entering a username and password.While this is really useful it also complicates the authentication schema a bit.Upon connect the initial privileges will be raised based on the source address.

Before any username / password based authentication has taken place the client must haveobtained a challenge (which stays fixed for the session). This is done via the 'hello' method.

In principle it's possible to use two different authentication idioms with HTSP.Depending on how your application works one or another may be more suitable.While they do not really differ from a protocol point of view it's worth mentioning a bit about them here:

The client performs all of its authentication using the 'login' method.

It may choose to send:

Username and password: Privileges will be raised based on these credentials.

Username only: Privileges will be based on just the source address. The username will be used for various logging purposes.

Nothing: Privileges will be based on just the source address.

If no privileges are granted after the login message has been received by the server (i.e. both network and username + password based)the server will reply with 'noaccess' set to 1. A client that only employs initial login should honor this flag and ask theuser for a username + password and retry by using the 'authenticate' method. I.e. it should not send the 'login' method again.

When using this method, the client will check every RPC reply for the 'noaccess' field.If it set to 1 it whould ask the user for username + password and retry the request but alsoadd 'username' and 'digest' to the original message. (See RPC request extra fields above)

Used to identify the client toward the server and to get the session challenge used tohash passwords into digests. The client can request a different version of the HTSPprotocol with this method. If no 'hello' message is sent the server assumes latest versionis to be used.

Client/Server should select lowest common version, if this is not possible connection should be terminated.

When this is enabled the client will get continuous updates from the server about added, update or deleted channels, tags, dvr and epg entries.

An interactive application that presents the user with information about these things should probably enable this and the implement the various server to client methods.

Request message fields:

epg u32 optional Set to 1, to include EPG data in async, implied by epgMaxTime (Added in version 6).
lastUpdate s64 optional Only provide metadata that has changed since this time (Added in version 6).
epgMaxTime s64 optional Maximum time to return EPG data up to (Added in version 6)
language str optional RFC 2616 compatible language list (Added in version 6)

Reply message fields:

None

Once the reply as been sent the initial data set will be provided, and then updates will arrive asynchronously after that. The initial data dump is sent using the following messages:

Request information about a set of events. If no options are specified the entire EPG database will be returned.

Request message fields:

eventId u32 optional Event ID to begin from (Optional since version 6)
channelId u32 optional Channel ID to get data for (Added in version 6)
numFollowing u32 optional Number of events to add (Optional since version 6)
maxTime u64 optional Maximum time to return data up to (Added in version 6)
language str optional RFC 2616 compatible language list (Added in version 6)

Create a new DVR entry. Either eventId or channelId, start and stop must be specified.

Request message fields:

eventId u32 optional Event ID (Optional since version 5).
channelId u32 optional Channel ID (Added in version 5)
start s64 optional Time to start recording (Added in version 5)
stop s64 optional Time to stop recording (Added in version 5)
retention u32 optional Retention time in days (Added in version 13)
creator str optional Name of the event creator (Added in version 5, obsoleted in version 18 - applications are not allowed to change credential)
priority u32 optional Recording priority (Added in version 5)
startExtra s64 optional Pre-recording buffer in minutes (Added in version 5)
stopExtra s64 optional Post-recording buffer in minutes (Added in version 5)
title str optional Recording title, if no eventId (Added in version 6)
subtitle str optional Recording subtitle, if no eventId (Added in version 20)
description str optional Recording description, if no eventId (Added in version 5)
configName str optional DVR configuration name or UUID
enabled u32 optional Enabled flag (Added in version 23).

channelId u32 required ID for channel.
subscriptionId u32 required Subscription ID. Selected by client. This value is not interpreted by the server in any form.
The value is used from now on in all messages related to the subscription.
weight u32 optional Weighting of this subscription (same as recording priority).
90khz u32 optional Request PTS/DTS in default 90kHz timebase, default is 1MHz (Added in version 7)
normts u32 optional Request PTS/DTS normalisation (Added in version 7)
Note: this will mean missing timestamps are added, first packet should be ~0 and will always be an i-frame.
Note: this is implied if timeshiftPeriod is enabled
Note: from version 17, this is always enabled and this parameter is ignored.
queueDepth u32 optional Change the default packet queue lengths, default 500000 bytes (Added in version 7)
Note: I-frame depth is 3*queueDepth, P-frame is 2*queueDepth and B-frame is queueDepth
timeshiftPeriod u32 optional The number of seconds to keep in the timeshift buffer (Added in version 9)
Note: this may be bounded by server configuration settings
profile str optional Select stream profile (Added in version 16).

Reply message fields:

90khz u32 optional Indicates 90khz timestamps will be used
normts u32 optional Indicates timestamps will be normalised (and fixed)
timeshiftPeriod u32 optional The actual timeshiftPeriod to be used

channelId u32 required ID of channel.
channelNumber u32 required Channel number, 0 means unconfigured.
channelNumberMinor u32 optional Minor channel number (Added in version 13).
channelName str required Name of channel.
channelIcon str optional URL to an icon representative for the channel
(For v8+ clients this could be a relative /imagecache/ID URL
intended to be fed to fileOpen() or HTTP server)
(For v15+ clients this could be a relative imagecache/ID URL
intended to be fed to fileOpen() or HTTP server)
eventId u32 optional ID of the current event on this channel.
nextEventId u32 optional ID of the next event on the channel.
tags u32[] optional Tags this channel is mapped to.
services msg[] optional List of available services (Added in version 5)

tagId u32 required ID of tag.
tagName str required Name of tag.
tagIndex u32 optional Index value for sorting (default by from min to max) (Added in version 18).
tagIcon str optional URL to an icon representative for the channel.
tagTitledIcon u32 optional Icon includes a title
members u32[] optional Channel IDs of those that belong to the tag

id u32 required ID of dvrEntry.
channel u32 optional Channel of dvrEntry.
start s64 required Time of when this entry was scheduled to start recording.
stop s64 required Time of when this entry was scheduled to stop recording.
startExtra s64 required Extra start time (pre-time) in minutes (Added in version 13).
stopExtra s64 required Extra stop time (post-time) in minutes (Added in version 13).
retention s64 required DVR Entry retention time in days (Added in version 13).
priority u32 required Priority (0 = Important, 1 = High, 2 = Normal, 3 = Low, 4 = Unimportant, 5 = Not set) (Added in version 13).
eventId u32 optional Associated EPG Event ID (Added in version 13).
autorecId str optional Associated Autorec UUID (Added in version 13).
timerecId str optional Associated Timerec UUID (Added in version 18).
contentType u32 optional Content Type (like in the DVB standard) (Added in version 13).
title str optional Title of recording
subtitle str optional Subtitle of recording (Added in version 20).
summary str optional Short description of the recording (Added in version 6).
description str optional Long description of the recording.
state str required Recording state
error str optional Plain english error description (e.g. "Aborted by user").
owner str optional Name of the entry owner (Added in version 18).
creator str optional Name of the entry creator (Added in version 18).
subscriptionError str optional Subscription error string (Added in version 20).
streamErrors str optional Number of recording errors (Added in version 20).
dataErrors str optional Number of stream data errors (Added in version 20).
path str optional Recording path for playback.
files msg optional All recorded files for playback (Added in version 21).
dataSize s64 optional Actual file size of the last recordings (Added in version 21).
enabled u32 optional Enabled flag (Added in version 23).

Valid values for state:

TODO

Valid values for subscriptionError:

noFreeAdapter No free adapter for this service.
scrambled Service is scrambled.
badSignal Bad signal status.
tuningFailed Tuning of this service failed.
subscriptionOverridden Subscription overridden by another one.
muxNotEnabled No mux enabled for this service.
invalidTarget Recording/livestream cannot be saved to filesystem or recording/streaming configuration is incorrect.
userAccess User does not have access rights for this service.
userLimit Maximum number of streaming connections set in user's profile reached.

eventId u32 required Event ID
channelId u32 required The channel this event is related to.
start u64 required Start time of event, UNIX time.
stop u64 required Ending time of event, UNIX time.
title str optional Title of event.
summary str optional Short description of the event (Added in version 6).
description str optional Long description of the event.
serieslinkId u32 optional Series Link ID (Added in version 6).
episodeId u32 optional Episode ID (Added in version 6).
seasonId u32 optional Season ID (Added in version 6).
brandId u32 optional Brand ID (Added in version 6).
contentType u32 optional DVB content code (Added in version 4, Modified in version 6*).
ageRating u32 optional Minimum age rating (Added in version 6).
starRating u32 optional Star rating (1-5) (Added in version 6).
firstAired s64 optional Original broadcast time, UNIX time (Added in version 6).
seasonNumber u32 optional Season number (Added in version 6).
seasonCount u32 optional Show season count (Added in version 6).
episodeNumber u32 optional Episode number (Added in version 6).
episodeCount u32 optional Season episode count (Added in version 6).
partNumber u32 optional Multi-part episode part number (Added in version 6).
partCount u32 optional Multi-part episode part count (Added in version 6).
episodeOnscreen str optional Textual representation of episode number (Added in version 6).
image str optional URL to a still capture from the episode (Added in version 6).
dvrId u32 optional ID of a recording (Added in version 5).
nextEventId u32 optional ID of next event on the same channel.

*contentType previously had the major DVB category in the bottom 4 bits, however in v6 this has been changed to properly match DVB, so top 4 bits as major category and bottom 4 bits has sub-category. Clients requesting v5 or lower will get the old output.

Notifies client about the grace timeout (timeout for stream activation). It can be issues multiple times.For example a configuration with satellite rotors requires more than 120 seconds to tune, so usersshould be notified..

subscriptionId u32 required Subscription ID.
error u32 optional The last skip command caused an error.
absolute u32 optional Indicates the output is absolute (Note: should always be 1 at the moment)
time u64 optional The time the subscription has skipped to.
size u64 optional The position in the file we've skipped to (Note: not currently used).

subscriptionId u32 required Subscription ID.
full u32 required Indicates whether the buffer is full
shift s64 required Current position relative to live
start s64 optional PTS of the first frame in the buffer
end s64 optional PTS of the last frame in the buffer