Htsp » History » Version 31
Andreas Smas, 2009-03-03 22:59
1 | 17 | Andreas Smas | = Home Tv Streaming Protocol (HTSP) = |
---|---|---|---|
2 | 1 | Andreas Smas | |
3 | 17 | Andreas Smas | == General == |
4 | 1 | Andreas Smas | |
5 | 17 | Andreas Smas | 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. |
6 | 1 | Andreas Smas | |
7 | 17 | Andreas Smas | The transmission and reception of a channel over HTSP is referred to a subscription. A single HTSP session can handle as many concurrent subscriptions as the bandwidth and CPU permits. |
8 | 1 | Andreas Smas | |
9 | |||
10 | 17 | Andreas Smas | 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 is suitable for long-distance transmissions and/or paths with non-perfect delivery. |
11 | (It has been tested with a server in Stockholm and the client in Berlin). |
||
12 | |||
13 | 27 | Andreas Smas | The HTS Showtime client can be found [http://trac.lonelycoder.com/hts/browser/trunk/showtime/tv/htsp.c here]. |
14 | 22 | Andreas Smas | |
15 | 18 | Andreas Smas | ---- |
16 | 17 | Andreas Smas | == Communication == |
17 | |||
18 | 23 | Andreas Smas | This communication is currently implemented by using htsmsg:s. All strings are encoded as UTF-8. |
19 | |||
20 | 17 | Andreas Smas | There are two distinct ways for communication within HTSP. |
21 | |||
22 | 28 | Andreas Smas | Apart from this there is a number of messages that needs to be exchanged during login, see the login section below. |
23 | |||
24 | 17 | Andreas Smas | === RPC communication === |
25 | 1 | Andreas Smas | |
26 | 18 | Andreas Smas | 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: |
27 | |||
28 | RPC request extra fields: |
||
29 | 17 | Andreas Smas | {{{ |
30 | 1 | Andreas Smas | seq int optional Sequence number. This field will be echoed back by the server in the reply. |
31 | 28 | Andreas Smas | username str optional Username, in combination with 'digest' this can be used to raise the privileges |
32 | for the session in combination with invocation of a method. |
||
33 | digest bin optional Used to raise privileges. |
||
34 | 1 | Andreas Smas | }}} |
35 | 28 | Andreas Smas | |
36 | The followings field should be used by the client to match the reply with the request. |
||
37 | 18 | Andreas Smas | All replies are guaranteed to arrive in the same order as the requests. |
38 | Even so, probably the best way to implement the request-reply client is by taking advantage of the 'seq' field. |
||
39 | 1 | Andreas Smas | |
40 | 18 | Andreas Smas | RPC reply extra fields: |
41 | {{{ |
||
42 | 19 | Andreas Smas | seq int optional Sequence number. Same as in the request. |
43 | error str optional If present an error has occurred and the text describes the error. |
||
44 | 18 | Andreas Smas | noaccess int optional If present and set to '1' the user is prohibited from invoking the method due to |
45 | 19 | Andreas Smas | access restrictions. |
46 | 18 | Andreas Smas | }}} |
47 | 1 | Andreas Smas | |
48 | 18 | Andreas Smas | === Streaming communication === |
49 | 19 | Andreas Smas | |
50 | 1 | Andreas Smas | For streaming of live TV and various related messages the server will continuously push data to the client. |
51 | These messages are referred to as asynchronous messages and always have the 'method' field set and never have the 'seq' field set. |
||
52 | 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). |
||
53 | |||
54 | 28 | Andreas Smas | === Login === |
55 | 1 | Andreas Smas | |
56 | 28 | Andreas Smas | Upon connect the server sends a welcome message looking like this: |
57 | 1 | Andreas Smas | |
58 | 19 | Andreas Smas | {{{ |
59 | 28 | Andreas Smas | method str required Contains 'welcome' |
60 | htspversion int required The server supports all versions of the protocol up to and including this number. |
||
61 | servername str required Server software name. |
||
62 | serverversion str required Server software version. |
||
63 | challenge bin required 32 bit randomized data used to generate authentication digests |
||
64 | }}} |
||
65 | 19 | Andreas Smas | |
66 | 28 | Andreas Smas | The client is then expected to reply with: |
67 | 19 | Andreas Smas | |
68 | 1 | Andreas Smas | {{{ |
69 | 28 | Andreas Smas | method str required Contains 'login' |
70 | htspversion int required HTSP protocol version the client wish to use. |
||
71 | username str optional Login username. If omitted the login is considered anonymous. |
||
72 | 29 | Andreas Smas | digest bin optional SHA-1 hash of [password (not including terminating NUL)] + [challenge from welcome message] |
73 | 19 | Andreas Smas | }}} |
74 | 1 | Andreas Smas | |
75 | The server will in turn reply with: |
||
76 | |||
77 | 19 | Andreas Smas | {{{ |
78 | 1 | Andreas Smas | method str required Contains 'loginAck' |
79 | 29 | Andreas Smas | noaccess int optional The initial credentials did not grant access to any methods. |
80 | If the client employs 'on-demand authentication' it will chose to ignore this. |
||
81 | error str optional If set, an error occurred during login. The connection will be terminated by the server. |
||
82 | 1 | Andreas Smas | }}} |
83 | |||
84 | After this procedure normal communication may take place. |
||
85 | |||
86 | 29 | Andreas Smas | === Authentication === |
87 | 1 | Andreas Smas | |
88 | 29 | Andreas Smas | In Tvheadend, each method has an associated access restriction. Currently there is only on restriction (Streaming). However, this may change in the future. |
89 | 7 | Andreas Smas | |
90 | 29 | Andreas Smas | Privileges for these restrictions may be granted in two ways: Username + Password and/or Source IP address. |
91 | Therefore it is possible to gain permissions to the system without entering a username and password. |
||
92 | While this is really useful it also complicates the authentication schema a bit. |
||
93 | Upon connect the initial privileges will be raised based on the source address. |
||
94 | 7 | Andreas Smas | |
95 | 29 | Andreas Smas | In principle it's possible to use two different authentication idioms with HTSP. |
96 | Depending on how your application works one or another may be more suitable. |
||
97 | 31 | Andreas Smas | While they do not really differ from a protocol point of view it's worth mentioning a bit about them here: |
98 | 1 | Andreas Smas | |
99 | 31 | Andreas Smas | === Initial login authentication === |
100 | 26 | Andreas Smas | |
101 | 29 | Andreas Smas | The client performs all of its authentication using the 'login' method. |
102 | 26 | Andreas Smas | |
103 | 1 | Andreas Smas | It may choose to send: |
104 | 30 | Andreas Smas | * Username and password: Privileges will be raised based on these credentials. |
105 | * Username only: Privileges will be based on just the source address. The username will be used for various logging purposes. |
||
106 | * Nothing: Privileges will be based on just the source address. |
||
107 | 1 | Andreas Smas | |
108 | 30 | Andreas Smas | If no privileges are granted after the login message has been received by the server (i.e. both network and username + password based) |
109 | the server will reply with 'noaccess' set to 1. A client that only employs initial login should honor this flag and ask the |
||
110 | user for a username + password and reconnect. |
||
111 | 1 | Andreas Smas | |
112 | 30 | Andreas Smas | === On-demand authentication === |
113 | 1 | Andreas Smas | |
114 | 30 | Andreas Smas | The client performs all of its authentication when it needs to. |
115 | 1 | Andreas Smas | |
116 | 30 | Andreas Smas | When using this method, the client will check every RPC reply for the 'noaccess' field. |
117 | If it set to 1 it whould ask the user for username + password and retry the request but also |
||
118 | add 'username' and 'digest' to the original message. (See ''RPC request extra fields'' above) |
||
119 | 10 | Andreas Smas | |
120 | 30 | Andreas Smas | Typically it would not send a username or digest during login. |
121 | 29 | Andreas Smas | |
122 | ---- |
||
123 | 18 | Andreas Smas | = Client to Server (RPC) methods = |
124 | 10 | Andreas Smas | |
125 | ---- |
||
126 | === enableAsyncMetadata === |
||
127 | |||
128 | When this is enabled the client will get continuous updates from the server about channels and tags. |
||
129 | This also includes creation and deletion of channels and tags. |
||
130 | |||
131 | An interactive application that presents the user with information about channels and tags would probably want to switch to this mode. |
||
132 | |||
133 | |||
134 | Request message fields: |
||
135 | {{{ |
||
136 | None |
||
137 | }}} |
||
138 | |||
139 | 1 | Andreas Smas | Reply message fields: |
140 | 5 | Andreas Smas | {{{ |
141 | 1 | Andreas Smas | None |
142 | 6 | Andreas Smas | }}} |
143 | 23 | Andreas Smas | |
144 | |||
145 | |||
146 | ---- |
||
147 | === getEvent === |
||
148 | |||
149 | Request information about the given event. An event typically corresponds to a program on a channel. |
||
150 | |||
151 | Request message fields: |
||
152 | {{{ |
||
153 | eventId int required Event ID. |
||
154 | }}} |
||
155 | |||
156 | Reply message fields: |
||
157 | {{{ |
||
158 | start int required Start time of event (Seconds since the epoch, in UTC) |
||
159 | 6 | Andreas Smas | stop int required Ending time of event (Seconds since the epoch, in UTC) |
160 | 1 | Andreas Smas | title str required Title of event. |
161 | 6 | Andreas Smas | description str required Description of event. This can be quite huge and may also contain newlines. |
162 | nextEventId int optional ID of next event on the same channel. |
||
163 | 25 | Andreas Smas | }}} |
164 | 1 | Andreas Smas | |
165 | ---- |
||
166 | 8 | Andreas Smas | === subscribe === |
167 | |||
168 | Request subscription to the given channel. |
||
169 | 1 | Andreas Smas | |
170 | 6 | Andreas Smas | Request message fields: |
171 | {{{ |
||
172 | channelId int required ID for channel. |
||
173 | subscriptionId int required Subscription ID. Selected by client. This value is not interpreted by the server in any form. |
||
174 | 4 | Andreas Smas | The value is used from now on in all messages related to the subscription. |
175 | 6 | Andreas Smas | }}} |
176 | 5 | Andreas Smas | |
177 | 1 | Andreas Smas | Reply message fields: |
178 | 5 | Andreas Smas | {{{ |
179 | 1 | Andreas Smas | None. |
180 | 5 | Andreas Smas | }}} |
181 | |||
182 | 1 | Andreas Smas | |
183 | ---- |
||
184 | 6 | Andreas Smas | === unsubscribe === |
185 | |||
186 | Stop a subscription. |
||
187 | Attributes |
||
188 | 2 | Andreas Smas | {{{ |
189 | subscriptionId int required Subscription ID. |
||
190 | }}} |
||
191 | |||
192 | Reply message fields: |
||
193 | {{{ |
||
194 | 12 | Andreas Smas | None. |
195 | 2 | Andreas Smas | }}} |
196 | 1 | Andreas Smas | |
197 | 11 | Andreas Smas | |
198 | ---- |
||
199 | |||
200 | = Server to Client methods = |
||
201 | |||
202 | ---- |
||
203 | === channelAdd === |
||
204 | |||
205 | 13 | Andreas Smas | A new channel has been created on the server. |
206 | 11 | Andreas Smas | |
207 | Message fields: |
||
208 | 12 | Andreas Smas | {{{ |
209 | 1 | Andreas Smas | channelId int required ID of channel. |
210 | channelName str required Name of channel. |
||
211 | 11 | Andreas Smas | channelIcon str required URL to an icon representative for the channel. |
212 | eventId int optional ID of the current (or next to be) event on this channel. |
||
213 | 1 | Andreas Smas | tags int[] optional Tags this channel is mapped to. |
214 | 11 | Andreas Smas | }}} |
215 | |||
216 | ---- |
||
217 | === channelUpdate === |
||
218 | |||
219 | A channel has been updated on the server. All fields will be sent even if they are not changed. Most clients can process this and the 'channelAdd' message |
||
220 | with the very same code. |
||
221 | |||
222 | 13 | Andreas Smas | Message fields: |
223 | 12 | Andreas Smas | {{{ |
224 | 3 | Andreas Smas | channelId int required ID of channel. |
225 | 1 | Andreas Smas | channelName str required Name of channel. |
226 | 11 | Andreas Smas | channelIcon str optioanl URL to an icon representative for the channel. |
227 | 1 | Andreas Smas | eventId int optional ID of the current (or next to be) event on this channel. |
228 | 11 | Andreas Smas | tags int[] required Tags this channel is mapped to. |
229 | }}} |
||
230 | |||
231 | ---- |
||
232 | === channelDelete === |
||
233 | |||
234 | A channel has been deleted on the server. |
||
235 | 12 | Andreas Smas | |
236 | 11 | Andreas Smas | This message is only sent if session is in asynchronous mode. |
237 | 1 | Andreas Smas | |
238 | 11 | Andreas Smas | Message fields: |
239 | {{{ |
||
240 | channelId int required ID of channel. |
||
241 | }}} |
||
242 | 13 | Andreas Smas | |
243 | 11 | Andreas Smas | ---- |
244 | === tagAdd === |
||
245 | |||
246 | A new tag has been created on the server. |
||
247 | |||
248 | 1 | Andreas Smas | Message fields: |
249 | 11 | Andreas Smas | {{{ |
250 | 1 | Andreas Smas | tagId int required ID of tag. |
251 | 11 | Andreas Smas | tagName str required Name of tag. |
252 | tagIcon str optional URL to an icon representative for the channel. |
||
253 | channels int[] required Channels this tag is mapped to. |
||
254 | }}} |
||
255 | 13 | Andreas Smas | |
256 | 11 | Andreas Smas | ---- |
257 | === tagUpdate === |
||
258 | |||
259 | A tag has been updated on the server. |
||
260 | |||
261 | 12 | Andreas Smas | Message fields: |
262 | 1 | Andreas Smas | {{{ |
263 | tagId int required ID of tag. |
||
264 | 11 | Andreas Smas | tagName str required Name of tag. |
265 | tagIcon str optional URL to an icon representative for the channel. |
||
266 | channels int[] required Channels this tag is mapped to. |
||
267 | 1 | Andreas Smas | }}} |
268 | 11 | Andreas Smas | |
269 | ---- |
||
270 | 1 | Andreas Smas | === tagDelete === |
271 | 11 | Andreas Smas | |
272 | A tag has been deleted from the server. |
||
273 | 12 | Andreas Smas | |
274 | 11 | Andreas Smas | Message fields: |
275 | 2 | Andreas Smas | {{{ |
276 | 14 | Andreas Smas | tagId str required ID of tag. |
277 | }}} |
||
278 | |||
279 | ---- |
||
280 | === subscriptionStart === |
||
281 | |||
282 | Message fields: |
||
283 | {{{ |
||
284 | subscriptionId int required Subscription ID. |
||
285 | streams msg[] required Array of messages with stream information |
||
286 | |||
287 | |||
288 | 'streams' message: |
||
289 | |||
290 | index int required Index for this stream |
||
291 | type str required Type of stream |
||
292 | language str optional Language for stream |
||
293 | |||
294 | |||
295 | 1 | Andreas Smas | Stream types: |
296 | 14 | Andreas Smas | AC3 AC3 audio |
297 | MPEG2AUDIO MPEG2 audio (MP2) |
||
298 | 21 | Andreas Smas | MPEG2VIDEO MPEG2 video |
299 | 12 | Andreas Smas | H264 H264 video |
300 | 2 | Andreas Smas | |
301 | |||
302 | 15 | Andreas Smas | }}} |
303 | |||
304 | |||
305 | ---- |
||
306 | === subscriptionStop === |
||
307 | |||
308 | 12 | Andreas Smas | Message fields: |
309 | 2 | Andreas Smas | {{{ |
310 | subscriptionId int required Subscription ID. |
||
311 | 15 | Andreas Smas | reason str optional Reason for subscription stop. |
312 | }}} |
||
313 | |||
314 | ---- |
||
315 | === subscriptionStatus === |
||
316 | |||
317 | Message fields: |
||
318 | 12 | Andreas Smas | {{{ |
319 | 2 | Andreas Smas | subscriptionId int required Subscription ID. |
320 | 15 | Andreas Smas | status str optional English clear text of status. Absence of this field means that the status is OK. |
321 | }}} |
||
322 | |||
323 | |||
324 | ---- |
||
325 | === queueStatus === |
||
326 | |||
327 | The queueStatus message is sent every second during normal data delivery. |
||
328 | |||
329 | The transmit scheduler have different drop thresholds for different frame types. |
||
330 | If congestion occurs it will favor dropping B-frames before P-frames before I-frames. |
||
331 | All audio is recognized as I-frames. |
||
332 | |||
333 | Message fields: |
||
334 | {{{ |
||
335 | subscriptionId int required Subscription ID. |
||
336 | packets int required Number of data packets in queue. |
||
337 | 16 | Andreas Smas | bytes int required Number of bytes in queue. |
338 | delay int required Estimated delay of queue (in µs) |
||
339 | Bdrops int required Number of B-frames dropped |
||
340 | Pdrops int required Number of P-frames dropped |
||
341 | Idrops int required Number of I-frames dropped |
||
342 | }}} |
||
343 | |||
344 | ---- |
||
345 | === muxpkt === |
||
346 | |||
347 | Streaming data. |
||
348 | |||
349 | Message fields: |
||
350 | {{{ |
||
351 | subscriptionId int required Subscription ID. |
||
352 | frametype int required Type of frame as ASCII value: 'I', 'P', 'B' |
||
353 | stream int required Stream index. Corresponds to the streams reported in the subscriptionStart message. |
||
354 | 1 | Andreas Smas | dts int required Decode Time Stamp in µs. |
355 | pts int required Presentation Time Stamp in µs. |
||
356 | duration int required Duration of frame in µs. |
||
357 | payload bin required Actual frame data. |
||
358 | |||
359 | }}} |