rbsrt 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md ADDED
@@ -0,0 +1,752 @@
1
+ # Ruby SRT API [WIP]
2
+
3
+ A ruby gem which you can use to build [SRT (Secure Reliable Transport)](https://github.com/Haivision/srt "Haivisionsrt") Servers and Clients.
4
+
5
+ > Secure Reliable Transport (SRT) is an open source transport technology that optimizes streaming performance across unpredictable networks, such as the Internet.
6
+ >
7
+ > From: Haivision
8
+
9
+ Ruby SRT is a Work in Progress, please [create an issue if you find any bugs, leaks, or would like to request additional API](https://github.com/spllr/rbsrt/issues).
10
+
11
+
12
+ ## Table Of Contents
13
+
14
+ - [Ruby SRT API [WIP]](#ruby-srt-api-wip)
15
+ - [Table Of Contents](#table-of-contents)
16
+ - [Installation](#installation)
17
+ - [Dependencies](#dependencies)
18
+ - [rbsrt gem](#rbsrt-gem)
19
+ - [Examples](#examples)
20
+ - [A Simple SRT Socket Server In File Mode](#a-simple-srt-socket-server-in-file-mode)
21
+ - [A Simple Socket Client In File Mode](#a-simple-socket-client-in-file-mode)
22
+ - [A Simple SRT Socket Server In Live Mode](#a-simple-srt-socket-server-in-live-mode)
23
+ - [A Simple Socket Client In Live Mode](#a-simple-socket-client-in-live-mode)
24
+ - [A Simple Recording Server](#a-simple-recording-server)
25
+ - [A Simple ffmpeg Sending Client](#a-simple-ffmpeg-sending-client)
26
+ - [API](#api)
27
+ - [`SRT` Module](#srt-module)
28
+ - [`SRT::Socket` Class](#srtsocket-class)
29
+ - [`SRT::Server` Class](#srtserver-class)
30
+ - [`SRT::Connection` Class](#srtconnection-class)
31
+ - [`SRT::Client` Class](#srtclient-class)
32
+ - [`SRT::Poll` Class](#srtpoll-class)
33
+ - [`SRT::StreamIDComponents` Class](#srtstreamidcomponents-class)
34
+ - [`SRT::Stats` Class](#srtstats-class)
35
+ - [`SRT::Error` Classes](#srterror-classes)
36
+ - [License](#license)
37
+
38
+ ## Installation
39
+
40
+ Currently rbsrt must be build with llvm/clang. This will change in the future.
41
+
42
+ The gem requires Ruby 2.2 or higher.
43
+
44
+
45
+ ### Dependencies
46
+
47
+ You will need to install the SRT library. Visit the [SRT Github Repo](https://github.com/Haivision/srt "SRT On Github") for detailed installation instructions.
48
+
49
+ On macOs run you can run `brew install srt` to install.
50
+
51
+
52
+ ### rbsrt gem
53
+
54
+ Install with rubygems:
55
+
56
+ ```sh
57
+ gem install rbsrt
58
+ ```
59
+
60
+
61
+ Alternativly you can install the rbsrt Ruby gem from source.
62
+
63
+ Clone the git repo:
64
+
65
+ ```sh
66
+ git clone https://github.com/spllr/rbsrt.git
67
+ ```
68
+
69
+ Install:
70
+
71
+ ```
72
+ cd rbsrt
73
+ rake install
74
+ ```
75
+
76
+
77
+ ## Examples
78
+
79
+ ### A Simple SRT Socket Server In File Mode
80
+
81
+ ```ruby
82
+ server = SRT::Socket.new
83
+ server.transmission_mode = :file
84
+
85
+ puts "server state=#{server.state}, id=#{server.id}"
86
+
87
+ server.bind "127.0.0.1", "5556"
88
+
89
+ puts "server #{server.state}"
90
+
91
+ server.listen 3
92
+
93
+ puts "server #{server.state}"
94
+
95
+ client = server.accept
96
+
97
+ puts "server accepted: streamid=\"#{client.streamid}\", id=#{client.id}, tsbpdmode=#{client.tsbpdmode?}"
98
+
99
+ loop do
100
+ break unless client.connected?
101
+ break unless data = client.recvmsg
102
+ puts "server received: #{data}"
103
+ rescue SRT::Error::CONNLOST => e
104
+ puts "connection lost: #{e}"
105
+ break
106
+ rescue SRT::Error => e
107
+ puts "server error: #{e.class}"
108
+ end
109
+
110
+ puts "client closed #{client.closed?}"
111
+
112
+ server.close
113
+
114
+ puts "server done"
115
+ ```
116
+
117
+ ### A Simple Socket Client In File Mode
118
+
119
+ ```ruby
120
+ client = SRT::Socket.new
121
+
122
+ client.streamid = "a ruby srt socket"
123
+ client.transmission_mode = :file
124
+
125
+ client.connect "127.0.0.1", "5556"
126
+
127
+ 10.times do |i|
128
+ payload = "Hello from ruby client #{i}"
129
+ puts "will send: \"#{payload}\""
130
+ client.sendmsg "Hello from ruby client #{i}"
131
+ puts "did send: \"#{payload}\""
132
+ rescue SRT::Error => e
133
+ puts "client error: #{e}"
134
+ end
135
+
136
+ client.close
137
+ ```
138
+
139
+ ### A Simple SRT Socket Server In Live Mode
140
+
141
+ ```ruby
142
+ server = SRT::Socket.new
143
+ server.transmission_mode = :live
144
+
145
+ puts "server state=#{server.state}, id=#{server.id}"
146
+
147
+ server.bind "127.0.0.1", "5556"
148
+
149
+ puts "server #{server.state}"
150
+
151
+ server.listen 3
152
+
153
+ puts "server #{server.state}"
154
+
155
+ client = server.accept
156
+
157
+ puts "server accepted: streamid=\"#{client.streamid}\", id=#{client.id}, tsbpdmode=#{client.tsbpdmode?}"
158
+
159
+ loop do
160
+ break unless client.connected?
161
+ break unless data = client.recvmsg
162
+ puts "server received: #{data}"
163
+ rescue SRT::Error::CONNLOST => e
164
+ puts "connection lost: #{e}"
165
+ break
166
+ rescue SRT::Error => e
167
+ puts "server error: #{e.class}"
168
+ end
169
+
170
+ puts "client closed #{client.closed?}"
171
+
172
+ server.close
173
+
174
+ puts "server done"
175
+ ```
176
+
177
+ ### A Simple Socket Client In Live Mode
178
+
179
+ ```ruby
180
+ client = SRT::Socket.new
181
+
182
+ client.streamid = "a ruby srt socket"
183
+ client.transmission_mode = :live
184
+
185
+ client.connect "127.0.0.1", "5556"
186
+
187
+ 100.times do |i|
188
+ payload = "Hello from ruby client #{i}"
189
+ client.sendmsg "Hello from ruby client #{i}"
190
+ sleep 1 / 30 # mimic framerate
191
+ rescue SRT::Error => e
192
+ puts "client error: #{e}"
193
+ end
194
+
195
+ client.close
196
+ ```
197
+
198
+ ### A Simple Recording Server
199
+
200
+ This example shows how a naive recorder server can be build.
201
+
202
+ The server will accept incomming SRT connections and will write whatever comes in to a file on disk.
203
+
204
+ ```ruby
205
+ require 'rbsrt'
206
+
207
+ server = SRT::Server.new "0.0.0.0", "5555"
208
+
209
+ server.start do |connection|
210
+
211
+ streaminfo = SRT::StreamIDComponents.new connection.streamid
212
+
213
+ puts "new connection: streamid=#{streaminfo.resource_name}, connections=#{connection_count}, id=#{connection.id}"
214
+
215
+ # only handle publishing clients
216
+ return false unless streaminfo.mode == :publish
217
+
218
+ output_file = File.new "recording-#{Process.pid}-#{connection.id}", "w+"
219
+ output_file.close_on_exec = true
220
+
221
+ connection.at_data do |chunk|
222
+ puts "received data"
223
+ output_file.write(chunk)
224
+ end
225
+
226
+ connection.at_close do
227
+ puts "closed connection"
228
+ output_file.close
229
+ end
230
+ end
231
+ ```
232
+
233
+
234
+ ### A Simple ffmpeg Sending Client
235
+
236
+ ```ruby
237
+ require 'rbsrt'
238
+ require 'uri'
239
+
240
+ puts "create srt client"
241
+
242
+ client = SRT::Client.new
243
+
244
+ streaminfo = SRT::StreamIDComponents.new :mode => :publish,
245
+ :type => :stream,
246
+ :resource_name => "my_movie.ts"
247
+
248
+ client.streamid = streaminfo.to_s
249
+
250
+ at_exit { client.close }
251
+
252
+ begin
253
+ client.connect "127.0.0.1", "5555"
254
+ rescue SRT::Error => e
255
+ puts "A STR Error occurred. #{e.message}"
256
+ exit 1
257
+ rescue StandardError => e
258
+ puts "Something went wrong: #{e.message}"
259
+ exit 1
260
+ end
261
+
262
+ # run a ffmpeg command and write stdout to the client
263
+ require 'open3'
264
+
265
+ cmd = "ffmpeg -re -stream_loop 10 -i my_movie.ts -codec copy -f mpegts -"
266
+
267
+ Open3.popen3(cmd) do |stdin, stdout, stderr, wait_thr|
268
+ stdout.each do |buf|
269
+ client.sendmsg buf
270
+ end
271
+ end
272
+ ```
273
+
274
+ ## API
275
+
276
+ Also see the [Haivision SRT docs](https://github.com/Haivision/srt/tree/master/docs "Haivision SRT docs"), specificly the [API-functions](https://github.com/Haivision/srt/blob/master/docs/API-functions.md) and [API](https://github.com/Haivision/srt/blob/master/docs/API.md) documents, for more information about SRT, it's API and underlaying concepts.
277
+
278
+ The Ruby SRT gem comes with the following items:
279
+
280
+
281
+ | Item | Kind | Description |
282
+ |-------|------|-------------|
283
+ | `SRT` | Module | The root module |
284
+ | `SRT::Socket` | Class | A general purpose SRT Socket |
285
+ | `SRT::Server` | Class | A multi-client SRT Server |
286
+ | `SRT::Connection` | Class | Used by SRT::Server to represent a client |
287
+ | `SRT::Client` | Class | A SRT Client |
288
+ | `SRT::Stats` | Class | Used to obtain statistics from a socket |
289
+ | `SRT::StreamIDComponents` | Class | SRT Access Control complient streamid parser and compiler |
290
+ | `SRT::Error` | Class | The base class for a number of SRT specific errors |
291
+
292
+
293
+ ### `SRT` Module
294
+
295
+ The `SRT` module has the following constants:
296
+
297
+ | Name | Kind | Description |
298
+ |------|------|-------------|
299
+ | VERSION | String | Gem version string |
300
+ | SRT_VERSION | String | The version of the linked libsrt |
301
+
302
+
303
+ ### `SRT::Socket` Class
304
+
305
+ The `SRT::Socket` class is a general purpose SRT socket. It can be used to create both servers and clients.
306
+
307
+ The `SRT::Socket` supports the following methods:
308
+
309
+ | Name | Kind | Description |
310
+ |------|------|-------------|
311
+ | #accept | `SRT::Socket` | Accept a new connection |
312
+ | #bind(address, port) | | Bind the socket to an address and port |
313
+ | #broken? | Bool | True when the socket state is `:broken` |
314
+ | #close | | Closes the socket |
315
+ | #closed? | Bool | True the when the socket state is `:closed` |
316
+ | #closing? | Bool | True the when the socket state is `:closing` |
317
+ | #connect(address, port) | | Opens a connection to a server at `srt://#{address}:#{port}` |
318
+ | #connected? | Bool | True the when the socket state is `:conneted` |
319
+ | #connecting? | Bool | True the when the socket state is `:connecting` |
320
+ | #id | Any | An identifier for the socket. This identifier will be unique for all sockets existing at any one time but might not be unique over the lifetime of a script |
321
+ | #listen(maxbacklog) | | Start listening. Must be called after `#bind` |
322
+ | #listening? | Bool | True the when the socket state is `:listening` |
323
+ | #nonexist? | Bool | True the when the socket state is `:nonexist` |
324
+ | #opened? | Bool | True the when the socket state is `:opened` |
325
+ | #rcvsyn= | Bool | Alias for `#read_sync` |
326
+ | #rcvsyn? | Bool | Alias for `#read_sync?` |
327
+ | #read | String | Alias for `#recvmsg` |
328
+ | #read_sync= | Bool | When true, set the socket to read in a non-blocking manner |
329
+ | #read_sync? | Bool | True when the socket is readable in a non-blocking manner |
330
+ | #ready? | Bool | True when the socket is ready for usage (e.g. initialized) |
331
+ | #recvmsg | String | Read data from the socket |
332
+ | #sendmsg(string) | String | Send bytes to the socket |
333
+ | #sndsyn= | Bool | Alias of `#write_sync=` |
334
+ | #sndsyn? | Bool | Alias of `#write_sync?` |
335
+ | #state | Symbol | Returns the state of the socket. Can be one of: `:broken`, `:closed`, `:closing`, `:connected`, `:connecting`, `:listening`, `:nonexist`, `:opened`, `:ready` |
336
+ | #streamid | String | The streamid of the socket if supplied |
337
+ | #streamid= | String | The streamid of the socket, must be 512 characters or less |
338
+ | #timestamp_based_packet_delivery_mode= | Bool | Indicates if the sending socket will control the timed delivery of data (e.g. video stream) |
339
+ | #timestamp_based_packet_delivery_mode? | Bool | True if the sending socket controls the timing of data delivery |
340
+ | #trans_mode= | Symbol | Alias for `#transmission_mode=` |
341
+ | #transmission_mode= | Symbol | Controls how the socket expects data transmission. Can be set to `:live` or `:file` |
342
+ | #transtype= | Symbol | Alias for `#transmission_mode=` |
343
+ | #tsbpdmode= | Bool | Alias of `#timestamp_based_packet_delivery_mode=` |
344
+ | #tsbpdmode? | Bool | Alias of `#timestamp_based_packet_delivery_mode?` |
345
+ | #write | String | Alias of `#sendmsg` |
346
+ | #write_sync= | Any | When true, set the socket to write in a non-blocking manner |
347
+ | #write_sync? | Any | True when the socket is writable in a non-blocking manner |
348
+
349
+
350
+ ### `SRT::Server` Class
351
+
352
+ The `SRT::Server` class is an implementation of a multi-client SRT server. It does not inherit from `SRT::Socket` but has similar API where applicable.
353
+
354
+ The `SRT::Server` is a higher level abstraction freeing the developer of much of the boiletplate of building a server.
355
+
356
+ The `SRT::Server` will `yield` a new `SRT::Connection` instance when a new client connects.
357
+
358
+ The `SRT::Server` supports the following methods:
359
+
360
+ The constructor takes 2 aguments, an address and a port.Both must be strings.
361
+
362
+ | Name | Kind | Description |
363
+ |------|------|-------------|
364
+ | #broken? | Bool | True when the server socket state is `:broken` |
365
+ | #closed? | Bool | True the when the server socket state is `:closed` |
366
+ | #closing? | Bool | True the when the server socket state is `:closing` |
367
+ | #connected? | Bool | True the when the server socket state is `:conneted` |
368
+ | #connecting? | Bool | True the when the server socket state is `:connecting` |
369
+ | #listening? | Bool | True the when the server socket state is `:listening` |
370
+ | #nonexist? | Bool | True the when the server socket state is `:nonexist` |
371
+ | #opened? | Bool | True the when the server socket state is `:opened` |
372
+ | #rcvsyn? | Bool | Alias for `#read_sync?` |
373
+ | #read_sync? | Bool | True when the server socket is readable in a non-blocking manner |
374
+ | #ready? | Bool | True when the server socket is ready for usage (e.g. initialized) |
375
+ | #start(&blck) | Bool | Starts the servers. The block will be executed each time a new connection is accepted. Return a falsy value to reject the connection. The block will executed with the `self` set to the server |
376
+
377
+
378
+ ### `SRT::Connection` Class
379
+
380
+ The `SRT::Connection` class is used by the `SRT::Server`. You should not have to instantiate instances of this class yourself.
381
+
382
+ `SRT::Connection` does not inherit from `SRT::Socket` but has similar API where applicable.
383
+
384
+ Instances of `SRT::Connection` support the following methods:
385
+
386
+
387
+ | Name | Kind | Description |
388
+ |------|------|-------------|
389
+ | #at_close(&blck) | Block | A block which will be called when the connection closed |
390
+ | #at_data(&block) | Block | A block which will be called when new data was read |
391
+ | #broken? | Bool | True when the connection socket state is `:broken` |
392
+ | #closed? | Bool | True the when the connection socket state is `:closed` |
393
+ | #closing? | Bool | True the when the connection socket state is `:closing` |
394
+ | #connected? | Bool | True the when the connection socket state is `:conneted` |
395
+ | #connecting? | Bool | True the when the connection socket state is `:connecting` |
396
+ | #id | Any | An identifier for the connection. This identifier will be unique for all sockets existing at any one time but might not be unique over the lifetime of a script |
397
+ | #listening? | Bool | True the when the connection socket state is `:listening` |
398
+ | #nonexist? | Bool | True the when the connection socket state is `:nonexist` |
399
+ | #opened? | Bool | True the when the connection socket state is `:opened` |
400
+ | #ready? | Bool | True when the connection socket is ready for usage (e.g. initialized) |
401
+ | #sendmsg(string) | String | Send bytes to the socket |
402
+ | #sndsyn= | Bool | Alias of `#write_sync=` |
403
+ | #sndsyn? | Bool | Alias of `#write_sync?` |
404
+ | #state | Symbol | Returns the state of the socket. Can be one of: `:broken`, `:closed`, `:closing`, `:connected`, `:connecting`, `:listening`, `:nonexist`, `:opened`, `:ready` |
405
+ | #streamid | String | The streamid of the socket if supplied |
406
+ | #streamid= | String | The streamid of the socket, must be 512 characters or less |
407
+ | #timestamp_based_packet_delivery_mode= | Bool | Indicates if the sending socket will control the timed delivery of data (e.g. video stream) |
408
+ | #timestamp_based_packet_delivery_mode? | Bool | True if the sending socket controls the timing of data delivery |
409
+ | #trans_mode= | Symbol | Alias for `#transmission_mode=` |
410
+ | #transmission_mode= | Symbol | Controls how the socket expects data transmission. Can be set to `:live` or `:file` |
411
+ | #transtype= | Symbol | Alias for `#transmission_mode=` |
412
+ | #tsbpdmode= | Bool | Alias of `#timestamp_based_packet_delivery_mode=` |
413
+ | #tsbpdmode? | Bool | Alias of `#timestamp_based_packet_delivery_mode?` |
414
+ | #write | String | Alias of `#sendmsg` |
415
+ | #write_sync= | Any | When true, set the socket to write in a non-blocking manner |
416
+ | #write_sync? | Any | True when the socket is writable in a non-blocking manner |
417
+
418
+
419
+ ### `SRT::Client` Class
420
+
421
+ The `SRT::Client` can be used to connect to a SRT server.
422
+
423
+ Instances of `SRT::Client` support the following methods and attributes:
424
+
425
+ | Name | Kind | Description |
426
+ |------|------|-------------|
427
+ | #broken? | Bool | True when the socket state is `:broken` |
428
+ | #close | | Closes the socket |
429
+ | #closed? | Bool | True the when the socket state is `:closed` |
430
+ | #closing? | Bool | True the when the socket state is `:closing` |
431
+ | #connect(address, port) | | Opens a connection to a server at `srt://#{address}:#{port}` |
432
+ | #connected? | Bool | True the when the socket state is `:conneted` |
433
+ | #connecting? | Bool | True the when the socket state is `:connecting` |
434
+ | #id | Any | An identifier for the socket. This identifier will be unique for all sockets existing at any one time but might not be unique over the lifetime of a script |
435
+ | #listening? | Bool | True the when the socket state is `:listening` |
436
+ | #nonexist? | Bool | True the when the socket state is `:nonexist` |
437
+ | #opened? | Bool | True the when the socket state is `:opened` |
438
+ | #rcvsyn= | Bool | Alias for `#read_sync` |
439
+ | #rcvsyn? | Bool | Alias for `#read_sync?` |
440
+ | #read | String | Alias for `#recvmsg` |
441
+ | #read_sync= | Bool | When true, set the socket to read in a non-blocking manner |
442
+ | #read_sync? | Bool | True when the socket is readable in a non-blocking manner |
443
+ | #ready? | Bool | True when the socket is ready for usage (e.g. initialized) |
444
+ | #recvmsg | String | Read data from the socket |
445
+ | #sendmsg(string) | String | Send bytes to the socket |
446
+ | #sndsyn= | Bool | Alias of `#write_sync=` |
447
+ | #sndsyn? | Bool | Alias of `#write_sync?` |
448
+ | #state | Symbol | Returns the state of the socket. Can be one of: `:broken`, `:closed`, `:closing`, `:connected`, `:connecting`, `:listening`, `:nonexist`, `:opened`, `:ready` |
449
+ | #streamid | String | The streamid of the socket if supplied |
450
+ | #streamid= | String | The streamid of the socket, must be 512 characters or less |
451
+ | #timestamp_based_packet_delivery_mode= | Bool | Indicates if the sending socket will control the timed delivery of data (e.g. video stream) |
452
+ | #timestamp_based_packet_delivery_mode? | Bool | True if the sending socket controls the timing of data delivery |
453
+ | #trans_mode= | Symbol | Alias for `#transmission_mode=` |
454
+ | #transmission_mode= | Symbol | Controls how the socket expects data transmission. Can be set to `:live` or `:file` |
455
+ | #transtype= | Symbol | Alias for `#transmission_mode=` |
456
+ | #tsbpdmode= | Bool | Alias of `#timestamp_based_packet_delivery_mode=` |
457
+ | #tsbpdmode? | Bool | Alias of `#timestamp_based_packet_delivery_mode?` |
458
+ | #write | String | Alias of `#sendmsg` |
459
+ | #write_sync= | Any | When true, set the socket to write in a non-blocking manner |
460
+ | #write_sync? | Any | True when the socket is writable in a non-blocking manner |
461
+
462
+
463
+ ### `SRT::Poll` Class
464
+
465
+ The `SRT::Poll` class provides a way to handle multiple sockets simultaneously. It's function is similar to `IO.select`.
466
+
467
+ For example, you could have create a multi-client server using `SRT::Poll`:
468
+
469
+ ```ruby
470
+ require "rbsrt"
471
+
472
+ server = SRT::Socket.new
473
+
474
+ server = SRT::Socket.new
475
+ server.bind "0.0.0.0", "6789"
476
+ server.listen 3
477
+
478
+ poll = SRT::Poll.new
479
+
480
+ poll.add server, :in
481
+
482
+ loop do
483
+ poll.wait do |readable, writable, errors|
484
+ readable.each do |socket|
485
+ if socket == server
486
+ client = socket.accept # accept new client
487
+ poll.add client, :in, :out, :err # add client to the poll
488
+ puts "accepted client"
489
+ else
490
+ data = socket.recvmsg # read data from a client
491
+ puts "received data"
492
+ poll.remote socket unless data # remove client from the poll
493
+ end
494
+ end
495
+ end
496
+ end
497
+ ```
498
+
499
+ `SRT::Poll` supports the following actions:
500
+
501
+ | Name | Alias | Description |
502
+ |--|--|--|
503
+ | `:in` | `:read` | report readiness for reading or incoming connection on a listener socket |
504
+ | `:out` | `:write` | report readiness for writing or a successful connection |
505
+ | `:err` | `:error` | report errors on the socket |
506
+ | `:et` | `:edge` | the event will be edge-triggered. In the edge-triggered mode the function will only return socket states that have changed since the last call. |
507
+
508
+ Instances of `SRT::Poll` supports the following methods:
509
+
510
+ | Name | Kind | Description |
511
+ |------|------|-------------|
512
+ | `#add(sock, *flags)` | Bool | Add a socket to the Poll |
513
+ | `#remove(sock)` | Socket | Remove a socket from the Poll |
514
+ | `#update(sock, *flags)` | Update the flags for the socket |
515
+
516
+ For more info see the [Asynchronous Operations Epoll](https://github.com/Haivision/srt/blob/master/docs/API-functions.md#Asynchronous-operations-epoll "Asynchronous-operations-epoll") section in the SRT docs.
517
+
518
+ ### `SRT::StreamIDComponents` Class
519
+
520
+ SRT provides a [Access Control Guideline](https://github.com/Haivision/srt/blob/master/docs/AccessControl.md "SRT Access Control Guidelines") allowing a more fine grained method of specifying the intent of connection. Using the "#streamid" clients and servers can pack a number of properties on the socket.
521
+
522
+ The `SRT::StreamIDComponents` class can be used to parse and compile such an extended streamid string.
523
+
524
+ Instances of `SRT::StreamIDComponents` support the following methods and attributes:
525
+
526
+ | Name | Kind | Description |
527
+ |------|------|-------------|
528
+ | #host_name | String | The hostname associated with the socket |
529
+ | #host_name= | String | Set the host associated with the socket. When the host has a pathname, and no other `#resource_name` is specified, the path will will be used as the `#resource_name`. |
530
+ | #mode | Symbol | The mode associated with the socket. Can be one of: `:request`, `:publish`, `:bidirectional` |
531
+ | #mode= | Any | Set the mode associated with the socket. Can be one of: `:request`, `:publish`, `:bidirectional` |
532
+ | #resource_name | Any | The resource name associated with the socket. e.g. "stream1", "/movies/butterfly.ts", "movies.ts?gid=1234" |
533
+ | #resource_name= | Any | Set the resource name associated with the socket. |
534
+ | #sessionid | Any | A temporary resource identifier negotiated with the server, used just for verification. Useful when using a different authentication server to negotiate access to a resource. |
535
+ | #sessionid= | Any | Set the session id |
536
+ | #to_s | Any | Compiles the Access Control string |
537
+ | #type | Any | The type associated with the socket. Can be one of `:stream`, `:file`, `:auth` |
538
+ | #type= | Any | Set the type associated with the socket. Can be one of `:stream`, `:file`, `:auth` |
539
+ | #user_name | Any | The user name associated with the socket |
540
+ | #user_name= | Any | Set the user name associated with the socket |
541
+
542
+ You can set and get any non-standard property on the `SRT::StreamIDComponents` by simply calling it's getter or setter method:
543
+
544
+ ```ruby
545
+ streamid = SRT::StreamIDComponents.new
546
+
547
+ # standard
548
+
549
+ streamid.mode = :publish
550
+ streamid.type = :live
551
+ streamid.resource_name = "movie1.ts"
552
+
553
+ # non standard
554
+
555
+ streamid.my_property = "foo"
556
+ streamid.bar = "baz"
557
+
558
+ ```
559
+
560
+ You can use the `SRT::StreamIDComponents` to set and retrieve Access Control properties:
561
+
562
+ ```ruby
563
+ # ... on the client side ...
564
+
565
+ client = SRT::Client.new
566
+
567
+ streamid = SRT::StreamIDComponents.new
568
+ streamid.mode = :publish
569
+ streamid.type = :live
570
+ streamid.resource_name = "movie1.ts"
571
+
572
+ client.streamid = streamid.to_s
573
+
574
+ # ...
575
+
576
+
577
+ # ... on the server side ...
578
+
579
+ client = server.accept
580
+
581
+ streamid = SRT::StreamIDComponents.new client.streamid
582
+
583
+ if streamid.mode == :publish
584
+ # read from the client
585
+ elsif streamid.mode == :request
586
+ # write to the client
587
+ end
588
+
589
+ # ...
590
+ ```
591
+
592
+ You may also pass a hash to construct the `SRT::StreamIDComponents`:
593
+
594
+ ```ruby
595
+ streamid = SRT::StreamIDComponents.new :mode => :publish,
596
+ :type => :live,
597
+ :resource_name => "my_movie.ts",
598
+ :user_name => "admin",
599
+ :sessionid => "12345",
600
+ :host_name => "stream.recce.nl",
601
+ :some_custom_property => "somevalue"
602
+ ```
603
+
604
+ ### `SRT::Stats` Class
605
+
606
+ The `SRT::Stats` class can be used to pull statistics from a `SRT::Socket`.
607
+
608
+ ```ruby
609
+ stats = SRT::Stats.new my_socket_or_connection_or_server
610
+
611
+ puts stats.pkt_sent_total
612
+ ```
613
+
614
+ The initializer takes a srt socket like instance and an optional `:clear => true/false` flag.
615
+
616
+ See https://github.com/Haivision/srt/blob/master/docs/statistics.md for more information about all the field.
617
+
618
+
619
+ Instances of `SRT::Stats` have the following properties:
620
+
621
+
622
+ | Name | Alias | Description |
623
+ |-----|---|---|
624
+ | `#msTimeStamp` | `#ms_time_stamp`, `#mstimestamp` | time since the UDT entity is started, in milliseconds |
625
+ | `#pktSentTotal` | `#pkt_sent_total`, `#pktsenttotal` | total number of sent data packets, including retransmissions |
626
+ | `#pktRecvTotal` | `#pkt_recv_total`, `#pktrecvtotal` | total number of received packets |
627
+ | `#pktSndLossTotal` | `#pkt_snd_loss_total`, `#pktsndlosstotal` | total number of lost packets (sender side) |
628
+ | `#pktRcvLossTotal` | `#pkt_rcv_loss_total`, `#pktrcvlosstotal` | total number of lost packets (receiver side) |
629
+ | `#pktRetransTotal` | `#pkt_retrans_total`, `#pktretranstotal` | total number of retransmitted packets |
630
+ | `#pktSentACKTotal` | `#pkt_sent_ack_total`, `#pktsentacktotal` | total number of sent ACK packets |
631
+ | `#pktRecvACKTotal` | `#pkt_recv_ack_total`, `#pktrecvacktotal` | total number of received ACK packets |
632
+ | `#pktSentNAKTotal` | `#pkt_sent_nak_total`, `#pktsentnaktotal` | total number of sent NAK packets |
633
+ | `#pktRecvNAKTotal` | `#pkt_recv_nak_total`, `#pktrecvnaktotal` | total number of received NAK packets |
634
+ | `#usSndDurationTotal` | `#us_snd_duration_total`, `#ussnddurationtotal` | total time duration when UDT is sending data (idle time exclusive) |
635
+ | `#pktSndDropTotal` | `#pkt_snd_drop_total`, `#pktsnddroptotal` | number of too-late-to-send dropped packets |
636
+ | `#pktRcvDropTotal` | `#pkt_rcv_drop_total`, `#pktrcvdroptotal` | number of too-late-to play missing packets |
637
+ | `#pktRcvUndecryptTotal` | `#pkt_rcv_undecrypt_total`, `#pktrcvundecrypttotal` | number of undecrypted packets |
638
+ | `#pktSndFilterExtraTotal` | `#pkt_snd_filter_extra_total`, `#pktsndfilterextratotal` | number of control packets supplied by packet filter |
639
+ | `#pktRcvFilterExtraTotal` | `#pkt_rcv_filter_extra_total`, `#pktrcvfilterextratotal` | number of control packets received and not supplied back |
640
+ | `#pktRcvFilterSupplyTotal` | `#pkt_rcv_filter_supply_total`, `#pktrcvfiltersupplytotal` | number of packets that the filter supplied extra (e.g. FEC rebuilt) |
641
+ | `#pktRcvFilterLossTotal` | `#pkt_rcv_filter_loss_total`, `#pktrcvfilterlosstotal` | number of packet loss not coverable by filter |
642
+ | `#byteSentTotal` | `#byte_sent_total`, `#bytesenttotal` | total number of sent data bytes, including retransmissions |
643
+ | `#byteRecvTotal` | `#byte_recv_total`, `#byterecvtotal` | total number of received bytes |
644
+ | `#byteRcvLossTotal` | `#byte_rcv_loss_total`, `#bytercvlosstotal` | total number of lost bytes SRT_ENABLE_LOSTBYTESCOUNT |
645
+ | `#byteRetransTotal` | `#byte_retrans_total`, `#byteretranstotal` | total number of retransmitted bytes |
646
+ | `#byteSndDropTotal` | `#byte_snd_drop_total`, `#bytesnddroptotal` | number of too-late-to-send dropped bytes |
647
+ | `#byteRcvDropTotal` | `#byte_rcv_drop_total`, `#bytercvdroptotal` | number of too-late-to play missing bytes (estimate based on average packet size) |
648
+ | `#byteRcvUndecryptTotal` | `#byte_rcv_undecrypt_total`, `#bytercvundecrypttotal` | number of undecrypted bytes |
649
+ | `#pktSent` | `#pkt_sent`, `#pktsent` | number of sent data packets, including retransmissions |
650
+ | `#pktRecv` | `#pkt_recv`, `#pktrecv` | number of received packets |
651
+ | `#pktSndLoss` | `#pkt_snd_loss`, `#pktsndloss` | number of lost packets (sender side) |
652
+ | `#pktRcvLoss` | `#pkt_rcv_loss`, `#pktrcvloss` | number of lost packets (receiver side) |
653
+ | `#pktRetrans` | `#pkt_retrans`, `#pktretrans` | number of retransmitted packets |
654
+ | `#pktRcvRetrans` | `#pkt_rcv_retrans`, `#pktrcvretrans` | number of retransmitted packets received |
655
+ | `#pktSentACK` | `#pkt_sent_ack`, `#pktsentack` | number of sent ACK packets |
656
+ | `#pktRecvACK` | `#pkt_recv_ack`, `#pktrecvack` | number of received ACK packets |
657
+ | `#pktSentNAK` | `#pkt_sent_nak`, `#pktsentnak` | number of sent NAK packets |
658
+ | `#pktRecvNAK` | `#pkt_recv_nak`, `#pktrecvnak` | number of received NAK packets |
659
+ | `#pktSndFilterExtra` | `#pkt_snd_filter_extra`, `#pktsndfilterextra` | number of control packets supplied by packet filter |
660
+ | `#pktRcvFilterExtra` | `#pkt_rcv_filter_extra`, `#pktrcvfilterextra` | number of control packets received and not supplied back |
661
+ | `#pktRcvFilterSupply` | `#pkt_rcv_filter_supply`, `#pktrcvfiltersupply` | number of packets that the filter supplied extra (e.g. FEC rebuilt) |
662
+ | `#pktRcvFilterLoss` | `#pkt_rcv_filter_loss`, `#pktrcvfilterloss` | number of packet loss not coverable by filter |
663
+ | `#mbpsSRate` | `#mbps_s_rate`, `#mbpssrate` | sending rate in Mb/s |
664
+ | `#mbpsRecvRate` | `#mbps_recv_rate`, `#mbpsrecvrate` | receiving rate in Mb/s |
665
+ | `#usSndDuration` | `#us_snd_duration`, `#ussndduration` | busy sending time (i.e., idle time exclusive) |
666
+ | `#pktReorderDistance` | `#pkt_reorder_distance`, `#pktreorderdistance` | size of order discrepancy in received sequences |
667
+ | `#pktRcvAvgBelatedTime` | `#pkt_rcv_avg_belated_time`, `#pktrcvavgbelatedtime` | average time of packet delay for belated packets (packets with sequence past the ACK) |
668
+ | `#pktRcvBelated` | `#pkt_rcv_belated`, `#pktrcvbelated` | number of received AND IGNORED packets due to having come too late |
669
+ | `#pktSndDrop` | `#pkt_snd_drop`, `#pktsnddrop` | number of too-late-to-send dropped packets |
670
+ | `#pktRcvDrop` | `#pkt_rcv_drop`, `#pktrcvdrop` | number of too-late-to play missing packets |
671
+ | `#pktRcvUndecrypt` | `#pkt_rcv_undecrypt`, `#pktrcvundecrypt` | number of undecrypted packets |
672
+ | `#byteSent` | `#byte_sent`, `#bytesent` | number of sent data bytes, including retransmissions |
673
+ | `#byteRecv` | `#byte_recv`, `#byterecv` | number of received bytes |
674
+ | `#byteRcvLoss` | `#byte_rcv_loss`, `#bytercvloss` | number of retransmitted bytes SRT_ENABLE_LOSTBYTESCOUNT |
675
+ | `#byteRetrans` | `#byte_retrans`, `#byteretrans` | number of retransmitted bytes |
676
+ | `#byteSndDrop` | `#byte_snd_drop`, `#bytesnddrop` | number of too-late-to-send dropped bytes |
677
+ | `#byteRcvDrop` | `#byte_rcv_drop`, `#bytercvdrop` | number of too-late-to play missing bytes (estimate based on average packet size) |
678
+ | `#byteRcvUndecrypt` | `#byte_rcv_undecrypt`, `#bytercvundecrypt` | number of undecrypted bytes |
679
+ | `#usPktSndPeriod` | `#us_pkt_snd_period`, `#uspktsndperiod` | packet sending period, in microseconds |
680
+ | `#pktFlowWindow` | `#pkt_flow_window`, `#pktflowwindow` | flow window size, in number of packets |
681
+ | `#pktCongestionWindow` | `#pkt_congestion_window`, `#pktcongestionwindow` | congestion window size, in number of packets |
682
+ | `#pktFlightSize` | `#pkt_flight_size`, `#pktflightsize` | number of packets on flight |
683
+ | `#msRTT` | `#ms_rtt`, `#msrtt` | RTT, in milliseconds |
684
+ | `#mbpsBandwidth` | `#mbps_bandwidth`, `#mbpsbandwidth` | estimated bandwidth, in Mb/s |
685
+ | `#byteAvailSndBuf` | `#byte_avail_snd_buf`, `#byteavailsndbuf` | available UDT sender buffer size |
686
+ | `#byteAvailRcvBuf` | `#byte_avail_rcv_buf`, `#byteavailrcvbuf` | available UDT receiver buffer size |
687
+ | `#mbpsMaxBW` | `#mbps_max_bw`, `#mbpsmaxbw` | Transmit Bandwidth ceiling (Mbps) |
688
+ | `#byteMSS` | `#byte_mss`, `#bytemss` | MTU |
689
+ | `#pktSndBuf` | `#pkt_snd_buf`, `#pktsndbuf` | UnACKed packets in UDT sender |
690
+ | `#byteSndBuf` | `#byte_snd_buf`, `#bytesndbuf` | UnACKed bytes in UDT sender |
691
+ | `#msSndBuf` | `#ms_snd_buf`, `#mssndbuf` | UnACKed timespan (msec) of UDT sender |
692
+ | `#msSndTsbPdDelay` | `#ms_snd_tsb_pd_delay`, `#mssndtsbpddelay` | Timestamp-based Packet Delivery Delay |
693
+ | `#pktRcvBuf` | `#pkt_rcv_buf`, `#pktrcvbuf` | Undelivered packets in UDT receiver |
694
+ | `#byteRcvBuf` | `#byte_rcv_buf`, `#bytercvbuf` | Undelivered bytes of UDT receiver |
695
+ | `#msRcvBuf` | `#ms_rcv_buf`, `#msrcvbuf` | Undelivered timespan (msec) of UDT receiver |
696
+ | `#msRcvTsbPdDelay` | `#ms_rcv_tsb_pd_delay`, `#msrcvtsbpddelay` | Timestamp-based Packet Delivery Delay |
697
+
698
+
699
+ ### `SRT::Error` Classes
700
+
701
+ SRT specifies a number of error types which can occur. The gem defines an Error class for each one allowing the developer to `rescue` and handle specific errors.
702
+
703
+ If you want to catch _any_ SRT error, you can `rescue` `SRT::Error`, when you need more fine grained control (e.g. non block read and write no-data errors), `rescue` the appropriate error.
704
+
705
+ Each error has both a constant, and an instance variable defined with it's corresponding error code, these codes correspond with the SRT C API error codes (e.g. `SRT::Error::ASYNCRCV::Code`, `err.code`).
706
+
707
+ The gem supplies the following SRT specific errors:
708
+
709
+ | Error | Description |
710
+ |-------|-------------|
711
+ | SRT::Error | The base class of any SRT related error |
712
+ | SRT::Error::ASYNCFAIL | ... |
713
+ | SRT::Error::ASYNCRCV | A non-blocking socket did have data available. |
714
+ | SRT::Error::ASYNCSND | A non-blocking socket could not accept data. |
715
+ | SRT::Error::BOUNDSOCK | ... |
716
+ | SRT::Error::CONGEST | ... |
717
+ | SRT::Error::CONNFAIL | ... |
718
+ | SRT::Error::CONNLOST | ... |
719
+ | SRT::Error::CONNREJ | ... |
720
+ | SRT::Error::CONNSETUP | ... |
721
+ | SRT::Error::CONNSOCK | ... |
722
+ | SRT::Error::DUPLISTEN | ... |
723
+ | SRT::Error::FILE | ... |
724
+ | SRT::Error::INVALBUFFERAPI | ... |
725
+ | SRT::Error::INVALMSGAPI | ... |
726
+ | SRT::Error::INVOP | ... |
727
+ | SRT::Error::INVPARAM | ... |
728
+ | SRT::Error::INVPOLLID | ... |
729
+ | SRT::Error::INVRDOFF | ... |
730
+ | SRT::Error::INVSOCK | ... |
731
+ | SRT::Error::INVWROFF | ... |
732
+ | SRT::Error::LARGEMSG | ... |
733
+ | SRT::Error::NOBUF | ... |
734
+ | SRT::Error::NOCONN | ... |
735
+ | SRT::Error::NOLISTEN | ... |
736
+ | SRT::Error::NOSERVER | ... |
737
+ | SRT::Error::PEERERR | ... |
738
+ | SRT::Error::RDPERM | ... |
739
+ | SRT::Error::RDVNOSERV | ... |
740
+ | SRT::Error::RDVUNBOUND | ... |
741
+ | SRT::Error::RESOURCE | ... |
742
+ | SRT::Error::SECFAIL | ... |
743
+ | SRT::Error::SOCKFAIL | ... |
744
+ | SRT::Error::THREAD | ... |
745
+ | SRT::Error::TIMEOUT | ... |
746
+ | SRT::Error::UNBOUNDSOCK | ... |
747
+ | SRT::Error::UNKNOWN | ... |
748
+ | SRT::Error::WRPERM | ... |
749
+
750
+ ## License
751
+
752
+ All Ruby code is released under the MIT License. All C code is released under the Mozilla Public License, v. 2.0.