├── .gitignore
├── Cargo.lock
├── Cargo.toml
├── README.md
├── assets
├── banner.png
└── logo.png
├── crates
├── broadcast
│ ├── Cargo.lock
│ ├── Cargo.toml
│ ├── README.md
│ └── src
│ │ ├── lib.rs
│ │ ├── rtc
│ │ ├── codecs.rs
│ │ ├── mod.rs
│ │ ├── producers.rs
│ │ ├── routers.rs
│ │ └── workers.rs
│ │ └── signaling
│ │ ├── messages.rs
│ │ ├── mod.rs
│ │ └── websocket.rs
└── ftl
│ ├── Cargo.lock
│ ├── Cargo.toml
│ ├── README.md
│ └── src
│ ├── lib.rs
│ ├── protocol
│ ├── command.rs
│ ├── error.rs
│ ├── handshake.rs
│ ├── mod.rs
│ └── response.rs
│ ├── server.rs
│ └── util.rs
├── packages
├── docs
│ ├── .gitignore
│ ├── README.md
│ ├── babel.config.js
│ ├── docs
│ │ ├── components
│ │ │ ├── _category_.json
│ │ │ ├── broadcast.md
│ │ │ ├── ftl.md
│ │ │ └── javascript-lib.md
│ │ ├── ftl
│ │ │ ├── _category_.json
│ │ │ ├── establishing.md
│ │ │ ├── overview.md
│ │ │ ├── proposals.md
│ │ │ ├── protocol.md
│ │ │ └── security.md
│ │ └── intro.md
│ ├── docusaurus.config.js
│ ├── package.json
│ ├── sidebars.js
│ ├── src
│ │ ├── css
│ │ │ └── custom.css
│ │ └── theme
│ │ │ └── prism-include-languages.js
│ ├── static
│ │ ├── .nojekyll
│ │ ├── github-dark.min.css
│ │ ├── highlight.min.js
│ │ ├── img
│ │ │ ├── favicon.ico
│ │ │ ├── ftl_test.png
│ │ │ └── logo.png
│ │ └── inject.js
│ └── yarn.lock
├── hyperspeed.js
│ ├── .gitignore
│ ├── README.md
│ ├── package.json
│ ├── src
│ │ ├── client.ts
│ │ ├── index.ts
│ │ └── messages.ts
│ ├── tsconfig.json
│ └── yarn.lock
└── web-player
│ ├── .eslintrc
│ ├── .gitignore
│ ├── README.md
│ ├── next-env.d.ts
│ ├── next.config.js
│ ├── package.json
│ ├── pages
│ ├── _app.tsx
│ └── index.tsx
│ ├── styles
│ ├── Home.module.scss
│ └── globals.scss
│ ├── tsconfig.json
│ └── yarn.lock
└── src
└── main.rs
/.gitignore:
--------------------------------------------------------------------------------
1 | target/
2 |
--------------------------------------------------------------------------------
/Cargo.lock:
--------------------------------------------------------------------------------
1 | # This file is automatically @generated by Cargo.
2 | # It is not intended for manual editing.
3 | version = 3
4 |
5 | [[package]]
6 | name = "aho-corasick"
7 | version = "0.7.18"
8 | source = "registry+https://github.com/rust-lang/crates.io-index"
9 | checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
10 | dependencies = [
11 | "memchr",
12 | ]
13 |
14 | [[package]]
15 | name = "async-attributes"
16 | version = "1.1.2"
17 | source = "registry+https://github.com/rust-lang/crates.io-index"
18 | checksum = "a3203e79f4dd9bdda415ed03cf14dae5a2bf775c683a00f94e9cd1faf0f596e5"
19 | dependencies = [
20 | "quote",
21 | "syn",
22 | ]
23 |
24 | [[package]]
25 | name = "async-channel"
26 | version = "1.6.1"
27 | source = "registry+https://github.com/rust-lang/crates.io-index"
28 | checksum = "2114d64672151c0c5eaa5e131ec84a74f06e1e559830dabba01ca30605d66319"
29 | dependencies = [
30 | "concurrent-queue",
31 | "event-listener",
32 | "futures-core",
33 | ]
34 |
35 | [[package]]
36 | name = "async-executor"
37 | version = "1.4.1"
38 | source = "registry+https://github.com/rust-lang/crates.io-index"
39 | checksum = "871f9bb5e0a22eeb7e8cf16641feb87c9dc67032ccf8ff49e772eb9941d3a965"
40 | dependencies = [
41 | "async-task",
42 | "concurrent-queue",
43 | "fastrand",
44 | "futures-lite",
45 | "once_cell",
46 | "slab",
47 | ]
48 |
49 | [[package]]
50 | name = "async-global-executor"
51 | version = "2.0.2"
52 | source = "registry+https://github.com/rust-lang/crates.io-index"
53 | checksum = "9586ec52317f36de58453159d48351bc244bc24ced3effc1fce22f3d48664af6"
54 | dependencies = [
55 | "async-channel",
56 | "async-executor",
57 | "async-io",
58 | "async-mutex",
59 | "blocking",
60 | "futures-lite",
61 | "num_cpus",
62 | "once_cell",
63 | ]
64 |
65 | [[package]]
66 | name = "async-io"
67 | version = "1.6.0"
68 | source = "registry+https://github.com/rust-lang/crates.io-index"
69 | checksum = "a811e6a479f2439f0c04038796b5cfb3d2ad56c230e0f2d3f7b04d68cfee607b"
70 | dependencies = [
71 | "concurrent-queue",
72 | "futures-lite",
73 | "libc",
74 | "log",
75 | "once_cell",
76 | "parking",
77 | "polling",
78 | "slab",
79 | "socket2",
80 | "waker-fn",
81 | "winapi",
82 | ]
83 |
84 | [[package]]
85 | name = "async-lock"
86 | version = "2.4.0"
87 | source = "registry+https://github.com/rust-lang/crates.io-index"
88 | checksum = "e6a8ea61bf9947a1007c5cada31e647dbc77b103c679858150003ba697ea798b"
89 | dependencies = [
90 | "event-listener",
91 | ]
92 |
93 | [[package]]
94 | name = "async-mutex"
95 | version = "1.4.0"
96 | source = "registry+https://github.com/rust-lang/crates.io-index"
97 | checksum = "479db852db25d9dbf6204e6cb6253698f175c15726470f78af0d918e99d6156e"
98 | dependencies = [
99 | "event-listener",
100 | ]
101 |
102 | [[package]]
103 | name = "async-oneshot"
104 | version = "0.5.0"
105 | source = "registry+https://github.com/rust-lang/crates.io-index"
106 | checksum = "1ec7c75bcbcb0139e9177f30692fd617405ca4e0c27802e128d53171f7042e2c"
107 | dependencies = [
108 | "futures-micro",
109 | ]
110 |
111 | [[package]]
112 | name = "async-process"
113 | version = "1.3.0"
114 | source = "registry+https://github.com/rust-lang/crates.io-index"
115 | checksum = "83137067e3a2a6a06d67168e49e68a0957d215410473a740cea95a2425c0b7c6"
116 | dependencies = [
117 | "async-io",
118 | "blocking",
119 | "cfg-if",
120 | "event-listener",
121 | "futures-lite",
122 | "libc",
123 | "once_cell",
124 | "signal-hook",
125 | "winapi",
126 | ]
127 |
128 | [[package]]
129 | name = "async-std"
130 | version = "1.10.0"
131 | source = "registry+https://github.com/rust-lang/crates.io-index"
132 | checksum = "f8056f1455169ab86dd47b47391e4ab0cbd25410a70e9fe675544f49bafaf952"
133 | dependencies = [
134 | "async-attributes",
135 | "async-channel",
136 | "async-global-executor",
137 | "async-io",
138 | "async-lock",
139 | "async-process",
140 | "crossbeam-utils",
141 | "futures-channel",
142 | "futures-core",
143 | "futures-io",
144 | "futures-lite",
145 | "gloo-timers",
146 | "kv-log-macro",
147 | "log",
148 | "memchr",
149 | "num_cpus",
150 | "once_cell",
151 | "pin-project-lite",
152 | "pin-utils",
153 | "slab",
154 | "wasm-bindgen-futures",
155 | ]
156 |
157 | [[package]]
158 | name = "async-task"
159 | version = "4.1.0"
160 | source = "registry+https://github.com/rust-lang/crates.io-index"
161 | checksum = "677d306121baf53310a3fd342d88dc0824f6bbeace68347593658525565abee8"
162 |
163 | [[package]]
164 | name = "async-trait"
165 | version = "0.1.52"
166 | source = "registry+https://github.com/rust-lang/crates.io-index"
167 | checksum = "061a7acccaa286c011ddc30970520b98fa40e00c9d644633fb26b5fc63a265e3"
168 | dependencies = [
169 | "proc-macro2",
170 | "quote",
171 | "syn",
172 | ]
173 |
174 | [[package]]
175 | name = "async-tungstenite"
176 | version = "0.16.1"
177 | source = "registry+https://github.com/rust-lang/crates.io-index"
178 | checksum = "5682ea0913e5c20780fe5785abacb85a411e7437bf52a1bedb93ddb3972cb8dd"
179 | dependencies = [
180 | "async-std",
181 | "futures-io",
182 | "futures-util",
183 | "log",
184 | "pin-project-lite",
185 | "tungstenite",
186 | ]
187 |
188 | [[package]]
189 | name = "atomic-take"
190 | version = "1.0.0"
191 | source = "registry+https://github.com/rust-lang/crates.io-index"
192 | checksum = "f9f65e4fb35ff6a80b3298d1f028649f3a23da141fa3951e9b24dde1d515b67e"
193 |
194 | [[package]]
195 | name = "atomic-waker"
196 | version = "1.0.0"
197 | source = "registry+https://github.com/rust-lang/crates.io-index"
198 | checksum = "065374052e7df7ee4047b1160cca5e1467a12351a40b3da123c870ba0b8eda2a"
199 |
200 | [[package]]
201 | name = "atty"
202 | version = "0.2.14"
203 | source = "registry+https://github.com/rust-lang/crates.io-index"
204 | checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
205 | dependencies = [
206 | "hermit-abi",
207 | "libc",
208 | "winapi",
209 | ]
210 |
211 | [[package]]
212 | name = "autocfg"
213 | version = "1.0.1"
214 | source = "registry+https://github.com/rust-lang/crates.io-index"
215 | checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
216 |
217 | [[package]]
218 | name = "base64"
219 | version = "0.13.0"
220 | source = "registry+https://github.com/rust-lang/crates.io-index"
221 | checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
222 |
223 | [[package]]
224 | name = "bitflags"
225 | version = "1.3.2"
226 | source = "registry+https://github.com/rust-lang/crates.io-index"
227 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
228 |
229 | [[package]]
230 | name = "bitpattern"
231 | version = "0.1.0"
232 | source = "registry+https://github.com/rust-lang/crates.io-index"
233 | checksum = "3fc436c543b5fd522e5428d65c88e7bfb538ba267dad95cfb9d8fb8a465b0935"
234 | dependencies = [
235 | "paste",
236 | "proc-macro2",
237 | "quote",
238 | ]
239 |
240 | [[package]]
241 | name = "block-buffer"
242 | version = "0.9.0"
243 | source = "registry+https://github.com/rust-lang/crates.io-index"
244 | checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4"
245 | dependencies = [
246 | "generic-array",
247 | ]
248 |
249 | [[package]]
250 | name = "blocking"
251 | version = "1.1.0"
252 | source = "registry+https://github.com/rust-lang/crates.io-index"
253 | checksum = "046e47d4b2d391b1f6f8b407b1deb8dee56c1852ccd868becf2710f601b5f427"
254 | dependencies = [
255 | "async-channel",
256 | "async-task",
257 | "atomic-waker",
258 | "fastrand",
259 | "futures-lite",
260 | "once_cell",
261 | ]
262 |
263 | [[package]]
264 | name = "bumpalo"
265 | version = "3.9.1"
266 | source = "registry+https://github.com/rust-lang/crates.io-index"
267 | checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899"
268 |
269 | [[package]]
270 | name = "byteorder"
271 | version = "1.4.3"
272 | source = "registry+https://github.com/rust-lang/crates.io-index"
273 | checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
274 |
275 | [[package]]
276 | name = "bytes"
277 | version = "1.1.0"
278 | source = "registry+https://github.com/rust-lang/crates.io-index"
279 | checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8"
280 |
281 | [[package]]
282 | name = "cache-padded"
283 | version = "1.2.0"
284 | source = "registry+https://github.com/rust-lang/crates.io-index"
285 | checksum = "c1db59621ec70f09c5e9b597b220c7a2b43611f4710dc03ceb8748637775692c"
286 |
287 | [[package]]
288 | name = "cc"
289 | version = "1.0.72"
290 | source = "registry+https://github.com/rust-lang/crates.io-index"
291 | checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee"
292 |
293 | [[package]]
294 | name = "cfg-if"
295 | version = "1.0.0"
296 | source = "registry+https://github.com/rust-lang/crates.io-index"
297 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
298 |
299 | [[package]]
300 | name = "concurrent-queue"
301 | version = "1.2.2"
302 | source = "registry+https://github.com/rust-lang/crates.io-index"
303 | checksum = "30ed07550be01594c6026cff2a1d7fe9c8f683caa798e12b68694ac9e88286a3"
304 | dependencies = [
305 | "cache-padded",
306 | ]
307 |
308 | [[package]]
309 | name = "cpufeatures"
310 | version = "0.2.1"
311 | source = "registry+https://github.com/rust-lang/crates.io-index"
312 | checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469"
313 | dependencies = [
314 | "libc",
315 | ]
316 |
317 | [[package]]
318 | name = "crossbeam-utils"
319 | version = "0.8.6"
320 | source = "registry+https://github.com/rust-lang/crates.io-index"
321 | checksum = "cfcae03edb34f947e64acdb1c33ec169824e20657e9ecb61cef6c8c74dcb8120"
322 | dependencies = [
323 | "cfg-if",
324 | "lazy_static",
325 | ]
326 |
327 | [[package]]
328 | name = "ctor"
329 | version = "0.1.21"
330 | source = "registry+https://github.com/rust-lang/crates.io-index"
331 | checksum = "ccc0a48a9b826acdf4028595adc9db92caea352f7af011a3034acd172a52a0aa"
332 | dependencies = [
333 | "quote",
334 | "syn",
335 | ]
336 |
337 | [[package]]
338 | name = "digest"
339 | version = "0.9.0"
340 | source = "registry+https://github.com/rust-lang/crates.io-index"
341 | checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066"
342 | dependencies = [
343 | "generic-array",
344 | ]
345 |
346 | [[package]]
347 | name = "env_logger"
348 | version = "0.7.1"
349 | source = "registry+https://github.com/rust-lang/crates.io-index"
350 | checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36"
351 | dependencies = [
352 | "atty",
353 | "humantime",
354 | "log",
355 | "regex",
356 | "termcolor",
357 | ]
358 |
359 | [[package]]
360 | name = "event-listener"
361 | version = "2.5.2"
362 | source = "registry+https://github.com/rust-lang/crates.io-index"
363 | checksum = "77f3309417938f28bf8228fcff79a4a37103981e3e186d2ccd19c74b38f4eb71"
364 |
365 | [[package]]
366 | name = "event-listener-primitives"
367 | version = "2.0.1"
368 | source = "registry+https://github.com/rust-lang/crates.io-index"
369 | checksum = "5384093b4255393cc8c42f0fc3dd4f19977ad3b1025f968257854895a993028c"
370 | dependencies = [
371 | "nohash-hasher",
372 | "parking_lot",
373 | "smallvec",
374 | ]
375 |
376 | [[package]]
377 | name = "fastrand"
378 | version = "1.7.0"
379 | source = "registry+https://github.com/rust-lang/crates.io-index"
380 | checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf"
381 | dependencies = [
382 | "instant",
383 | ]
384 |
385 | [[package]]
386 | name = "fnv"
387 | version = "1.0.7"
388 | source = "registry+https://github.com/rust-lang/crates.io-index"
389 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
390 |
391 | [[package]]
392 | name = "form_urlencoded"
393 | version = "1.0.1"
394 | source = "registry+https://github.com/rust-lang/crates.io-index"
395 | checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191"
396 | dependencies = [
397 | "matches",
398 | "percent-encoding",
399 | ]
400 |
401 | [[package]]
402 | name = "ftl-protocol"
403 | version = "0.0.6"
404 | source = "registry+https://github.com/rust-lang/crates.io-index"
405 | checksum = "a89a4d7b50237d0f1218514e6cdd136cb26f1af515c13470159e3c3aa5caf5ba"
406 | dependencies = [
407 | "async-std",
408 | "async-trait",
409 | "hex",
410 | "log",
411 | "rand",
412 | "ring",
413 | ]
414 |
415 | [[package]]
416 | name = "futures"
417 | version = "0.3.19"
418 | source = "registry+https://github.com/rust-lang/crates.io-index"
419 | checksum = "28560757fe2bb34e79f907794bb6b22ae8b0e5c669b638a1132f2592b19035b4"
420 | dependencies = [
421 | "futures-channel",
422 | "futures-core",
423 | "futures-executor",
424 | "futures-io",
425 | "futures-sink",
426 | "futures-task",
427 | "futures-util",
428 | ]
429 |
430 | [[package]]
431 | name = "futures-channel"
432 | version = "0.3.19"
433 | source = "registry+https://github.com/rust-lang/crates.io-index"
434 | checksum = "ba3dda0b6588335f360afc675d0564c17a77a2bda81ca178a4b6081bd86c7f0b"
435 | dependencies = [
436 | "futures-core",
437 | "futures-sink",
438 | ]
439 |
440 | [[package]]
441 | name = "futures-core"
442 | version = "0.3.19"
443 | source = "registry+https://github.com/rust-lang/crates.io-index"
444 | checksum = "d0c8ff0461b82559810cdccfde3215c3f373807f5e5232b71479bff7bb2583d7"
445 |
446 | [[package]]
447 | name = "futures-executor"
448 | version = "0.3.19"
449 | source = "registry+https://github.com/rust-lang/crates.io-index"
450 | checksum = "29d6d2ff5bb10fb95c85b8ce46538a2e5f5e7fdc755623a7d4529ab8a4ed9d2a"
451 | dependencies = [
452 | "futures-core",
453 | "futures-task",
454 | "futures-util",
455 | ]
456 |
457 | [[package]]
458 | name = "futures-io"
459 | version = "0.3.19"
460 | source = "registry+https://github.com/rust-lang/crates.io-index"
461 | checksum = "b1f9d34af5a1aac6fb380f735fe510746c38067c5bf16c7fd250280503c971b2"
462 |
463 | [[package]]
464 | name = "futures-lite"
465 | version = "1.12.0"
466 | source = "registry+https://github.com/rust-lang/crates.io-index"
467 | checksum = "7694489acd39452c77daa48516b894c153f192c3578d5a839b62c58099fcbf48"
468 | dependencies = [
469 | "fastrand",
470 | "futures-core",
471 | "futures-io",
472 | "memchr",
473 | "parking",
474 | "pin-project-lite",
475 | "waker-fn",
476 | ]
477 |
478 | [[package]]
479 | name = "futures-macro"
480 | version = "0.3.19"
481 | source = "registry+https://github.com/rust-lang/crates.io-index"
482 | checksum = "6dbd947adfffb0efc70599b3ddcf7b5597bb5fa9e245eb99f62b3a5f7bb8bd3c"
483 | dependencies = [
484 | "proc-macro2",
485 | "quote",
486 | "syn",
487 | ]
488 |
489 | [[package]]
490 | name = "futures-micro"
491 | version = "0.5.0"
492 | source = "registry+https://github.com/rust-lang/crates.io-index"
493 | checksum = "b460264b3593d68b16a7bc35f7bc226ddfebdf9a1c8db1ed95d5cc6b7168c826"
494 | dependencies = [
495 | "pin-project-lite",
496 | ]
497 |
498 | [[package]]
499 | name = "futures-sink"
500 | version = "0.3.19"
501 | source = "registry+https://github.com/rust-lang/crates.io-index"
502 | checksum = "e3055baccb68d74ff6480350f8d6eb8fcfa3aa11bdc1a1ae3afdd0514617d508"
503 |
504 | [[package]]
505 | name = "futures-task"
506 | version = "0.3.19"
507 | source = "registry+https://github.com/rust-lang/crates.io-index"
508 | checksum = "6ee7c6485c30167ce4dfb83ac568a849fe53274c831081476ee13e0dce1aad72"
509 |
510 | [[package]]
511 | name = "futures-util"
512 | version = "0.3.19"
513 | source = "registry+https://github.com/rust-lang/crates.io-index"
514 | checksum = "d9b5cf40b47a271f77a8b1bec03ca09044d99d2372c0de244e66430761127164"
515 | dependencies = [
516 | "futures-channel",
517 | "futures-core",
518 | "futures-io",
519 | "futures-macro",
520 | "futures-sink",
521 | "futures-task",
522 | "memchr",
523 | "pin-project-lite",
524 | "pin-utils",
525 | "slab",
526 | ]
527 |
528 | [[package]]
529 | name = "generic-array"
530 | version = "0.14.5"
531 | source = "registry+https://github.com/rust-lang/crates.io-index"
532 | checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803"
533 | dependencies = [
534 | "typenum",
535 | "version_check",
536 | ]
537 |
538 | [[package]]
539 | name = "getrandom"
540 | version = "0.2.4"
541 | source = "registry+https://github.com/rust-lang/crates.io-index"
542 | checksum = "418d37c8b1d42553c93648be529cb70f920d3baf8ef469b74b9638df426e0b4c"
543 | dependencies = [
544 | "cfg-if",
545 | "libc",
546 | "wasi",
547 | ]
548 |
549 | [[package]]
550 | name = "gloo-timers"
551 | version = "0.2.2"
552 | source = "registry+https://github.com/rust-lang/crates.io-index"
553 | checksum = "6f16c88aa13d2656ef20d1c042086b8767bbe2bdb62526894275a1b062161b2e"
554 | dependencies = [
555 | "futures-channel",
556 | "futures-core",
557 | "js-sys",
558 | "wasm-bindgen",
559 | "web-sys",
560 | ]
561 |
562 | [[package]]
563 | name = "h264-profile-level-id"
564 | version = "0.1.1"
565 | source = "registry+https://github.com/rust-lang/crates.io-index"
566 | checksum = "e12ebc03fc4f14b7ddc94da90cfb28ba3edee2d926798a9eef89f8a27bbdbca5"
567 | dependencies = [
568 | "bitpattern",
569 | "log",
570 | "once_cell",
571 | "thiserror",
572 | ]
573 |
574 | [[package]]
575 | name = "hash_hasher"
576 | version = "2.0.3"
577 | source = "registry+https://github.com/rust-lang/crates.io-index"
578 | checksum = "74721d007512d0cb3338cd20f0654ac913920061a4c4d0d8708edb3f2a698c0c"
579 |
580 | [[package]]
581 | name = "hermit-abi"
582 | version = "0.1.19"
583 | source = "registry+https://github.com/rust-lang/crates.io-index"
584 | checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
585 | dependencies = [
586 | "libc",
587 | ]
588 |
589 | [[package]]
590 | name = "hex"
591 | version = "0.4.3"
592 | source = "registry+https://github.com/rust-lang/crates.io-index"
593 | checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
594 |
595 | [[package]]
596 | name = "http"
597 | version = "0.2.6"
598 | source = "registry+https://github.com/rust-lang/crates.io-index"
599 | checksum = "31f4c6746584866f0feabcc69893c5b51beef3831656a968ed7ae254cdc4fd03"
600 | dependencies = [
601 | "bytes",
602 | "fnv",
603 | "itoa",
604 | ]
605 |
606 | [[package]]
607 | name = "httparse"
608 | version = "1.5.1"
609 | source = "registry+https://github.com/rust-lang/crates.io-index"
610 | checksum = "acd94fdbe1d4ff688b67b04eee2e17bd50995534a61539e45adfefb45e5e5503"
611 |
612 | [[package]]
613 | name = "humantime"
614 | version = "1.3.0"
615 | source = "registry+https://github.com/rust-lang/crates.io-index"
616 | checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f"
617 | dependencies = [
618 | "quick-error",
619 | ]
620 |
621 | [[package]]
622 | name = "hyperspeed"
623 | version = "0.1.0"
624 | dependencies = [
625 | "async-std",
626 | "async-trait",
627 | "ftl-protocol",
628 | "hyperspeed-broadcast",
629 | "once_cell",
630 | "pretty_env_logger",
631 | ]
632 |
633 | [[package]]
634 | name = "hyperspeed-broadcast"
635 | version = "0.0.11"
636 | dependencies = [
637 | "async-std",
638 | "async-trait",
639 | "async-tungstenite",
640 | "bytes",
641 | "ftl-protocol",
642 | "futures",
643 | "lazy_static",
644 | "log",
645 | "mediasoup",
646 | "nanoid",
647 | "once_cell",
648 | "rtp",
649 | "serde",
650 | "serde_json",
651 | "webrtc-util",
652 | ]
653 |
654 | [[package]]
655 | name = "idna"
656 | version = "0.2.3"
657 | source = "registry+https://github.com/rust-lang/crates.io-index"
658 | checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8"
659 | dependencies = [
660 | "matches",
661 | "unicode-bidi",
662 | "unicode-normalization",
663 | ]
664 |
665 | [[package]]
666 | name = "instant"
667 | version = "0.1.12"
668 | source = "registry+https://github.com/rust-lang/crates.io-index"
669 | checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
670 | dependencies = [
671 | "cfg-if",
672 | ]
673 |
674 | [[package]]
675 | name = "ipnet"
676 | version = "2.3.1"
677 | source = "registry+https://github.com/rust-lang/crates.io-index"
678 | checksum = "68f2d64f2edebec4ce84ad108148e67e1064789bee435edc5b60ad398714a3a9"
679 |
680 | [[package]]
681 | name = "itoa"
682 | version = "1.0.1"
683 | source = "registry+https://github.com/rust-lang/crates.io-index"
684 | checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35"
685 |
686 | [[package]]
687 | name = "js-sys"
688 | version = "0.3.56"
689 | source = "registry+https://github.com/rust-lang/crates.io-index"
690 | checksum = "a38fc24e30fd564ce974c02bf1d337caddff65be6cc4735a1f7eab22a7440f04"
691 | dependencies = [
692 | "wasm-bindgen",
693 | ]
694 |
695 | [[package]]
696 | name = "kv-log-macro"
697 | version = "1.0.7"
698 | source = "registry+https://github.com/rust-lang/crates.io-index"
699 | checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f"
700 | dependencies = [
701 | "log",
702 | ]
703 |
704 | [[package]]
705 | name = "lazy_static"
706 | version = "1.4.0"
707 | source = "registry+https://github.com/rust-lang/crates.io-index"
708 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
709 |
710 | [[package]]
711 | name = "libc"
712 | version = "0.2.115"
713 | source = "registry+https://github.com/rust-lang/crates.io-index"
714 | checksum = "0a8d982fa7a96a000f6ec4cfe966de9703eccde29750df2bb8949da91b0e818d"
715 |
716 | [[package]]
717 | name = "lock_api"
718 | version = "0.4.5"
719 | source = "registry+https://github.com/rust-lang/crates.io-index"
720 | checksum = "712a4d093c9976e24e7dbca41db895dabcbac38eb5f4045393d17a95bdfb1109"
721 | dependencies = [
722 | "scopeguard",
723 | "serde",
724 | ]
725 |
726 | [[package]]
727 | name = "log"
728 | version = "0.4.14"
729 | source = "registry+https://github.com/rust-lang/crates.io-index"
730 | checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
731 | dependencies = [
732 | "cfg-if",
733 | "value-bag",
734 | ]
735 |
736 | [[package]]
737 | name = "lru"
738 | version = "0.7.2"
739 | source = "registry+https://github.com/rust-lang/crates.io-index"
740 | checksum = "274353858935c992b13c0ca408752e2121da852d07dec7ce5f108c77dfa14d1f"
741 |
742 | [[package]]
743 | name = "matches"
744 | version = "0.1.9"
745 | source = "registry+https://github.com/rust-lang/crates.io-index"
746 | checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f"
747 |
748 | [[package]]
749 | name = "mediasoup"
750 | version = "0.9.2"
751 | source = "registry+https://github.com/rust-lang/crates.io-index"
752 | checksum = "517582a7a65fefeb305b9a9b9dc711a5f91a28bc0d2f4a52d8bca935a4a7b4aa"
753 | dependencies = [
754 | "async-channel",
755 | "async-executor",
756 | "async-lock",
757 | "async-oneshot",
758 | "async-trait",
759 | "atomic-take",
760 | "event-listener-primitives",
761 | "fastrand",
762 | "futures-lite",
763 | "h264-profile-level-id",
764 | "hash_hasher",
765 | "log",
766 | "lru",
767 | "mediasoup-sys",
768 | "nohash-hasher",
769 | "once_cell",
770 | "parking_lot",
771 | "regex",
772 | "serde",
773 | "serde_json",
774 | "serde_repr",
775 | "thiserror",
776 | "uuid",
777 | ]
778 |
779 | [[package]]
780 | name = "mediasoup-sys"
781 | version = "0.3.2"
782 | source = "registry+https://github.com/rust-lang/crates.io-index"
783 | checksum = "c83eda72bddffb50bd363b3d598a9c4634f7458be4b5ec67c459b38237b6d301"
784 |
785 | [[package]]
786 | name = "memchr"
787 | version = "2.4.1"
788 | source = "registry+https://github.com/rust-lang/crates.io-index"
789 | checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
790 |
791 | [[package]]
792 | name = "memoffset"
793 | version = "0.6.5"
794 | source = "registry+https://github.com/rust-lang/crates.io-index"
795 | checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce"
796 | dependencies = [
797 | "autocfg",
798 | ]
799 |
800 | [[package]]
801 | name = "mio"
802 | version = "0.7.14"
803 | source = "registry+https://github.com/rust-lang/crates.io-index"
804 | checksum = "8067b404fe97c70829f082dec8bcf4f71225d7eaea1d8645349cb76fa06205cc"
805 | dependencies = [
806 | "libc",
807 | "log",
808 | "miow",
809 | "ntapi",
810 | "winapi",
811 | ]
812 |
813 | [[package]]
814 | name = "miow"
815 | version = "0.3.7"
816 | source = "registry+https://github.com/rust-lang/crates.io-index"
817 | checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21"
818 | dependencies = [
819 | "winapi",
820 | ]
821 |
822 | [[package]]
823 | name = "nanoid"
824 | version = "0.4.0"
825 | source = "registry+https://github.com/rust-lang/crates.io-index"
826 | checksum = "3ffa00dec017b5b1a8b7cf5e2c008bfda1aa7e0697ac1508b491fdf2622fb4d8"
827 | dependencies = [
828 | "rand",
829 | ]
830 |
831 | [[package]]
832 | name = "nix"
833 | version = "0.23.1"
834 | source = "registry+https://github.com/rust-lang/crates.io-index"
835 | checksum = "9f866317acbd3a240710c63f065ffb1e4fd466259045ccb504130b7f668f35c6"
836 | dependencies = [
837 | "bitflags",
838 | "cc",
839 | "cfg-if",
840 | "libc",
841 | "memoffset",
842 | ]
843 |
844 | [[package]]
845 | name = "nohash-hasher"
846 | version = "0.2.0"
847 | source = "registry+https://github.com/rust-lang/crates.io-index"
848 | checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451"
849 |
850 | [[package]]
851 | name = "ntapi"
852 | version = "0.3.6"
853 | source = "registry+https://github.com/rust-lang/crates.io-index"
854 | checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44"
855 | dependencies = [
856 | "winapi",
857 | ]
858 |
859 | [[package]]
860 | name = "num_cpus"
861 | version = "1.13.1"
862 | source = "registry+https://github.com/rust-lang/crates.io-index"
863 | checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1"
864 | dependencies = [
865 | "hermit-abi",
866 | "libc",
867 | ]
868 |
869 | [[package]]
870 | name = "once_cell"
871 | version = "1.9.0"
872 | source = "registry+https://github.com/rust-lang/crates.io-index"
873 | checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5"
874 |
875 | [[package]]
876 | name = "opaque-debug"
877 | version = "0.3.0"
878 | source = "registry+https://github.com/rust-lang/crates.io-index"
879 | checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
880 |
881 | [[package]]
882 | name = "parking"
883 | version = "2.0.0"
884 | source = "registry+https://github.com/rust-lang/crates.io-index"
885 | checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72"
886 |
887 | [[package]]
888 | name = "parking_lot"
889 | version = "0.11.2"
890 | source = "registry+https://github.com/rust-lang/crates.io-index"
891 | checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99"
892 | dependencies = [
893 | "instant",
894 | "lock_api",
895 | "parking_lot_core",
896 | ]
897 |
898 | [[package]]
899 | name = "parking_lot_core"
900 | version = "0.8.5"
901 | source = "registry+https://github.com/rust-lang/crates.io-index"
902 | checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216"
903 | dependencies = [
904 | "cfg-if",
905 | "instant",
906 | "libc",
907 | "redox_syscall",
908 | "smallvec",
909 | "winapi",
910 | ]
911 |
912 | [[package]]
913 | name = "paste"
914 | version = "0.1.18"
915 | source = "registry+https://github.com/rust-lang/crates.io-index"
916 | checksum = "45ca20c77d80be666aef2b45486da86238fabe33e38306bd3118fe4af33fa880"
917 | dependencies = [
918 | "paste-impl",
919 | "proc-macro-hack",
920 | ]
921 |
922 | [[package]]
923 | name = "paste-impl"
924 | version = "0.1.18"
925 | source = "registry+https://github.com/rust-lang/crates.io-index"
926 | checksum = "d95a7db200b97ef370c8e6de0088252f7e0dfff7d047a28528e47456c0fc98b6"
927 | dependencies = [
928 | "proc-macro-hack",
929 | ]
930 |
931 | [[package]]
932 | name = "percent-encoding"
933 | version = "2.1.0"
934 | source = "registry+https://github.com/rust-lang/crates.io-index"
935 | checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
936 |
937 | [[package]]
938 | name = "pin-project-lite"
939 | version = "0.2.8"
940 | source = "registry+https://github.com/rust-lang/crates.io-index"
941 | checksum = "e280fbe77cc62c91527259e9442153f4688736748d24660126286329742b4c6c"
942 |
943 | [[package]]
944 | name = "pin-utils"
945 | version = "0.1.0"
946 | source = "registry+https://github.com/rust-lang/crates.io-index"
947 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
948 |
949 | [[package]]
950 | name = "polling"
951 | version = "2.2.0"
952 | source = "registry+https://github.com/rust-lang/crates.io-index"
953 | checksum = "685404d509889fade3e86fe3a5803bca2ec09b0c0778d5ada6ec8bf7a8de5259"
954 | dependencies = [
955 | "cfg-if",
956 | "libc",
957 | "log",
958 | "wepoll-ffi",
959 | "winapi",
960 | ]
961 |
962 | [[package]]
963 | name = "ppv-lite86"
964 | version = "0.2.16"
965 | source = "registry+https://github.com/rust-lang/crates.io-index"
966 | checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872"
967 |
968 | [[package]]
969 | name = "pretty_env_logger"
970 | version = "0.4.0"
971 | source = "registry+https://github.com/rust-lang/crates.io-index"
972 | checksum = "926d36b9553851b8b0005f1275891b392ee4d2d833852c417ed025477350fb9d"
973 | dependencies = [
974 | "env_logger",
975 | "log",
976 | ]
977 |
978 | [[package]]
979 | name = "proc-macro-hack"
980 | version = "0.5.19"
981 | source = "registry+https://github.com/rust-lang/crates.io-index"
982 | checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
983 |
984 | [[package]]
985 | name = "proc-macro2"
986 | version = "1.0.36"
987 | source = "registry+https://github.com/rust-lang/crates.io-index"
988 | checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029"
989 | dependencies = [
990 | "unicode-xid",
991 | ]
992 |
993 | [[package]]
994 | name = "quick-error"
995 | version = "1.2.3"
996 | source = "registry+https://github.com/rust-lang/crates.io-index"
997 | checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
998 |
999 | [[package]]
1000 | name = "quote"
1001 | version = "1.0.15"
1002 | source = "registry+https://github.com/rust-lang/crates.io-index"
1003 | checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145"
1004 | dependencies = [
1005 | "proc-macro2",
1006 | ]
1007 |
1008 | [[package]]
1009 | name = "rand"
1010 | version = "0.8.4"
1011 | source = "registry+https://github.com/rust-lang/crates.io-index"
1012 | checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8"
1013 | dependencies = [
1014 | "libc",
1015 | "rand_chacha",
1016 | "rand_core",
1017 | "rand_hc",
1018 | ]
1019 |
1020 | [[package]]
1021 | name = "rand_chacha"
1022 | version = "0.3.1"
1023 | source = "registry+https://github.com/rust-lang/crates.io-index"
1024 | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
1025 | dependencies = [
1026 | "ppv-lite86",
1027 | "rand_core",
1028 | ]
1029 |
1030 | [[package]]
1031 | name = "rand_core"
1032 | version = "0.6.3"
1033 | source = "registry+https://github.com/rust-lang/crates.io-index"
1034 | checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
1035 | dependencies = [
1036 | "getrandom",
1037 | ]
1038 |
1039 | [[package]]
1040 | name = "rand_hc"
1041 | version = "0.3.1"
1042 | source = "registry+https://github.com/rust-lang/crates.io-index"
1043 | checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7"
1044 | dependencies = [
1045 | "rand_core",
1046 | ]
1047 |
1048 | [[package]]
1049 | name = "redox_syscall"
1050 | version = "0.2.10"
1051 | source = "registry+https://github.com/rust-lang/crates.io-index"
1052 | checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff"
1053 | dependencies = [
1054 | "bitflags",
1055 | ]
1056 |
1057 | [[package]]
1058 | name = "regex"
1059 | version = "1.5.4"
1060 | source = "registry+https://github.com/rust-lang/crates.io-index"
1061 | checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461"
1062 | dependencies = [
1063 | "aho-corasick",
1064 | "memchr",
1065 | "regex-syntax",
1066 | ]
1067 |
1068 | [[package]]
1069 | name = "regex-syntax"
1070 | version = "0.6.25"
1071 | source = "registry+https://github.com/rust-lang/crates.io-index"
1072 | checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
1073 |
1074 | [[package]]
1075 | name = "ring"
1076 | version = "0.16.20"
1077 | source = "registry+https://github.com/rust-lang/crates.io-index"
1078 | checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc"
1079 | dependencies = [
1080 | "cc",
1081 | "libc",
1082 | "once_cell",
1083 | "spin",
1084 | "untrusted",
1085 | "web-sys",
1086 | "winapi",
1087 | ]
1088 |
1089 | [[package]]
1090 | name = "rtp"
1091 | version = "0.6.5"
1092 | source = "registry+https://github.com/rust-lang/crates.io-index"
1093 | checksum = "5110c12c9f7d1e76eba80076cce4ccb82ee085bd10a62472468de0663240f8b5"
1094 | dependencies = [
1095 | "async-trait",
1096 | "bytes",
1097 | "rand",
1098 | "thiserror",
1099 | "webrtc-util",
1100 | ]
1101 |
1102 | [[package]]
1103 | name = "ryu"
1104 | version = "1.0.9"
1105 | source = "registry+https://github.com/rust-lang/crates.io-index"
1106 | checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f"
1107 |
1108 | [[package]]
1109 | name = "scopeguard"
1110 | version = "1.1.0"
1111 | source = "registry+https://github.com/rust-lang/crates.io-index"
1112 | checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
1113 |
1114 | [[package]]
1115 | name = "serde"
1116 | version = "1.0.136"
1117 | source = "registry+https://github.com/rust-lang/crates.io-index"
1118 | checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789"
1119 | dependencies = [
1120 | "serde_derive",
1121 | ]
1122 |
1123 | [[package]]
1124 | name = "serde_derive"
1125 | version = "1.0.136"
1126 | source = "registry+https://github.com/rust-lang/crates.io-index"
1127 | checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9"
1128 | dependencies = [
1129 | "proc-macro2",
1130 | "quote",
1131 | "syn",
1132 | ]
1133 |
1134 | [[package]]
1135 | name = "serde_json"
1136 | version = "1.0.78"
1137 | source = "registry+https://github.com/rust-lang/crates.io-index"
1138 | checksum = "d23c1ba4cf0efd44be32017709280b32d1cea5c3f1275c3b6d9e8bc54f758085"
1139 | dependencies = [
1140 | "itoa",
1141 | "ryu",
1142 | "serde",
1143 | ]
1144 |
1145 | [[package]]
1146 | name = "serde_repr"
1147 | version = "0.1.7"
1148 | source = "registry+https://github.com/rust-lang/crates.io-index"
1149 | checksum = "98d0516900518c29efa217c298fa1f4e6c6ffc85ae29fd7f4ee48f176e1a9ed5"
1150 | dependencies = [
1151 | "proc-macro2",
1152 | "quote",
1153 | "syn",
1154 | ]
1155 |
1156 | [[package]]
1157 | name = "sha-1"
1158 | version = "0.9.8"
1159 | source = "registry+https://github.com/rust-lang/crates.io-index"
1160 | checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6"
1161 | dependencies = [
1162 | "block-buffer",
1163 | "cfg-if",
1164 | "cpufeatures",
1165 | "digest",
1166 | "opaque-debug",
1167 | ]
1168 |
1169 | [[package]]
1170 | name = "signal-hook"
1171 | version = "0.3.13"
1172 | source = "registry+https://github.com/rust-lang/crates.io-index"
1173 | checksum = "647c97df271007dcea485bb74ffdb57f2e683f1306c854f468a0c244badabf2d"
1174 | dependencies = [
1175 | "libc",
1176 | "signal-hook-registry",
1177 | ]
1178 |
1179 | [[package]]
1180 | name = "signal-hook-registry"
1181 | version = "1.4.0"
1182 | source = "registry+https://github.com/rust-lang/crates.io-index"
1183 | checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0"
1184 | dependencies = [
1185 | "libc",
1186 | ]
1187 |
1188 | [[package]]
1189 | name = "slab"
1190 | version = "0.4.5"
1191 | source = "registry+https://github.com/rust-lang/crates.io-index"
1192 | checksum = "9def91fd1e018fe007022791f865d0ccc9b3a0d5001e01aabb8b40e46000afb5"
1193 |
1194 | [[package]]
1195 | name = "smallvec"
1196 | version = "1.8.0"
1197 | source = "registry+https://github.com/rust-lang/crates.io-index"
1198 | checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83"
1199 |
1200 | [[package]]
1201 | name = "socket2"
1202 | version = "0.4.4"
1203 | source = "registry+https://github.com/rust-lang/crates.io-index"
1204 | checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0"
1205 | dependencies = [
1206 | "libc",
1207 | "winapi",
1208 | ]
1209 |
1210 | [[package]]
1211 | name = "spin"
1212 | version = "0.5.2"
1213 | source = "registry+https://github.com/rust-lang/crates.io-index"
1214 | checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
1215 |
1216 | [[package]]
1217 | name = "syn"
1218 | version = "1.0.86"
1219 | source = "registry+https://github.com/rust-lang/crates.io-index"
1220 | checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b"
1221 | dependencies = [
1222 | "proc-macro2",
1223 | "quote",
1224 | "unicode-xid",
1225 | ]
1226 |
1227 | [[package]]
1228 | name = "termcolor"
1229 | version = "1.1.2"
1230 | source = "registry+https://github.com/rust-lang/crates.io-index"
1231 | checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4"
1232 | dependencies = [
1233 | "winapi-util",
1234 | ]
1235 |
1236 | [[package]]
1237 | name = "thiserror"
1238 | version = "1.0.30"
1239 | source = "registry+https://github.com/rust-lang/crates.io-index"
1240 | checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417"
1241 | dependencies = [
1242 | "thiserror-impl",
1243 | ]
1244 |
1245 | [[package]]
1246 | name = "thiserror-impl"
1247 | version = "1.0.30"
1248 | source = "registry+https://github.com/rust-lang/crates.io-index"
1249 | checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b"
1250 | dependencies = [
1251 | "proc-macro2",
1252 | "quote",
1253 | "syn",
1254 | ]
1255 |
1256 | [[package]]
1257 | name = "tinyvec"
1258 | version = "1.5.1"
1259 | source = "registry+https://github.com/rust-lang/crates.io-index"
1260 | checksum = "2c1c1d5a42b6245520c249549ec267180beaffcc0615401ac8e31853d4b6d8d2"
1261 | dependencies = [
1262 | "tinyvec_macros",
1263 | ]
1264 |
1265 | [[package]]
1266 | name = "tinyvec_macros"
1267 | version = "0.1.0"
1268 | source = "registry+https://github.com/rust-lang/crates.io-index"
1269 | checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
1270 |
1271 | [[package]]
1272 | name = "tokio"
1273 | version = "1.15.0"
1274 | source = "registry+https://github.com/rust-lang/crates.io-index"
1275 | checksum = "fbbf1c778ec206785635ce8ad57fe52b3009ae9e0c9f574a728f3049d3e55838"
1276 | dependencies = [
1277 | "bytes",
1278 | "libc",
1279 | "memchr",
1280 | "mio",
1281 | "num_cpus",
1282 | "once_cell",
1283 | "parking_lot",
1284 | "pin-project-lite",
1285 | "signal-hook-registry",
1286 | "tokio-macros",
1287 | "winapi",
1288 | ]
1289 |
1290 | [[package]]
1291 | name = "tokio-macros"
1292 | version = "1.7.0"
1293 | source = "registry+https://github.com/rust-lang/crates.io-index"
1294 | checksum = "b557f72f448c511a979e2564e55d74e6c4432fc96ff4f6241bc6bded342643b7"
1295 | dependencies = [
1296 | "proc-macro2",
1297 | "quote",
1298 | "syn",
1299 | ]
1300 |
1301 | [[package]]
1302 | name = "tungstenite"
1303 | version = "0.16.0"
1304 | source = "registry+https://github.com/rust-lang/crates.io-index"
1305 | checksum = "6ad3713a14ae247f22a728a0456a545df14acf3867f905adff84be99e23b3ad1"
1306 | dependencies = [
1307 | "base64",
1308 | "byteorder",
1309 | "bytes",
1310 | "http",
1311 | "httparse",
1312 | "log",
1313 | "rand",
1314 | "sha-1",
1315 | "thiserror",
1316 | "url",
1317 | "utf-8",
1318 | ]
1319 |
1320 | [[package]]
1321 | name = "typenum"
1322 | version = "1.15.0"
1323 | source = "registry+https://github.com/rust-lang/crates.io-index"
1324 | checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987"
1325 |
1326 | [[package]]
1327 | name = "unicode-bidi"
1328 | version = "0.3.7"
1329 | source = "registry+https://github.com/rust-lang/crates.io-index"
1330 | checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f"
1331 |
1332 | [[package]]
1333 | name = "unicode-normalization"
1334 | version = "0.1.19"
1335 | source = "registry+https://github.com/rust-lang/crates.io-index"
1336 | checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9"
1337 | dependencies = [
1338 | "tinyvec",
1339 | ]
1340 |
1341 | [[package]]
1342 | name = "unicode-xid"
1343 | version = "0.2.2"
1344 | source = "registry+https://github.com/rust-lang/crates.io-index"
1345 | checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
1346 |
1347 | [[package]]
1348 | name = "untrusted"
1349 | version = "0.7.1"
1350 | source = "registry+https://github.com/rust-lang/crates.io-index"
1351 | checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
1352 |
1353 | [[package]]
1354 | name = "url"
1355 | version = "2.2.2"
1356 | source = "registry+https://github.com/rust-lang/crates.io-index"
1357 | checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c"
1358 | dependencies = [
1359 | "form_urlencoded",
1360 | "idna",
1361 | "matches",
1362 | "percent-encoding",
1363 | ]
1364 |
1365 | [[package]]
1366 | name = "utf-8"
1367 | version = "0.7.6"
1368 | source = "registry+https://github.com/rust-lang/crates.io-index"
1369 | checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
1370 |
1371 | [[package]]
1372 | name = "uuid"
1373 | version = "0.8.2"
1374 | source = "registry+https://github.com/rust-lang/crates.io-index"
1375 | checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7"
1376 | dependencies = [
1377 | "getrandom",
1378 | "serde",
1379 | ]
1380 |
1381 | [[package]]
1382 | name = "value-bag"
1383 | version = "1.0.0-alpha.8"
1384 | source = "registry+https://github.com/rust-lang/crates.io-index"
1385 | checksum = "79923f7731dc61ebfba3633098bf3ac533bbd35ccd8c57e7088d9a5eebe0263f"
1386 | dependencies = [
1387 | "ctor",
1388 | "version_check",
1389 | ]
1390 |
1391 | [[package]]
1392 | name = "version_check"
1393 | version = "0.9.4"
1394 | source = "registry+https://github.com/rust-lang/crates.io-index"
1395 | checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
1396 |
1397 | [[package]]
1398 | name = "waker-fn"
1399 | version = "1.1.0"
1400 | source = "registry+https://github.com/rust-lang/crates.io-index"
1401 | checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca"
1402 |
1403 | [[package]]
1404 | name = "wasi"
1405 | version = "0.10.2+wasi-snapshot-preview1"
1406 | source = "registry+https://github.com/rust-lang/crates.io-index"
1407 | checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
1408 |
1409 | [[package]]
1410 | name = "wasm-bindgen"
1411 | version = "0.2.79"
1412 | source = "registry+https://github.com/rust-lang/crates.io-index"
1413 | checksum = "25f1af7423d8588a3d840681122e72e6a24ddbcb3f0ec385cac0d12d24256c06"
1414 | dependencies = [
1415 | "cfg-if",
1416 | "wasm-bindgen-macro",
1417 | ]
1418 |
1419 | [[package]]
1420 | name = "wasm-bindgen-backend"
1421 | version = "0.2.79"
1422 | source = "registry+https://github.com/rust-lang/crates.io-index"
1423 | checksum = "8b21c0df030f5a177f3cba22e9bc4322695ec43e7257d865302900290bcdedca"
1424 | dependencies = [
1425 | "bumpalo",
1426 | "lazy_static",
1427 | "log",
1428 | "proc-macro2",
1429 | "quote",
1430 | "syn",
1431 | "wasm-bindgen-shared",
1432 | ]
1433 |
1434 | [[package]]
1435 | name = "wasm-bindgen-futures"
1436 | version = "0.4.29"
1437 | source = "registry+https://github.com/rust-lang/crates.io-index"
1438 | checksum = "2eb6ec270a31b1d3c7e266b999739109abce8b6c87e4b31fcfcd788b65267395"
1439 | dependencies = [
1440 | "cfg-if",
1441 | "js-sys",
1442 | "wasm-bindgen",
1443 | "web-sys",
1444 | ]
1445 |
1446 | [[package]]
1447 | name = "wasm-bindgen-macro"
1448 | version = "0.2.79"
1449 | source = "registry+https://github.com/rust-lang/crates.io-index"
1450 | checksum = "2f4203d69e40a52ee523b2529a773d5ffc1dc0071801c87b3d270b471b80ed01"
1451 | dependencies = [
1452 | "quote",
1453 | "wasm-bindgen-macro-support",
1454 | ]
1455 |
1456 | [[package]]
1457 | name = "wasm-bindgen-macro-support"
1458 | version = "0.2.79"
1459 | source = "registry+https://github.com/rust-lang/crates.io-index"
1460 | checksum = "bfa8a30d46208db204854cadbb5d4baf5fcf8071ba5bf48190c3e59937962ebc"
1461 | dependencies = [
1462 | "proc-macro2",
1463 | "quote",
1464 | "syn",
1465 | "wasm-bindgen-backend",
1466 | "wasm-bindgen-shared",
1467 | ]
1468 |
1469 | [[package]]
1470 | name = "wasm-bindgen-shared"
1471 | version = "0.2.79"
1472 | source = "registry+https://github.com/rust-lang/crates.io-index"
1473 | checksum = "3d958d035c4438e28c70e4321a2911302f10135ce78a9c7834c0cab4123d06a2"
1474 |
1475 | [[package]]
1476 | name = "web-sys"
1477 | version = "0.3.56"
1478 | source = "registry+https://github.com/rust-lang/crates.io-index"
1479 | checksum = "c060b319f29dd25724f09a2ba1418f142f539b2be99fbf4d2d5a8f7330afb8eb"
1480 | dependencies = [
1481 | "js-sys",
1482 | "wasm-bindgen",
1483 | ]
1484 |
1485 | [[package]]
1486 | name = "webrtc-util"
1487 | version = "0.5.3"
1488 | source = "registry+https://github.com/rust-lang/crates.io-index"
1489 | checksum = "60b69bdea720881eddee50bd969be052ed95f04ccc5a6f684495131afb87e31c"
1490 | dependencies = [
1491 | "async-trait",
1492 | "bitflags",
1493 | "bytes",
1494 | "cc",
1495 | "ipnet",
1496 | "lazy_static",
1497 | "libc",
1498 | "log",
1499 | "nix",
1500 | "parking_lot",
1501 | "rand",
1502 | "thiserror",
1503 | "tokio",
1504 | "winapi",
1505 | ]
1506 |
1507 | [[package]]
1508 | name = "wepoll-ffi"
1509 | version = "0.1.2"
1510 | source = "registry+https://github.com/rust-lang/crates.io-index"
1511 | checksum = "d743fdedc5c64377b5fc2bc036b01c7fd642205a0d96356034ae3404d49eb7fb"
1512 | dependencies = [
1513 | "cc",
1514 | ]
1515 |
1516 | [[package]]
1517 | name = "winapi"
1518 | version = "0.3.9"
1519 | source = "registry+https://github.com/rust-lang/crates.io-index"
1520 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
1521 | dependencies = [
1522 | "winapi-i686-pc-windows-gnu",
1523 | "winapi-x86_64-pc-windows-gnu",
1524 | ]
1525 |
1526 | [[package]]
1527 | name = "winapi-i686-pc-windows-gnu"
1528 | version = "0.4.0"
1529 | source = "registry+https://github.com/rust-lang/crates.io-index"
1530 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
1531 |
1532 | [[package]]
1533 | name = "winapi-util"
1534 | version = "0.1.5"
1535 | source = "registry+https://github.com/rust-lang/crates.io-index"
1536 | checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
1537 | dependencies = [
1538 | "winapi",
1539 | ]
1540 |
1541 | [[package]]
1542 | name = "winapi-x86_64-pc-windows-gnu"
1543 | version = "0.4.0"
1544 | source = "registry+https://github.com/rust-lang/crates.io-index"
1545 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
1546 |
--------------------------------------------------------------------------------
/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "hyperspeed"
3 | version = "0.1.0"
4 | edition = "2018"
5 |
6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7 |
8 | [dependencies]
9 | hyperspeed-broadcast = { path = "crates/broadcast" }
10 | ftl-protocol = { version = "0.0.6", features = ["server"] }
11 | # ftl-protocol = { path = "crates/ftl", features = ["server"] }
12 |
13 | once_cell = "1.8.0"
14 | async-trait = "0.1.50"
15 | pretty_env_logger = "0.4"
16 | async-std = { version = "1.8.0", features = ["attributes"] }
17 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | ## [Documentation](https://hyperspeed.cli.rs)
8 |
9 | ## [FTL Protocol](https://hyperspeed.cli.rs/ftl)
10 |
--------------------------------------------------------------------------------
/assets/banner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/insertish/project-hyperspeed/df2b113701939f47046f533ceaf4a57fb68d7b7d/assets/banner.png
--------------------------------------------------------------------------------
/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/insertish/project-hyperspeed/df2b113701939f47046f533ceaf4a57fb68d7b7d/assets/logo.png
--------------------------------------------------------------------------------
/crates/broadcast/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "hyperspeed-broadcast"
3 | description = "FTL media ingest server and WebSocket signaling server."
4 | homepage = "https://hyperspeed.cli.rs"
5 | documentation = "https://hyperspeed.cli.rs/components/broadcast"
6 | repository = "https://github.com/insertish/project-hyperspeed"
7 | version = "0.0.11"
8 | license = "AGPL-3.0"
9 | edition = "2018"
10 |
11 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
12 |
13 | [features]
14 | rtc = [ "once_cell", "mediasoup" ]
15 | ingest = [ "rtc", "async-trait", "async-std", "rtp", "webrtc-util", "bytes", "lazy_static", "nanoid" ]
16 | signaling = [ "rtc", "futures", "async-std", "async-trait", "async-tungstenite", "serde", "serde_json" ]
17 | default = [ "rtc", "ingest", "signaling" ]
18 |
19 | [dependencies]
20 | # ftl-protocol = { path = "../ftl" }
21 | ftl-protocol = "0.0.6"
22 |
23 | # misc
24 | log = "0.4"
25 | bytes = { version = "1.1.0", optional = true }
26 | nanoid = { version = "0.4.0", optional = true }
27 | futures = { version = "0.3.15", optional = true }
28 | once_cell = { version = "1.8.0", optional = true }
29 | lazy_static = { version = "1.4.0", optional = true }
30 |
31 | # async std
32 | async-trait = { version = "0.1.50", optional = true }
33 | async-std = { version = "1.8.0", features = ["attributes", "unstable"], optional = true }
34 | async-tungstenite = { version = "0.16.1", features = ["async-std-runtime"], optional = true }
35 |
36 | # serde
37 | serde_json = { version = "1.0.64", optional = true }
38 | serde = { version = "1.0.126", features = ["derive"], optional = true }
39 |
40 | # WebRTC
41 | rtp = { version = "0.6.5", optional = true }
42 | mediasoup = { version = "0.9.2", optional = true }
43 | webrtc-util = { version = "0.5.3", optional = true }
44 |
45 | [package.metadata.docs.rs]
46 | all-features = true
47 | rustc-args = ["--cfg", "docsrs"]
48 | rustdoc-args = ["--cfg", "docsrs"]
49 |
--------------------------------------------------------------------------------
/crates/broadcast/README.md:
--------------------------------------------------------------------------------
1 | # Broadcast
2 |
3 | [hyperspeed-broadcast](https://gitlab.insrt.uk/insert/project-hyperspeed/-/tree/master/crates/broadcast) is a media ingest server (currently only supports FTL media ingest, forwarding RTP packets to WebRTC clients), it also provides a signaling WebSocket server for establishing new client connections.
4 |
5 | ## [Documentation](https://hyperspeed.cli.rs/components/broadcast)
6 |
--------------------------------------------------------------------------------
/crates/broadcast/src/lib.rs:
--------------------------------------------------------------------------------
1 | #![cfg_attr(docsrs, feature(doc_cfg))]
2 |
3 | #[cfg(feature = "ingest")]
4 | #[cfg_attr(docsrs, doc(cfg(feature = "ingest")))]
5 | #[macro_use]
6 | extern crate lazy_static;
7 |
8 | #[cfg(feature = "rtc")]
9 | #[cfg_attr(docsrs, doc(cfg(feature = "rtc")))]
10 | pub mod rtc;
11 |
12 | #[cfg(feature = "signaling")]
13 | #[cfg_attr(docsrs, doc(cfg(feature = "signaling")))]
14 | pub mod signaling;
15 |
--------------------------------------------------------------------------------
/crates/broadcast/src/rtc/codecs.rs:
--------------------------------------------------------------------------------
1 | use std::num::{NonZeroU32, NonZeroU8};
2 |
3 | use mediasoup::router::RouterOptions;
4 | use mediasoup::rtp_parameters::{MimeTypeAudio, MimeTypeVideo, RtcpFeedback, RtpCodecCapability, RtpCodecParametersParameters};
5 |
6 | use super::routers::DataSource;
7 |
8 | pub struct VideoCodec {
9 | pub mime_type: MimeTypeVideo,
10 | pub clock_rate: u32,
11 | pub parameters: RtpCodecParametersParameters,
12 | pub rtcp_feedback: Vec
13 | }
14 |
15 | impl VideoCodec {
16 | pub fn from(codec: &str) -> VideoCodec {
17 | let mime_type = match codec {
18 | "H264" => MimeTypeVideo::H264,
19 | _ => unimplemented!()
20 | };
21 |
22 | let mut parameters = match mime_type {
23 | MimeTypeVideo::H264 => RtpCodecParametersParameters::from([
24 | ("packetization-mode", 1_u32.into()),
25 | ("level-asymmetry-allowed", 1_u32.into())
26 | ]),
27 | _ => unreachable!()
28 | };
29 |
30 | parameters.insert("profile-level-id", "42e01f");
31 |
32 | let clock_rate = match mime_type {
33 | MimeTypeVideo::H264 => 90_000,
34 | _ => unreachable!()
35 | };
36 |
37 | let rtcp_feedback = match mime_type {
38 | MimeTypeVideo::H264 => vec! [
39 | RtcpFeedback::Nack,
40 | RtcpFeedback::NackPli,
41 | RtcpFeedback::CcmFir,
42 | RtcpFeedback::GoogRemb,
43 | RtcpFeedback::TransportCc,
44 | ],
45 | _ => unreachable!()
46 | };
47 |
48 | VideoCodec {
49 | mime_type,
50 | clock_rate,
51 | parameters,
52 | rtcp_feedback
53 | }
54 | }
55 | }
56 |
57 | pub struct AudioCodec {
58 | pub mime_type: MimeTypeAudio,
59 | pub clock_rate: u32,
60 | pub parameters: RtpCodecParametersParameters,
61 | pub rtcp_feedback: Vec
62 | }
63 |
64 | impl AudioCodec {
65 | pub fn from(codec: &str) -> AudioCodec {
66 | let mime_type = match codec {
67 | "OPUS" => MimeTypeAudio::Opus,
68 | _ => unimplemented!()
69 | };
70 |
71 | let parameters = RtpCodecParametersParameters::default();
72 | let rtcp_feedback = Vec::new();
73 |
74 | let clock_rate = match mime_type {
75 | MimeTypeAudio::Opus => 48_000,
76 | _ => unreachable!()
77 | };
78 |
79 | AudioCodec {
80 | mime_type,
81 | clock_rate,
82 | parameters,
83 | rtcp_feedback
84 | }
85 | }
86 | }
87 |
88 | pub fn init_codecs(options: &mut RouterOptions, source: &DataSource) {
89 | match source {
90 | DataSource::Ftl(handshake) => {
91 | if let Some(video) = &handshake.video {
92 | let VideoCodec { mime_type, clock_rate, parameters, rtcp_feedback }
93 | = VideoCodec::from(&video.codec);
94 |
95 | options.media_codecs.push(
96 | RtpCodecCapability::Video {
97 | mime_type,
98 | preferred_payload_type: None,
99 | clock_rate: NonZeroU32::new(clock_rate).unwrap(),
100 | parameters,
101 | rtcp_feedback
102 | }
103 | );
104 | }
105 |
106 | if let Some(audio) = &handshake.audio {
107 | let AudioCodec { mime_type, clock_rate, parameters, rtcp_feedback }
108 | = AudioCodec::from(&audio.codec);
109 |
110 | options.media_codecs.push(
111 | RtpCodecCapability::Audio {
112 | mime_type,
113 | preferred_payload_type: None,
114 | clock_rate: NonZeroU32::new(clock_rate).unwrap(),
115 | channels: NonZeroU8::new(2).unwrap(),
116 | parameters,
117 | rtcp_feedback
118 | }
119 | );
120 | }
121 | }
122 | }
123 | }
124 |
--------------------------------------------------------------------------------
/crates/broadcast/src/rtc/mod.rs:
--------------------------------------------------------------------------------
1 | pub mod producers;
2 | pub mod routers;
3 | pub mod workers;
4 | pub mod codecs;
5 |
--------------------------------------------------------------------------------
/crates/broadcast/src/rtc/producers.rs:
--------------------------------------------------------------------------------
1 | use std::num::{NonZeroU32, NonZeroU8};
2 | use std::net::SocketAddr;
3 |
4 | use mediasoup::plain_transport::PlainTransportOptions;
5 | use mediasoup::prelude::TransportListenIp;
6 | use mediasoup::producer::{Producer, ProducerOptions};
7 | use mediasoup::router::Router;
8 | use mediasoup::transport::Transport;
9 | use mediasoup::rtp_parameters::{MediaKind, RtpCodecParameters, RtpEncodingParameters, RtpParameters};
10 |
11 | use crate::rtc::codecs::{AudioCodec, VideoCodec};
12 |
13 | use super::routers::DataSource;
14 |
15 | pub async fn init_producers(router: &Router, source: &DataSource, addr: SocketAddr) -> Vec {
16 | let mut producers = Vec::new();
17 |
18 | match source {
19 | DataSource::Ftl(handshake) => {
20 | // Prepare transport options
21 | let listen_ip = TransportListenIp {
22 | ip: addr.ip(),
23 | announced_ip: None,
24 | };
25 | let mut transport_options = PlainTransportOptions::new(listen_ip);
26 | transport_options.port = Some(addr.port());
27 | transport_options.rtcp_mux = true;
28 | transport_options.comedia = true;
29 |
30 | // Create plain transport
31 | let plain_transport = router
32 | .create_plain_transport(transport_options)
33 | .await.unwrap();
34 |
35 | // Initialise video producer
36 | if let Some(video) = &handshake.video {
37 | let VideoCodec { mime_type, clock_rate, parameters, rtcp_feedback }
38 | = VideoCodec::from(&video.codec);
39 |
40 | let mut video_rtp_params = RtpParameters::default();
41 | video_rtp_params.codecs = vec![
42 | RtpCodecParameters::Video {
43 | mime_type,
44 | payload_type: video.payload_type,
45 | clock_rate: NonZeroU32::new(clock_rate).unwrap(),
46 | parameters,
47 | rtcp_feedback
48 | }
49 | ];
50 |
51 | video_rtp_params.encodings = vec![
52 | RtpEncodingParameters {
53 | ssrc: Some(video.ssrc),
54 | ..RtpEncodingParameters::default()
55 | }
56 | ];
57 |
58 | producers.push(
59 | plain_transport.produce(
60 | ProducerOptions::new(MediaKind::Video, video_rtp_params)
61 | ).await.unwrap()
62 | );
63 | }
64 |
65 | // Initialise audio producer
66 | if let Some(audio) = &handshake.audio {
67 | let AudioCodec { mime_type, clock_rate, parameters, rtcp_feedback }
68 | = AudioCodec::from(&audio.codec);
69 |
70 | let mut audio_rtp_params = RtpParameters::default();
71 | audio_rtp_params.codecs = vec![
72 | RtpCodecParameters::Audio {
73 | mime_type,
74 | payload_type: audio.payload_type,
75 | clock_rate: NonZeroU32::new(clock_rate).unwrap(),
76 | channels: NonZeroU8::new(2).unwrap(),
77 | parameters,
78 | rtcp_feedback,
79 | }
80 | ];
81 |
82 | audio_rtp_params.encodings = vec![
83 | RtpEncodingParameters {
84 | ssrc: Some(audio.ssrc),
85 | ..RtpEncodingParameters::default()
86 | }
87 | ];
88 |
89 | producers.push(
90 | plain_transport.produce(
91 | ProducerOptions::new(MediaKind::Audio, audio_rtp_params)
92 | ).await.unwrap()
93 | );
94 | }
95 | }
96 | }
97 |
98 | return producers;
99 | }
100 |
--------------------------------------------------------------------------------
/crates/broadcast/src/rtc/routers.rs:
--------------------------------------------------------------------------------
1 | use std::net::SocketAddr;
2 |
3 | use mediasoup::router::{Router, RouterOptions};
4 | use mediasoup::producer::{Producer, ProducerId};
5 | use ftl_protocol::protocol::FtlHandshakeFinalised;
6 |
7 | use super::{codecs::init_codecs, workers::WorkerPool, producers::init_producers};
8 |
9 | #[derive(Clone)]
10 | pub enum DataSource {
11 | Ftl(FtlHandshakeFinalised)
12 | }
13 |
14 | #[derive(Clone)]
15 | pub struct HyperspeedRouter {
16 | pub router: Router,
17 | pub channel_id: String,
18 | pub producers: Vec,
19 | pub source: DataSource
20 | }
21 |
22 | impl HyperspeedRouter {
23 | pub async fn new(channel_id: String, source: DataSource, addr: SocketAddr) -> HyperspeedRouter {
24 | let mut options = RouterOptions::default();
25 | init_codecs(&mut options, &source);
26 |
27 | let router = WorkerPool::get()
28 | .get_worker()
29 | .create_router(options)
30 | .await
31 | .unwrap();
32 |
33 | let producers = init_producers(&router, &source, addr).await;
34 |
35 | HyperspeedRouter {
36 | router,
37 | channel_id,
38 | producers,
39 | source
40 | }
41 | }
42 |
43 | pub fn clone_router(&self) -> Router {
44 | self.router.clone()
45 | }
46 |
47 | pub fn get_producer_ids(&self) -> Vec {
48 | self.producers.iter()
49 | .map(|v| v.id().clone())
50 | .collect()
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/crates/broadcast/src/rtc/workers.rs:
--------------------------------------------------------------------------------
1 | use mediasoup::{worker::Worker, worker::WorkerSettings, worker_manager::WorkerManager};
2 | use once_cell::sync::OnceCell;
3 | use log::debug;
4 |
5 | static WORKER_POOL: OnceCell = OnceCell::new();
6 |
7 | // ! Worker pool taken from Vortex source code.
8 | // ! This is single-threaded, which is enough for now.
9 |
10 | #[derive(Debug)]
11 | pub struct WorkerPool {
12 | _manager: WorkerManager,
13 | worker: Worker,
14 | }
15 |
16 | impl WorkerPool {
17 | pub async fn init() {
18 | let worker_pool = WorkerPool::new().await;
19 | WORKER_POOL.set(worker_pool).unwrap();
20 | }
21 |
22 | pub fn get() -> &'static WorkerPool {
23 | WORKER_POOL
24 | .get()
25 | .expect("Mediasoup worker pool not initialized")
26 | }
27 |
28 | pub async fn new() -> Self {
29 | let manager = WorkerManager::new();
30 | let mut settings = WorkerSettings::default();
31 | // ! FIXME: hardcoded value
32 | settings.rtc_ports_range = 10100..=10200;
33 |
34 | let worker = manager.create_worker(settings).await.unwrap();
35 | debug!("Initialized worker pool");
36 | WorkerPool {
37 | _manager: manager,
38 | worker,
39 | }
40 | }
41 |
42 | pub fn get_worker(&self) -> &Worker {
43 | &self.worker
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/crates/broadcast/src/signaling/messages.rs:
--------------------------------------------------------------------------------
1 | use mediasoup::rtp_parameters::{MediaKind, RtpCapabilities, RtpCapabilitiesFinalized, RtpParameters};
2 | use mediasoup::data_structures::{DtlsParameters, IceCandidate, IceParameters};
3 | use mediasoup::transport::TransportId;
4 | use mediasoup::consumer::ConsumerId;
5 | use mediasoup::producer::ProducerId;
6 |
7 | use serde::{Serialize, Deserialize};
8 |
9 | #[derive(Serialize, Deserialize)]
10 | #[serde(rename_all = "camelCase")]
11 | pub struct TransportOptions {
12 | pub id: TransportId,
13 | pub dtls_parameters: DtlsParameters,
14 | pub ice_candidates: Vec,
15 | pub ice_parameters: IceParameters,
16 | }
17 |
18 | #[derive(Serialize, Deserialize)]
19 | #[serde(tag = "type")]
20 | pub enum ServerboundMessage {
21 | Begin {
22 | channel_id: String
23 | },
24 | Init {
25 | rtp_capabilities: RtpCapabilities
26 | },
27 | Connect {
28 | dtls_parameters: DtlsParameters
29 | },
30 | Consume,
31 | Resume {
32 | id: ConsumerId
33 | },
34 | PollConnectedViewers,
35 | }
36 |
37 | #[derive(Serialize, Deserialize)]
38 | #[serde(rename_all = "camelCase")]
39 | pub struct Consume {
40 | pub id: ConsumerId,
41 | pub producer_id: ProducerId,
42 | pub kind: MediaKind,
43 | pub rtp_parameters: RtpParameters
44 | }
45 |
46 | #[derive(Serialize, Deserialize)]
47 | #[serde(tag = "type")]
48 | pub enum ClientboundMessage {
49 | Init {
50 | producers: Vec,
51 | transport: TransportOptions,
52 | router_rtp_capabilities: RtpCapabilitiesFinalized
53 | },
54 | Connected,
55 | #[serde(rename_all = "camelCase")]
56 | Consuming {
57 | consume: Vec
58 | },
59 | ViewerCount {
60 | count: usize
61 | },
62 | }
63 |
--------------------------------------------------------------------------------
/crates/broadcast/src/signaling/mod.rs:
--------------------------------------------------------------------------------
1 | pub mod websocket;
2 | pub mod messages;
3 |
--------------------------------------------------------------------------------
/crates/broadcast/src/signaling/websocket.rs:
--------------------------------------------------------------------------------
1 | use std::collections::{HashMap, HashSet};
2 |
3 | use async_tungstenite::tungstenite::Message;
4 | use futures::{StreamExt, TryStreamExt, SinkExt};
5 | use async_std::{net::TcpListener, sync::RwLock};
6 | use mediasoup::{consumer::ConsumerOptions, data_structures::TransportListenIp, producer::ProducerId, router::Router, webrtc_transport::{TransportListenIps, WebRtcTransportOptions, WebRtcTransportRemoteParameters}};
7 | use mediasoup::transport::Transport;
8 | use async_trait::async_trait;
9 | use async_std::task;
10 | use log::info;
11 |
12 | use crate::signaling::messages::{ClientboundMessage, Consume, ServerboundMessage, TransportOptions};
13 |
14 | pub struct StreamInformation {
15 | pub router: Router,
16 | pub producers: Vec
17 | }
18 |
19 | lazy_static! {
20 | static ref VIEWERS: RwLock>> = RwLock::new(HashMap::new());
21 | }
22 |
23 | async fn viewers_start(channel: String, ip: String) {
24 | let mut viewers = VIEWERS.write().await;
25 | if !viewers.contains_key(&channel) {
26 | viewers.insert(channel.clone(), HashSet::new());
27 | }
28 |
29 | if let Some(set) = viewers.get_mut(&channel) {
30 | set.insert(ip);
31 | }
32 | }
33 |
34 | async fn viewers_stop(channel: String, ip: String) {
35 | let mut viewers = VIEWERS.write().await;
36 | if let Some(set) = viewers.get_mut(&channel) {
37 | set.remove(&ip);
38 | }
39 | }
40 |
41 | async fn viewers_count(channel: String) -> usize {
42 | VIEWERS.read().await.get(&channel).map(|x| x.len()).unwrap_or_else(|| 0)
43 | }
44 |
45 | #[async_trait]
46 | pub trait SignalingServer {
47 | async fn launch(&'static self, addr: &'static str, announced_ip: &'static str) {
48 | let try_socket = TcpListener::bind(addr).await;
49 | let listener = try_socket.expect("Failed to bind");
50 |
51 | while let Ok((stream, _)) = listener.accept().await {
52 | task::spawn_local(async move {
53 | let addr = stream.peer_addr().unwrap();
54 | let id = nanoid::nanoid!(32);
55 | info!("User connected: {addr} (assigned id {id})");
56 |
57 | let ws = async_tungstenite::accept_async(stream)
58 | .await.unwrap();
59 |
60 | let (mut write, mut read) = ws.split();
61 | let mut channel_id = None;
62 | 'outer: while let Ok(message) = read.try_next().await {
63 | if let Message::Text(text) = message.unwrap() {
64 | let msg: ServerboundMessage = serde_json::from_str(&text).unwrap();
65 | match msg {
66 | ServerboundMessage::Begin { channel_id: cid } => {
67 | channel_id = Some(cid);
68 | break 'outer;
69 | },
70 | _ => {}
71 | }
72 | }
73 | }
74 |
75 | let channel_id = channel_id.unwrap();
76 | let stream_info = self.get_stream(channel_id.clone()).await;
77 |
78 | if stream_info.is_none() {
79 | // ! FIXME: throw error; not live here
80 | dbg!("not live");
81 | return;
82 | }
83 |
84 | let StreamInformation { router, producers } = stream_info.unwrap();
85 | let transport_options =
86 | WebRtcTransportOptions::new(TransportListenIps::new(TransportListenIp {
87 | ip: "0.0.0.0".parse().unwrap(),
88 | announced_ip: Some(announced_ip.parse().unwrap()),
89 | }));
90 |
91 | let consumer_transport = router
92 | .create_webrtc_transport(transport_options)
93 | .await.unwrap();
94 |
95 | write.send(Message::Text(
96 | serde_json::to_string(&ClientboundMessage::Init {
97 | transport: TransportOptions {
98 | id: consumer_transport.id(),
99 | dtls_parameters: consumer_transport.dtls_parameters(),
100 | ice_candidates: consumer_transport.ice_candidates().clone(),
101 | ice_parameters: consumer_transport.ice_parameters().clone()
102 | },
103 | router_rtp_capabilities: router.rtp_capabilities().clone(),
104 | producers: producers.clone()
105 | })
106 | .unwrap()
107 | ))
108 | .await.unwrap();
109 |
110 | // Client data
111 | let mut consumers = HashMap::new();
112 | let mut client_rtp_capabilities = None;
113 |
114 | 'disconnect: while let Ok(Some(message)) = read.try_next().await {
115 | if let Message::Text(text) = message {
116 | if let Ok(msg) = serde_json::from_str(&text) {
117 | match msg {
118 | ServerboundMessage::Begin { .. } => {},
119 | ServerboundMessage::Init { rtp_capabilities } => {
120 | client_rtp_capabilities = Some(rtp_capabilities);
121 | },
122 | ServerboundMessage::Connect { dtls_parameters } => {
123 | if consumer_transport
124 | .connect(WebRtcTransportRemoteParameters { dtls_parameters })
125 | .await
126 | .is_err() {
127 | break 'disconnect;
128 | }
129 |
130 | if write.send(Message::Text(
131 | serde_json::to_string(&ClientboundMessage::Connected)
132 | .unwrap()
133 | ))
134 | .await
135 | .is_err() {
136 | break 'disconnect;
137 | }
138 |
139 | viewers_start(channel_id.clone(), id.clone()).await;
140 | },
141 | ServerboundMessage::Consume => {
142 | let mut consume = vec![];
143 | for producer_id in &producers {
144 | let rtp_capabilities = client_rtp_capabilities.as_ref().unwrap();
145 | let mut options = ConsumerOptions::new(*producer_id, rtp_capabilities.clone());
146 | options.paused = true;
147 |
148 | let consumer = consumer_transport.consume(options).await.unwrap();
149 |
150 | let id = consumer.id();
151 | let kind = consumer.kind();
152 | let rtp_parameters = consumer.rtp_parameters().clone();
153 |
154 | consumers.insert(id, consumer);
155 | consume.push(Consume {
156 | id,
157 | producer_id: *producer_id,
158 | kind,
159 | rtp_parameters
160 | });
161 | }
162 |
163 | write.send(Message::Text(
164 | serde_json::to_string(&ClientboundMessage::Consuming {
165 | consume
166 | })
167 | .unwrap()
168 | ))
169 | .await.unwrap();
170 | },
171 | ServerboundMessage::Resume { id } => {
172 | if let Some(consumer) = consumers.get(&id).cloned() {
173 | consumer.resume().await.unwrap();
174 | }
175 | },
176 | ServerboundMessage::PollConnectedViewers => {
177 | write.send(Message::Text(
178 | serde_json::to_string(&ClientboundMessage::ViewerCount {
179 | count: viewers_count(channel_id.clone()).await
180 | })
181 | .unwrap()
182 | ))
183 | .await.unwrap();
184 | }
185 | }
186 | } else {
187 | break 'disconnect
188 | }
189 | }
190 | }
191 |
192 | viewers_stop(channel_id.clone(), id.clone()).await;
193 | });
194 | }
195 | }
196 |
197 | async fn get_stream(&self, channel_id: String) -> Option;
198 | }
199 |
--------------------------------------------------------------------------------
/crates/ftl/Cargo.lock:
--------------------------------------------------------------------------------
1 | # This file is automatically @generated by Cargo.
2 | # It is not intended for manual editing.
3 | version = 3
4 |
5 | [[package]]
6 | name = "async-attributes"
7 | version = "1.1.2"
8 | source = "registry+https://github.com/rust-lang/crates.io-index"
9 | checksum = "a3203e79f4dd9bdda415ed03cf14dae5a2bf775c683a00f94e9cd1faf0f596e5"
10 | dependencies = [
11 | "quote",
12 | "syn",
13 | ]
14 |
15 | [[package]]
16 | name = "async-channel"
17 | version = "1.6.1"
18 | source = "registry+https://github.com/rust-lang/crates.io-index"
19 | checksum = "2114d64672151c0c5eaa5e131ec84a74f06e1e559830dabba01ca30605d66319"
20 | dependencies = [
21 | "concurrent-queue",
22 | "event-listener",
23 | "futures-core",
24 | ]
25 |
26 | [[package]]
27 | name = "async-executor"
28 | version = "1.4.1"
29 | source = "registry+https://github.com/rust-lang/crates.io-index"
30 | checksum = "871f9bb5e0a22eeb7e8cf16641feb87c9dc67032ccf8ff49e772eb9941d3a965"
31 | dependencies = [
32 | "async-task",
33 | "concurrent-queue",
34 | "fastrand",
35 | "futures-lite",
36 | "once_cell",
37 | "slab",
38 | ]
39 |
40 | [[package]]
41 | name = "async-global-executor"
42 | version = "2.0.2"
43 | source = "registry+https://github.com/rust-lang/crates.io-index"
44 | checksum = "9586ec52317f36de58453159d48351bc244bc24ced3effc1fce22f3d48664af6"
45 | dependencies = [
46 | "async-channel",
47 | "async-executor",
48 | "async-io",
49 | "async-mutex",
50 | "blocking",
51 | "futures-lite",
52 | "num_cpus",
53 | "once_cell",
54 | ]
55 |
56 | [[package]]
57 | name = "async-io"
58 | version = "1.6.0"
59 | source = "registry+https://github.com/rust-lang/crates.io-index"
60 | checksum = "a811e6a479f2439f0c04038796b5cfb3d2ad56c230e0f2d3f7b04d68cfee607b"
61 | dependencies = [
62 | "concurrent-queue",
63 | "futures-lite",
64 | "libc",
65 | "log",
66 | "once_cell",
67 | "parking",
68 | "polling",
69 | "slab",
70 | "socket2",
71 | "waker-fn",
72 | "winapi",
73 | ]
74 |
75 | [[package]]
76 | name = "async-lock"
77 | version = "2.4.0"
78 | source = "registry+https://github.com/rust-lang/crates.io-index"
79 | checksum = "e6a8ea61bf9947a1007c5cada31e647dbc77b103c679858150003ba697ea798b"
80 | dependencies = [
81 | "event-listener",
82 | ]
83 |
84 | [[package]]
85 | name = "async-mutex"
86 | version = "1.4.0"
87 | source = "registry+https://github.com/rust-lang/crates.io-index"
88 | checksum = "479db852db25d9dbf6204e6cb6253698f175c15726470f78af0d918e99d6156e"
89 | dependencies = [
90 | "event-listener",
91 | ]
92 |
93 | [[package]]
94 | name = "async-std"
95 | version = "1.9.0"
96 | source = "registry+https://github.com/rust-lang/crates.io-index"
97 | checksum = "d9f06685bad74e0570f5213741bea82158279a4103d988e57bfada11ad230341"
98 | dependencies = [
99 | "async-attributes",
100 | "async-channel",
101 | "async-global-executor",
102 | "async-io",
103 | "async-lock",
104 | "crossbeam-utils",
105 | "futures-channel",
106 | "futures-core",
107 | "futures-io",
108 | "futures-lite",
109 | "gloo-timers",
110 | "kv-log-macro",
111 | "log",
112 | "memchr",
113 | "num_cpus",
114 | "once_cell",
115 | "pin-project-lite",
116 | "pin-utils",
117 | "slab",
118 | "wasm-bindgen-futures",
119 | ]
120 |
121 | [[package]]
122 | name = "async-task"
123 | version = "4.0.3"
124 | source = "registry+https://github.com/rust-lang/crates.io-index"
125 | checksum = "e91831deabf0d6d7ec49552e489aed63b7456a7a3c46cff62adad428110b0af0"
126 |
127 | [[package]]
128 | name = "async-trait"
129 | version = "0.1.50"
130 | source = "registry+https://github.com/rust-lang/crates.io-index"
131 | checksum = "0b98e84bbb4cbcdd97da190ba0c58a1bb0de2c1fdf67d159e192ed766aeca722"
132 | dependencies = [
133 | "proc-macro2",
134 | "quote",
135 | "syn",
136 | ]
137 |
138 | [[package]]
139 | name = "atomic-waker"
140 | version = "1.0.0"
141 | source = "registry+https://github.com/rust-lang/crates.io-index"
142 | checksum = "065374052e7df7ee4047b1160cca5e1467a12351a40b3da123c870ba0b8eda2a"
143 |
144 | [[package]]
145 | name = "blocking"
146 | version = "1.0.2"
147 | source = "registry+https://github.com/rust-lang/crates.io-index"
148 | checksum = "c5e170dbede1f740736619b776d7251cb1b9095c435c34d8ca9f57fcd2f335e9"
149 | dependencies = [
150 | "async-channel",
151 | "async-task",
152 | "atomic-waker",
153 | "fastrand",
154 | "futures-lite",
155 | "once_cell",
156 | ]
157 |
158 | [[package]]
159 | name = "bumpalo"
160 | version = "3.7.0"
161 | source = "registry+https://github.com/rust-lang/crates.io-index"
162 | checksum = "9c59e7af012c713f529e7a3ee57ce9b31ddd858d4b512923602f74608b009631"
163 |
164 | [[package]]
165 | name = "cache-padded"
166 | version = "1.1.1"
167 | source = "registry+https://github.com/rust-lang/crates.io-index"
168 | checksum = "631ae5198c9be5e753e5cc215e1bd73c2b466a3565173db433f52bb9d3e66dba"
169 |
170 | [[package]]
171 | name = "cc"
172 | version = "1.0.69"
173 | source = "registry+https://github.com/rust-lang/crates.io-index"
174 | checksum = "e70cc2f62c6ce1868963827bd677764c62d07c3d9a3e1fb1177ee1a9ab199eb2"
175 |
176 | [[package]]
177 | name = "cfg-if"
178 | version = "1.0.0"
179 | source = "registry+https://github.com/rust-lang/crates.io-index"
180 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
181 |
182 | [[package]]
183 | name = "concurrent-queue"
184 | version = "1.2.2"
185 | source = "registry+https://github.com/rust-lang/crates.io-index"
186 | checksum = "30ed07550be01594c6026cff2a1d7fe9c8f683caa798e12b68694ac9e88286a3"
187 | dependencies = [
188 | "cache-padded",
189 | ]
190 |
191 | [[package]]
192 | name = "crossbeam-utils"
193 | version = "0.8.5"
194 | source = "registry+https://github.com/rust-lang/crates.io-index"
195 | checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db"
196 | dependencies = [
197 | "cfg-if",
198 | "lazy_static",
199 | ]
200 |
201 | [[package]]
202 | name = "ctor"
203 | version = "0.1.20"
204 | source = "registry+https://github.com/rust-lang/crates.io-index"
205 | checksum = "5e98e2ad1a782e33928b96fc3948e7c355e5af34ba4de7670fe8bac2a3b2006d"
206 | dependencies = [
207 | "quote",
208 | "syn",
209 | ]
210 |
211 | [[package]]
212 | name = "event-listener"
213 | version = "2.5.1"
214 | source = "registry+https://github.com/rust-lang/crates.io-index"
215 | checksum = "f7531096570974c3a9dcf9e4b8e1cede1ec26cf5046219fb3b9d897503b9be59"
216 |
217 | [[package]]
218 | name = "fastrand"
219 | version = "1.4.1"
220 | source = "registry+https://github.com/rust-lang/crates.io-index"
221 | checksum = "77b705829d1e87f762c2df6da140b26af5839e1033aa84aa5f56bb688e4e1bdb"
222 | dependencies = [
223 | "instant",
224 | ]
225 |
226 | [[package]]
227 | name = "ftl-protocol"
228 | version = "0.0.6"
229 | dependencies = [
230 | "async-std",
231 | "async-trait",
232 | "hex",
233 | "log",
234 | "rand",
235 | "ring",
236 | ]
237 |
238 | [[package]]
239 | name = "futures-channel"
240 | version = "0.3.15"
241 | source = "registry+https://github.com/rust-lang/crates.io-index"
242 | checksum = "e682a68b29a882df0545c143dc3646daefe80ba479bcdede94d5a703de2871e2"
243 | dependencies = [
244 | "futures-core",
245 | ]
246 |
247 | [[package]]
248 | name = "futures-core"
249 | version = "0.3.15"
250 | source = "registry+https://github.com/rust-lang/crates.io-index"
251 | checksum = "0402f765d8a89a26043b889b26ce3c4679d268fa6bb22cd7c6aad98340e179d1"
252 |
253 | [[package]]
254 | name = "futures-io"
255 | version = "0.3.15"
256 | source = "registry+https://github.com/rust-lang/crates.io-index"
257 | checksum = "acc499defb3b348f8d8f3f66415835a9131856ff7714bf10dadfc4ec4bdb29a1"
258 |
259 | [[package]]
260 | name = "futures-lite"
261 | version = "1.12.0"
262 | source = "registry+https://github.com/rust-lang/crates.io-index"
263 | checksum = "7694489acd39452c77daa48516b894c153f192c3578d5a839b62c58099fcbf48"
264 | dependencies = [
265 | "fastrand",
266 | "futures-core",
267 | "futures-io",
268 | "memchr",
269 | "parking",
270 | "pin-project-lite",
271 | "waker-fn",
272 | ]
273 |
274 | [[package]]
275 | name = "getrandom"
276 | version = "0.2.3"
277 | source = "registry+https://github.com/rust-lang/crates.io-index"
278 | checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753"
279 | dependencies = [
280 | "cfg-if",
281 | "libc",
282 | "wasi",
283 | ]
284 |
285 | [[package]]
286 | name = "gloo-timers"
287 | version = "0.2.1"
288 | source = "registry+https://github.com/rust-lang/crates.io-index"
289 | checksum = "47204a46aaff920a1ea58b11d03dec6f704287d27561724a4631e450654a891f"
290 | dependencies = [
291 | "futures-channel",
292 | "futures-core",
293 | "js-sys",
294 | "wasm-bindgen",
295 | "web-sys",
296 | ]
297 |
298 | [[package]]
299 | name = "hermit-abi"
300 | version = "0.1.19"
301 | source = "registry+https://github.com/rust-lang/crates.io-index"
302 | checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
303 | dependencies = [
304 | "libc",
305 | ]
306 |
307 | [[package]]
308 | name = "hex"
309 | version = "0.4.3"
310 | source = "registry+https://github.com/rust-lang/crates.io-index"
311 | checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
312 |
313 | [[package]]
314 | name = "instant"
315 | version = "0.1.10"
316 | source = "registry+https://github.com/rust-lang/crates.io-index"
317 | checksum = "bee0328b1209d157ef001c94dd85b4f8f64139adb0eac2659f4b08382b2f474d"
318 | dependencies = [
319 | "cfg-if",
320 | ]
321 |
322 | [[package]]
323 | name = "js-sys"
324 | version = "0.3.51"
325 | source = "registry+https://github.com/rust-lang/crates.io-index"
326 | checksum = "83bdfbace3a0e81a4253f73b49e960b053e396a11012cbd49b9b74d6a2b67062"
327 | dependencies = [
328 | "wasm-bindgen",
329 | ]
330 |
331 | [[package]]
332 | name = "kv-log-macro"
333 | version = "1.0.7"
334 | source = "registry+https://github.com/rust-lang/crates.io-index"
335 | checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f"
336 | dependencies = [
337 | "log",
338 | ]
339 |
340 | [[package]]
341 | name = "lazy_static"
342 | version = "1.4.0"
343 | source = "registry+https://github.com/rust-lang/crates.io-index"
344 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
345 |
346 | [[package]]
347 | name = "libc"
348 | version = "0.2.98"
349 | source = "registry+https://github.com/rust-lang/crates.io-index"
350 | checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790"
351 |
352 | [[package]]
353 | name = "log"
354 | version = "0.4.14"
355 | source = "registry+https://github.com/rust-lang/crates.io-index"
356 | checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
357 | dependencies = [
358 | "cfg-if",
359 | "value-bag",
360 | ]
361 |
362 | [[package]]
363 | name = "memchr"
364 | version = "2.4.0"
365 | source = "registry+https://github.com/rust-lang/crates.io-index"
366 | checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc"
367 |
368 | [[package]]
369 | name = "num_cpus"
370 | version = "1.13.0"
371 | source = "registry+https://github.com/rust-lang/crates.io-index"
372 | checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3"
373 | dependencies = [
374 | "hermit-abi",
375 | "libc",
376 | ]
377 |
378 | [[package]]
379 | name = "once_cell"
380 | version = "1.8.0"
381 | source = "registry+https://github.com/rust-lang/crates.io-index"
382 | checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56"
383 |
384 | [[package]]
385 | name = "parking"
386 | version = "2.0.0"
387 | source = "registry+https://github.com/rust-lang/crates.io-index"
388 | checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72"
389 |
390 | [[package]]
391 | name = "pin-project-lite"
392 | version = "0.2.7"
393 | source = "registry+https://github.com/rust-lang/crates.io-index"
394 | checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443"
395 |
396 | [[package]]
397 | name = "pin-utils"
398 | version = "0.1.0"
399 | source = "registry+https://github.com/rust-lang/crates.io-index"
400 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
401 |
402 | [[package]]
403 | name = "polling"
404 | version = "2.1.0"
405 | source = "registry+https://github.com/rust-lang/crates.io-index"
406 | checksum = "92341d779fa34ea8437ef4d82d440d5e1ce3f3ff7f824aa64424cd481f9a1f25"
407 | dependencies = [
408 | "cfg-if",
409 | "libc",
410 | "log",
411 | "wepoll-ffi",
412 | "winapi",
413 | ]
414 |
415 | [[package]]
416 | name = "ppv-lite86"
417 | version = "0.2.10"
418 | source = "registry+https://github.com/rust-lang/crates.io-index"
419 | checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
420 |
421 | [[package]]
422 | name = "proc-macro2"
423 | version = "1.0.27"
424 | source = "registry+https://github.com/rust-lang/crates.io-index"
425 | checksum = "f0d8caf72986c1a598726adc988bb5984792ef84f5ee5aa50209145ee8077038"
426 | dependencies = [
427 | "unicode-xid",
428 | ]
429 |
430 | [[package]]
431 | name = "quote"
432 | version = "1.0.9"
433 | source = "registry+https://github.com/rust-lang/crates.io-index"
434 | checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
435 | dependencies = [
436 | "proc-macro2",
437 | ]
438 |
439 | [[package]]
440 | name = "rand"
441 | version = "0.8.4"
442 | source = "registry+https://github.com/rust-lang/crates.io-index"
443 | checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8"
444 | dependencies = [
445 | "libc",
446 | "rand_chacha",
447 | "rand_core",
448 | "rand_hc",
449 | ]
450 |
451 | [[package]]
452 | name = "rand_chacha"
453 | version = "0.3.1"
454 | source = "registry+https://github.com/rust-lang/crates.io-index"
455 | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
456 | dependencies = [
457 | "ppv-lite86",
458 | "rand_core",
459 | ]
460 |
461 | [[package]]
462 | name = "rand_core"
463 | version = "0.6.3"
464 | source = "registry+https://github.com/rust-lang/crates.io-index"
465 | checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
466 | dependencies = [
467 | "getrandom",
468 | ]
469 |
470 | [[package]]
471 | name = "rand_hc"
472 | version = "0.3.1"
473 | source = "registry+https://github.com/rust-lang/crates.io-index"
474 | checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7"
475 | dependencies = [
476 | "rand_core",
477 | ]
478 |
479 | [[package]]
480 | name = "ring"
481 | version = "0.16.20"
482 | source = "registry+https://github.com/rust-lang/crates.io-index"
483 | checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc"
484 | dependencies = [
485 | "cc",
486 | "libc",
487 | "once_cell",
488 | "spin",
489 | "untrusted",
490 | "web-sys",
491 | "winapi",
492 | ]
493 |
494 | [[package]]
495 | name = "slab"
496 | version = "0.4.3"
497 | source = "registry+https://github.com/rust-lang/crates.io-index"
498 | checksum = "f173ac3d1a7e3b28003f40de0b5ce7fe2710f9b9dc3fc38664cebee46b3b6527"
499 |
500 | [[package]]
501 | name = "socket2"
502 | version = "0.4.0"
503 | source = "registry+https://github.com/rust-lang/crates.io-index"
504 | checksum = "9e3dfc207c526015c632472a77be09cf1b6e46866581aecae5cc38fb4235dea2"
505 | dependencies = [
506 | "libc",
507 | "winapi",
508 | ]
509 |
510 | [[package]]
511 | name = "spin"
512 | version = "0.5.2"
513 | source = "registry+https://github.com/rust-lang/crates.io-index"
514 | checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
515 |
516 | [[package]]
517 | name = "syn"
518 | version = "1.0.73"
519 | source = "registry+https://github.com/rust-lang/crates.io-index"
520 | checksum = "f71489ff30030d2ae598524f61326b902466f72a0fb1a8564c001cc63425bcc7"
521 | dependencies = [
522 | "proc-macro2",
523 | "quote",
524 | "unicode-xid",
525 | ]
526 |
527 | [[package]]
528 | name = "unicode-xid"
529 | version = "0.2.2"
530 | source = "registry+https://github.com/rust-lang/crates.io-index"
531 | checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
532 |
533 | [[package]]
534 | name = "untrusted"
535 | version = "0.7.1"
536 | source = "registry+https://github.com/rust-lang/crates.io-index"
537 | checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
538 |
539 | [[package]]
540 | name = "value-bag"
541 | version = "1.0.0-alpha.7"
542 | source = "registry+https://github.com/rust-lang/crates.io-index"
543 | checksum = "dd320e1520f94261153e96f7534476ad869c14022aee1e59af7c778075d840ae"
544 | dependencies = [
545 | "ctor",
546 | "version_check",
547 | ]
548 |
549 | [[package]]
550 | name = "version_check"
551 | version = "0.9.3"
552 | source = "registry+https://github.com/rust-lang/crates.io-index"
553 | checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
554 |
555 | [[package]]
556 | name = "waker-fn"
557 | version = "1.1.0"
558 | source = "registry+https://github.com/rust-lang/crates.io-index"
559 | checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca"
560 |
561 | [[package]]
562 | name = "wasi"
563 | version = "0.10.2+wasi-snapshot-preview1"
564 | source = "registry+https://github.com/rust-lang/crates.io-index"
565 | checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
566 |
567 | [[package]]
568 | name = "wasm-bindgen"
569 | version = "0.2.74"
570 | source = "registry+https://github.com/rust-lang/crates.io-index"
571 | checksum = "d54ee1d4ed486f78874278e63e4069fc1ab9f6a18ca492076ffb90c5eb2997fd"
572 | dependencies = [
573 | "cfg-if",
574 | "wasm-bindgen-macro",
575 | ]
576 |
577 | [[package]]
578 | name = "wasm-bindgen-backend"
579 | version = "0.2.74"
580 | source = "registry+https://github.com/rust-lang/crates.io-index"
581 | checksum = "3b33f6a0694ccfea53d94db8b2ed1c3a8a4c86dd936b13b9f0a15ec4a451b900"
582 | dependencies = [
583 | "bumpalo",
584 | "lazy_static",
585 | "log",
586 | "proc-macro2",
587 | "quote",
588 | "syn",
589 | "wasm-bindgen-shared",
590 | ]
591 |
592 | [[package]]
593 | name = "wasm-bindgen-futures"
594 | version = "0.4.24"
595 | source = "registry+https://github.com/rust-lang/crates.io-index"
596 | checksum = "5fba7978c679d53ce2d0ac80c8c175840feb849a161664365d1287b41f2e67f1"
597 | dependencies = [
598 | "cfg-if",
599 | "js-sys",
600 | "wasm-bindgen",
601 | "web-sys",
602 | ]
603 |
604 | [[package]]
605 | name = "wasm-bindgen-macro"
606 | version = "0.2.74"
607 | source = "registry+https://github.com/rust-lang/crates.io-index"
608 | checksum = "088169ca61430fe1e58b8096c24975251700e7b1f6fd91cc9d59b04fb9b18bd4"
609 | dependencies = [
610 | "quote",
611 | "wasm-bindgen-macro-support",
612 | ]
613 |
614 | [[package]]
615 | name = "wasm-bindgen-macro-support"
616 | version = "0.2.74"
617 | source = "registry+https://github.com/rust-lang/crates.io-index"
618 | checksum = "be2241542ff3d9f241f5e2cb6dd09b37efe786df8851c54957683a49f0987a97"
619 | dependencies = [
620 | "proc-macro2",
621 | "quote",
622 | "syn",
623 | "wasm-bindgen-backend",
624 | "wasm-bindgen-shared",
625 | ]
626 |
627 | [[package]]
628 | name = "wasm-bindgen-shared"
629 | version = "0.2.74"
630 | source = "registry+https://github.com/rust-lang/crates.io-index"
631 | checksum = "d7cff876b8f18eed75a66cf49b65e7f967cb354a7aa16003fb55dbfd25b44b4f"
632 |
633 | [[package]]
634 | name = "web-sys"
635 | version = "0.3.51"
636 | source = "registry+https://github.com/rust-lang/crates.io-index"
637 | checksum = "e828417b379f3df7111d3a2a9e5753706cae29c41f7c4029ee9fd77f3e09e582"
638 | dependencies = [
639 | "js-sys",
640 | "wasm-bindgen",
641 | ]
642 |
643 | [[package]]
644 | name = "wepoll-ffi"
645 | version = "0.1.2"
646 | source = "registry+https://github.com/rust-lang/crates.io-index"
647 | checksum = "d743fdedc5c64377b5fc2bc036b01c7fd642205a0d96356034ae3404d49eb7fb"
648 | dependencies = [
649 | "cc",
650 | ]
651 |
652 | [[package]]
653 | name = "winapi"
654 | version = "0.3.9"
655 | source = "registry+https://github.com/rust-lang/crates.io-index"
656 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
657 | dependencies = [
658 | "winapi-i686-pc-windows-gnu",
659 | "winapi-x86_64-pc-windows-gnu",
660 | ]
661 |
662 | [[package]]
663 | name = "winapi-i686-pc-windows-gnu"
664 | version = "0.4.0"
665 | source = "registry+https://github.com/rust-lang/crates.io-index"
666 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
667 |
668 | [[package]]
669 | name = "winapi-x86_64-pc-windows-gnu"
670 | version = "0.4.0"
671 | source = "registry+https://github.com/rust-lang/crates.io-index"
672 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
673 |
--------------------------------------------------------------------------------
/crates/ftl/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "ftl-protocol"
3 | description = "Common data structures for working with the Faster Than Light protocol as well as an optional FTL ingest control server."
4 | homepage = "https://hyperspeed.cli.rs"
5 | documentation = "https://hyperspeed.cli.rs/components/ftl"
6 | repository = "https://github.com/insertish/project-hyperspeed"
7 | version = "0.0.6"
8 | license = "MIT"
9 | edition = "2018"
10 |
11 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
12 |
13 | [features]
14 | server = [ "log", "async-trait", "async-std", "util" ]
15 | util = [ "ring", "rand", "hex" ]
16 | default = [ "server" ]
17 |
18 | [dependencies]
19 | # server only
20 | log = { version = "0.4", optional = true }
21 | async-trait = { version = "0.1.50", optional = true }
22 | async-std = { version = "1.8.0", features = ["attributes"], optional = true }
23 |
24 | # util only
25 | ring = { version = "0.16.20", optional = true }
26 | rand = { version = "0.8.4", optional = true }
27 | hex = { version = "0.4.3", optional = true }
28 |
29 | [package.metadata.docs.rs]
30 | all-features = true
31 | rustc-args = ["--cfg", "docsrs"]
32 | rustdoc-args = ["--cfg", "docsrs"]
33 |
--------------------------------------------------------------------------------
/crates/ftl/README.md:
--------------------------------------------------------------------------------
1 | # FTL Protocol
2 |
3 | [ftl-protocol](https://gitlab.insrt.uk/insert/project-hyperspeed/-/tree/master/crates/ftl) provides common data structures for working with FTL as well as an optional FTL ingest control server.
4 |
5 | ## [Documentation](https://hyperspeed.cli.rs/components/ftl)
6 |
--------------------------------------------------------------------------------
/crates/ftl/src/lib.rs:
--------------------------------------------------------------------------------
1 | #![cfg_attr(docsrs, feature(doc_cfg))]
2 |
3 | pub mod protocol;
4 |
5 | #[cfg(feature = "server")]
6 | #[cfg_attr(docsrs, doc(cfg(feature = "server")))]
7 | pub mod server;
8 |
9 | #[cfg(feature = "util")]
10 | #[cfg_attr(docsrs, doc(cfg(feature = "util")))]
11 | pub mod util;
12 |
--------------------------------------------------------------------------------
/crates/ftl/src/protocol/command.rs:
--------------------------------------------------------------------------------
1 | use std::str::FromStr;
2 |
3 | use super::FtlError;
4 |
5 | #[derive(Debug, PartialEq)]
6 | pub enum FtlCommand {
7 | HMAC,
8 | Connect {
9 | channel_id: String,
10 | hashed_hmac_payload: String,
11 | },
12 | Dot,
13 | Attribute {
14 | key: String,
15 | value: String,
16 | },
17 | Ping {
18 | channel_id: String,
19 | },
20 | Disconnect,
21 | }
22 |
23 | impl FromStr for FtlCommand {
24 | type Err = FtlError;
25 |
26 | fn from_str(s: &str) -> Result {
27 | match s {
28 | "HMAC" => Ok(FtlCommand::HMAC),
29 | "." => Ok(FtlCommand::Dot),
30 | "DISCONNECT" => Ok(FtlCommand::Disconnect),
31 | s => {
32 | if &s[..4] == "PING" {
33 | Ok(FtlCommand::Ping {
34 | channel_id: s[5..].to_string(),
35 | })
36 | } else if &s[..7] == "CONNECT" {
37 | let parts = &mut s[8..].split(" ");
38 |
39 | Ok(FtlCommand::Connect {
40 | channel_id: parts
41 | .next()
42 | .ok_or_else(|| FtlError::MissingPart)?
43 | .to_string(),
44 | hashed_hmac_payload: parts
45 | .next()
46 | .ok_or_else(|| FtlError::MissingPart)?
47 | .to_string(),
48 | })
49 | } else {
50 | if s.contains(':') {
51 | let mut parts = s.split(':').map(|v| v.trim());
52 |
53 | return Ok(FtlCommand::Attribute {
54 | key: parts
55 | .next()
56 | .ok_or_else(|| FtlError::MissingPart)?
57 | .to_string(),
58 | value: parts
59 | .next()
60 | .ok_or_else(|| FtlError::MissingPart)?
61 | .to_string(),
62 | });
63 | }
64 |
65 | Err(FtlError::UnimplementedCommand)
66 | }
67 | }
68 | }
69 | }
70 | }
71 |
72 | #[cfg(test)]
73 | mod tests {
74 | use std::str::FromStr;
75 |
76 | use crate::protocol::FtlCommand;
77 |
78 | #[test]
79 | fn should_parse_hmac() {
80 | let command = FtlCommand::from_str("HMAC").unwrap();
81 | assert_eq!(command, FtlCommand::HMAC);
82 | }
83 |
84 | #[test]
85 | fn should_parse_dot() {
86 | let command = FtlCommand::from_str(".").unwrap();
87 | assert_eq!(command, FtlCommand::Dot);
88 | }
89 |
90 | #[test]
91 | fn should_parse_disconnect() {
92 | let command = FtlCommand::from_str("DISCONNECT").unwrap();
93 | assert_eq!(command, FtlCommand::Disconnect);
94 | }
95 |
96 | #[test]
97 | fn should_parse_ping() {
98 | let command = FtlCommand::from_str("PING channel_id").unwrap();
99 | assert_eq!(command, FtlCommand::Ping { channel_id: "channel_id".to_string() });
100 | }
101 |
102 | #[test]
103 | fn should_parse_connect() {
104 | let command = FtlCommand::from_str("CONNECT channel_id hmac").unwrap();
105 | assert_eq!(command, FtlCommand::Connect { channel_id: "channel_id".to_string(), hashed_hmac_payload: "hmac".to_string() });
106 | }
107 |
108 | #[test]
109 | fn should_parse_attribute() {
110 | let command = FtlCommand::from_str("ProtocolVersion: 0.9").unwrap();
111 | assert_eq!(command, FtlCommand::Attribute { key: "ProtocolVersion".to_string(), value: "0.9".to_string() });
112 | }
113 |
114 | #[test]
115 | fn should_fail_other() {
116 | let command = FtlCommand::from_str("i am invalid data");
117 | assert!(command.is_err())
118 | }
119 |
120 | #[test]
121 | fn doc_test() {
122 | use crate::protocol::FtlCommand;
123 |
124 | let command = FtlCommand::from_str(".").unwrap();
125 | assert_eq!(command, FtlCommand::Dot);
126 |
127 | let command = FtlCommand::from_str("PING 123").unwrap();
128 | assert_eq!(command, FtlCommand::Ping {
129 | channel_id: "123".to_string()
130 | });
131 | }
132 | }
133 |
--------------------------------------------------------------------------------
/crates/ftl/src/protocol/error.rs:
--------------------------------------------------------------------------------
1 | use std::string::ToString;
2 |
3 | #[derive(Debug)]
4 | pub enum FtlError {
5 | IoError,
6 | AllocateError,
7 | RingError,
8 | DecodeError,
9 | MissingPart,
10 |
11 | InvalidStreamKey, // applies to channel id as well
12 | ChannelNotAuthorized,
13 | ChannelInUse,
14 | UnsupportedRegion,
15 | GameBlocked,
16 |
17 | InvalidProtocolVersion,
18 | UnsupportedProtocolVersion,
19 | MissingCodecInformation,
20 | UnimplementedCommand,
21 |
22 | Disconnect,
23 | }
24 |
25 | impl FtlError {
26 | pub fn is_err(&self) -> bool {
27 | match self {
28 | FtlError::Disconnect => false,
29 | _ => true
30 | }
31 | }
32 | }
33 |
34 | impl ToString for FtlError {
35 | fn to_string(&self) -> String {
36 | match self {
37 | FtlError::IoError => "500 Internal Server Error\n".to_string(),
38 | FtlError::AllocateError => "500 Internal Server Error\n".to_string(),
39 | FtlError::RingError => "400 HMAC Decode Error\n".to_string(),
40 | FtlError::DecodeError => "400 HMAC Decode Error\n".to_string(),
41 | FtlError::MissingPart => "400 Bad Request\n".to_string(),
42 |
43 | FtlError::InvalidStreamKey => "405 Invalid stream key\n".to_string(),
44 | FtlError::ChannelNotAuthorized => "401 Channel not authorized to stream\n".to_string(),
45 | FtlError::ChannelInUse => "406 Channel actively streaming\n".to_string(),
46 | FtlError::UnsupportedRegion => "407 Streaming from your region is not authorized\n".to_string(),
47 | FtlError::GameBlocked => "409 Channel is not allowed to stream set game\n".to_string(),
48 |
49 | FtlError::InvalidProtocolVersion => "400 Invalid Protocol Version\n".to_string(),
50 | FtlError::UnsupportedProtocolVersion => "402 Outdated FTL SDK version\n".to_string(),
51 | FtlError::MissingCodecInformation => "400 Missing Codec Information\n".to_string(),
52 | FtlError::UnimplementedCommand => "901 Invalid Command\n".to_string(),
53 | _ => "".to_string(),
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/crates/ftl/src/protocol/handshake.rs:
--------------------------------------------------------------------------------
1 | use super::FtlError;
2 |
3 | #[derive(Default, Debug, Clone)]
4 | pub struct Vendor {
5 | pub name: Option,
6 | pub version: Option,
7 | }
8 |
9 | #[derive(Default, Debug, Clone)]
10 | pub struct Video {
11 | pub codec: Option,
12 | pub height: Option,
13 | pub width: Option,
14 | pub payload_type: Option,
15 | pub ssrc: Option,
16 | }
17 |
18 | #[derive(Default, Debug, Clone)]
19 | pub struct Audio {
20 | pub codec: Option,
21 | pub payload_type: Option,
22 | pub ssrc: Option,
23 | }
24 |
25 | #[derive(Default, Debug, Clone)]
26 | pub struct FtlHandshake {
27 | pub protocol_version: Option<(isize, isize)>,
28 | pub vendor: Vendor,
29 | pub video: Option