Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
This communication is currently implemented by using htsmsg's. All strings are encoded as UTF-8.
There are two distinct ways for communication within HTSP.
Apart from this there is a number of messages that needs to be exchanged during login, see the login section below.
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:
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:
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 have obtained 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 the user for a username + password and retry by using the 'authenticate' method. I.e. it should not send the 'login' method again.
The client performs all of its authentication when it needs to.
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 also add 'username' and 'digest' to the original message. (See RPC request extra fields above)
Typically it would not send a username or digest during login.
added comment field to addDvrEntry, updateDvrEntry, autorecEntryAdd, autorecEntryUpdate, timerecEntryAdd, timerecEntryUpdate
added full UUID to channelAdd, tagAdd and dvrEntryAdd
added ratingAuthority and ratingCountry to dvrEntryAdd and eventAdd
added DVR configuration UUID to dvrEntryAdd, dvrEntryUpdate, autorecEntryAdd, autorecEntryUpdate, timerecEntryAdd, timerecEntryUpdate
added broadcast type to autorec DVR entry
added service provider name to channelAdd -> services
added ratingLabel to EPG & DVR entries
added ratingIcon to EPG & DVR entries
added ageRating to DVR entries
TODO
added updateAutorecEntry and updateTimerecEntry
(and other changes not yet documented here)
added descrambleInfo (not yet documented here)
extended addDvrEntry, updateDvrEntry, dvrEntryAdd method
added enabled
extended getSysTime
added gmtoffset
extended updateDvrEntry method
added channelId
dvrEntry structures
added files msg (multiple files) to the files field
added dataSize field to show actual (last) file size in dvrEntry updates
epg events - added subtitle field
dvrEntry structures
added subscriptionError, streamErrors, dataErrors fields
added subtitle fields
autorecEntry structures
added dupDetect and fulltext fields
added errors fields to the stream status
added satpos to the subscription start
added subscriptionError field to subscriptionStatus server-to-client method
autorec/timerec structures
added directory field (forced output directory)
added enabled field
added addTimerecEntry, deleteTimerecEntry methods
added timerecEntryAdd, timerecEntryUpdate, timerecEntryDelete server-to-client methods
extended addAutorecEntry method
added start/startWindow/name fields
added owner/creator fields
obsoleted creator field
extended dvrEntryAdd, dvrEntryUpdate
added timerecId field
added owner/creator fields
extended addAutorecEntry, deleteAutorecEntry methods
added start/startWindow fields
obsoleted approxTime
added name/owner/creator fields
extended autorecEntryAdd, autorecEntryUpdate server-to-client methods
fields like for addAutorecEntry
extended getTag method
added tagIndex field
extended subscriptionStart server-to-client method
added meta field
changed H264 meta data handling (codec meta data are in the meta field only in start message)
VORBIS and AAC codecs have codec specific meta data in the meta field in start message
changed subscribe method
the normts is always active and the parameter is ignored
added getProfiles, getDvrConfigs methods
removed getCodecs methods
extended subscribe method
add profile field
extended channelAdd, channelUpdate server-to-client methods
the channelIcon URL can be relative 'imagecache/%d' or '/imagecache/%d'
extended getChannel method
the channelIcon URL can be relative 'imagecache/%d' or '/imagecache/%d'
added getChannel method
added addAutorecEntry method
added deleteAutorecEntry method
added autorecEntryAdd, autorecEntryUpdate, autorecEntryDelete server-to-client methods
extended channelAdd server-to-client method
added channelNumberMinor (for {major}.{minor} channel numbers)
extended dvrEntryAdd and dvrEntryUpdate server-to-client methods
added eventId, autorecId, startExtra, stopExtra, retention, priority, contentType fields
extended addDvrEntry method
added retention
extended updateDvrEntry method
added retention, priority
extended epgQuery method
added minduration, maxduration
added subscriptionGrace server-to-client method
added subscriptionFilterStream method
added getDvrCutpoints method
added audio_type in the subscriptionStart server-to-client method
added getCodecs method
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).
For information about the HTSP wire format please refer to the following page: HTSMSG Binary Format.
If you're looking to develop a new client, there are several existing client implementations from which you might be able to gain knowledge:
PyHTSP (This is a demo client and is WIP, it has limited functionality).
A new channel has been created on the server.
Message fields:
Service fields:
Same as channelAdd, but all fields (except channelId) are optional.
A channel has been deleted on the server.
Message fields:
A new tag has been created on the server.
Message fields:
Same as tagAdd, but all fields (except tagId) are optional.
A tag has been deleted from the server.
Message fields:
(Added in version 4)
A new recording has been created on the server.
Message fields:
Valid values for state:
Valid values for subscriptionError:
Message fields:
(Added in version 4)
A recording has been deleted from the server.
Message fields:
(Added in version 13)
A new autorec recording has been created on the server.
Message fields:
(Added in version 13)
Message fields:
Message fields:
(Added in version 18)
A new autorec recording has been created on the server.
Message fields:
(Added in version 18)
Message fields:
(Added in version 18)
Message fields:
(Added in version 6)
Message fields:
*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.
(Added in version 6)
Message fields:
(Added in version 6)
Message fields:
(Added in version 2)
Sent after all the initial metadata has been sent when session has been set to async mode.
Message fields:
Asynchronous message output when a new subscription is successfully started.
Message fields:
Stream message fields:
Sourceinfo message fields:
Video Stream types:
Audio Stream types:
Subtitle Stream types:
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 users should be notified..
Message fields:
A subscription has been stopped.
Message fields:
Valid values for subscriptionError:
(Added in version 9)
A subscription has been skipped.
Message fields:
(Added in version 9)
A subscription's playback speed has changed.
This can happen even without a speed request, should playback reach either end of the buffer.
Message fields:
Subscription status update.
Message fields:
Valid values for subscriptionError:
The queueStatus message is sent every second during normal data delivery.
The transmit scheduler have different drop thresholds for different frame types.
If congestion occurs it will favor dropping B-frames before P-frames before I-frames. All audio is recognized as I-frames.
Message fields:
The signalStatus message is sent every second during normal data delivery.
The optional fields may not have been implemented or may not be supported by the active adapter.
Message fields:
Provide status every second about the timeshift buffer.
Message fields:
Streaming data.
Message fields:
The HTSP api
method can be used as a proxy to access the HTTP/JSON API. This allows HTSP-only clients access to any JSON feature, including JSON-only features.
Data exchanged to and from the TVH server is achieved by encapsulating the required HTTP/JSON parameters within the HTSP message.
TVH expects to receive encapsulated JSON data and will respond with a HTSP map representing the JSON data returned.
Also see: JSON API.
API
Syntax SummaryRequest:
Reply:
To execute the HTTP API command:
http://TVH:9981/api/channel/grid
Set the path
field to channel/grid
and send the request. The args
field is not required.
The response will be a HTSP map
containing an element named response
. This element will be a map
containing the the JSON response presented as HTSP elements.
To execute the HTTP API command:
http://TVH:9981/api/channel/grid?sort=number&dir=desc
Set the path to channel/grid
as in the previous example.
The arg
field must be set to type map
, and in this example, contain two str
elements.
Map str
element named sort
should contain the value number
and map str
element named dir
should contain the value desc
.
To execute the HTTP API command:
http://TVH:9981/api/dvr/entry/create
Set the path to dvr/entry/create
.
As with the previous example, the args
field must be set to type map
.
Method 1 - JSON String
Create a JSON string containing the properties required to complete the request as detailed in the JSON API documentation. In this example, to create a new DVR entry.
Within that map
, create a str
element named conf
that contains the required JSON string.
Method 2 - HTSP Map
Instead of creating a JSON string, create a HTSP map
where each element name matches the name of the JSON property and contains the required property value.
args
should be a map
that contains another map
named conf
that contains another map
with the required JSON data represented as HTSP elements.
Message Structure
A message can be of either map or list type. In a map each field has a name, in a list the members do not have names, but the order should be preserved.
The field types are:
Name | ID | Description |
---|---|---|
All in all the message structure is quite similar to JSON but most notably; no boolean nor null type exist and HTSMSG supports binary objects.
The binary format is designed to for back-to-back transmission of messages over a network (TCP) connection.
The root message must always be of type map.
The data is repeated HTSMSG-Fields exactly as the root body. Note the subtle difference in that for the root-message the length includes the 4 bytes of length field itself whereas in the field encoding the length written includes just the actual payload.
Integers are encoded using a very simple variable length encoding. All leading bytes that are 0 is discarded. So to encode the value 100, datalength should be 1 and the data itself should be just one byte [0x64]. To encode 1337; datalength=2, data=[0x39 0x05].
Note that there is no sign extension in this encoding scheme so if you need to encode -1 you need to set datalength=8 and data = [0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff]. This can certainly be thought of as a bug, but it is the way it is.
Datalength should be the length of the string (NOT including the null terminating character). Thus the null terminator should not be present in data either.
Datalength should be the length of the binary object. Data is the binary object itself.
Used to identify the client toward the server and to get the session challenge used to hash passwords into digests. The client can request a different version of the HTSP protocol with this method. If no 'hello' message is sent the server assumes latest version is to be used.
Client/Server should select lowest common version, if this is not possible connection should be terminated.
Request message fields:
Reply message fields:
Note: possible values for servercapability[]:
This can be used to issue authentication without doing anything else. If no privileges are gained it will return with 'noaccess' set to 1.
Request message fields:
Reply message fields:
(Added in version 24)
This is a proxy to HTTP API.
Request message fields:
Reply message fields:
(Added in version 3)
Return diskspace status from Tvheadend's PVR storage
Request message fields:
Reply message fields:
(Added in version 3)
Return system time on the server.
Request message fields:
Reply message fields:
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:
Reply message fields:
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:
(Added in version 14)
Request information about the given channel.
Request message fields:
Reply message fields:
Request information about the given event. An event typically corresponds to a program on a channel.
The language field in the request allows preference for languages to be requested for the various string fields.
Request message fields:
Reply message fields:
(Added in version 4)
Request information about a set of events. If no options are specified the entire EPG database will be returned.
Request message fields:
Reply message fields:
(Added in version 4)
Query the EPG (event titles) and optionally restrict to channel/tag/content type.
Request message fields:
Reply message fields:
if full == 1
else
Get detailed EPG Object info.
Request message fields:
Reply message fields:
(Added in version 16)
Return a list of DVR configurations.
Reply message fields:
Message fields:
(Added in version 4)
Create a new DVR entry. Either eventId or channelId, start and stop must be specified.
Request message fields:
Reply message fields:
(Added in version 5)
Update an existing DVR entry.
Request message fields:
Reply message fields:
(Added in version 5)
Cancel an existing recording, but don't remove the entry from the database.
Request message fields:
Reply message fields:
(Added in version 4)
Delete an existing DVR entry from the database.
Request message fields:
Reply message fields:
(Added in version 12)
Get DVR cutpoints.
Request message fields:
Reply message fields:
Cutpoint fields:
(Added in version 13)
Create a new Autorec DVR entry. Title must be specified.
Request message fields:
Reply message fields:
(Added in version 25)
Update an existing Autorec DVR entry.
Request message fields:
Reply message fields:
(Added in version 13)
Delete an existing autorec DVR entry from the database.
Request message fields:
Reply message fields:
(Added in version 18)
Create a new Timerec DVR entry. Title must be specified.
Request message fields:
Reply message fields:
(Added in version 25)
Update an existing Timerec DVR entry.
Request message fields:
Reply message fields:
(Added in version 18)
Delete an existing timerec DVR entry from the database.
Request message fields:
Reply message fields:
(Added in version 5)
Get a ticket to allow access to a channel or recording via HTTP
Request message fields:
Reply message fields:
Request subscription to the given channel.
Request message fields:
Reply message fields:
Stop a subscription.
Request message fields:
Reply message fields:
(Added in version 5)
Change the weight of an existing subscription
Request message fields:
Reply message fields:
(Added in version 9)
Skip a timeshift enabled subscription. The response will be asynchronous subscriptionSkip().
Request message fields:
Reply message fields:
(Added in version 9)
Synonym for subscriptionSkip
(Added in version 9)
Set the playback speed for the subscription. The response will be asynchronous subscriptionSpeed().
Request message fields:
Reply message fields:
(Added in version 9)
Return a timeshifted session to live. Reply will be asynchronous subscriptionSkip().
Request message fields:
Reply message fields:
(Added in version 12)
Enable or disable specified streams by index.
Request message fields:
Reply message fields:
(Added in version 16)
Return a list of stream profiles (configurations).
Reply message fields:
Message fields:
(Added in version 11, Removed in version 16)
Return a list of encoders (codecs).
Reply message fields:
(Added in version 8)
Open a file within the Tvheadend file system. This is now the preferred method (in place of HTTP) for accessing recordings.
Accessing recordings via HTSP will overcome the limitations of standard HTTP streaming which cannot handle both skipping and growing files (i.e. in-progress recordings) at the same time.
Request message fields:
Valid file paths:
Reply message fields:
(Added in version 8)
Read data from a file.
Request message fields:
Reply message fields:
(Added in version 8)
Close an opened file.
Request message fields:
Reply message fields:
(Added in version 8)
Get status of a file.
Request message fields:
Reply message fields:
(Added in version 8)
Seek to position in a file.
Request message fields:
Note: valid values for whence
Reply message fields:
Also see: and .
Also see: .
Also see:
Also see:
Also see:
Map
1
Sub message of type map
S64
2
Signed 64bit integer
Str
3
UTF-8 encoded string
Bin
4
Binary blob
List
5
Sub message of type list
Dbl
6
Double precision floating point
Bool
7
Boolean
UUID
8
64 bit UUID in binary format
Length
4 byte integer
Total length of message (not including this length field itself)
Body
HTSMSG-Field * N
Fields in the root body
Type
1 byte integer
Type of field (see field type IDs above)
Namelength
1 byte integer
Length of name of field. If a field is part of a list message this must be 0
Datalength
4 byte integer
Length of field data
Name
N bytes
Field name, length as specified by Namelength
Data
N bytes
Field payload, for details see below