diff --git a/Cargo.lock b/Cargo.lock index 0c34d35a..9c487af2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,25 +17,6 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" -[[package]] -name = "aead" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fc95d1bdb8e6666b2b217308eeeb09f2d6728d104be3e31916cc74d15420331" -dependencies = [ - "generic-array", -] - -[[package]] -name = "aead" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b613b8e1e3cf911a086f53f03bf286f52fd7a7258e4fa606f0ef220d39d8877" -dependencies = [ - "generic-array", - "rand_core", -] - [[package]] name = "aead" version = "0.5.2" @@ -46,37 +27,14 @@ dependencies = [ "generic-array", ] -[[package]] -name = "aes" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "884391ef1066acaa41e766ba8f596341b96e93ce34f9a43e7d24bf0a0eaf0561" -dependencies = [ - "aes-soft", - "aesni", - "cipher 0.2.5", -] - -[[package]] -name = "aes" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8" -dependencies = [ - "cfg-if 1.0.0", - "cipher 0.3.0", - "cpufeatures", - "opaque-debug", -] - [[package]] name = "aes" version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2" dependencies = [ - "cfg-if 1.0.0", - "cipher 0.4.4", + "cfg-if", + "cipher", "cpufeatures", ] @@ -86,34 +44,14 @@ version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "209b47e8954a928e1d72e86eca7000ebb6655fe1436d33eefc2201cad027e237" dependencies = [ - "aead 0.5.2", - "aes 0.8.3", - "cipher 0.4.4", - "ctr 0.9.2", + "aead", + "aes", + "cipher", + "ctr", "ghash", "subtle", ] -[[package]] -name = "aes-soft" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be14c7498ea50828a38d0e24a765ed2effe92a705885b57d029cd67d45744072" -dependencies = [ - "cipher 0.2.5", - "opaque-debug", -] - -[[package]] -name = "aesni" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea2e11f5e94c2f7d386164cc2aa1f97823fed6f259e486940a71c174dd01b0ce" -dependencies = [ - "cipher 0.2.5", - "opaque-debug", -] - [[package]] name = "aho-corasick" version = "1.0.2" @@ -183,29 +121,13 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6" -[[package]] -name = "asn1-rs" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30ff05a702273012438132f449575dbc804e27b2f3cbe3069aa237d26c98fa33" -dependencies = [ - "asn1-rs-derive 0.1.0", - "asn1-rs-impl", - "displaydoc", - "nom", - "num-traits", - "rusticata-macros", - "thiserror", - "time", -] - [[package]] name = "asn1-rs" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f6fd5ddaf0351dff5b8da21b2fb4ff8e08ddd02857f0bf69c47639106c0fff0" dependencies = [ - "asn1-rs-derive 0.4.0", + "asn1-rs-derive", "asn1-rs-impl", "displaydoc", "nom", @@ -215,18 +137,6 @@ dependencies = [ "time", ] -[[package]] -name = "asn1-rs-derive" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db8b7511298d5b7784b40b092d9e9dcd3a627a5707e4b5e507931ab0d44eeebf" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", - "synstructure", -] - [[package]] name = "asn1-rs-derive" version = "0.4.0" @@ -331,7 +241,7 @@ checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12" dependencies = [ "addr2line", "cc", - "cfg-if 1.0.0", + "cfg-if", "libc", "miniz_oxide", "object", @@ -340,15 +250,9 @@ dependencies = [ [[package]] name = "base16ct" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" - -[[package]] -name = "base64" -version = "0.13.1" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" [[package]] name = "base64" @@ -393,21 +297,14 @@ dependencies = [ ] [[package]] -name = "block-modes" -version = "0.7.0" +name = "block-padding" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57a0e8073e8baa88212fb5823574c02ebccb395136ba9a164ab89379ec6072f0" +checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93" dependencies = [ - "block-padding", - "cipher 0.2.5", + "generic-array", ] -[[package]] -name = "block-padding" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" - [[package]] name = "bumpalo" version = "3.13.0" @@ -426,6 +323,15 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" +[[package]] +name = "cbc" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6" +dependencies = [ + "cipher", +] + [[package]] name = "cc" version = "1.0.79" @@ -434,45 +340,22 @@ checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" [[package]] name = "ccm" -version = "0.3.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aca1a8fbc20b50ac9673ff014abfb2b5f4085ee1a850d408f14a159c5853ac7" +checksum = "9ae3c82e4355234767756212c570e29833699ab63e6ffd161887314cc5b43847" dependencies = [ - "aead 0.3.2", - "cipher 0.2.5", + "aead", + "cipher", + "ctr", "subtle", ] -[[package]] -name = "cfg-if" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" - [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "cipher" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12f8e7987cbd042a63249497f41aed09f8e65add917ea6566effbc56578d6801" -dependencies = [ - "generic-array", -] - -[[package]] -name = "cipher" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" -dependencies = [ - "generic-array", -] - [[package]] name = "cipher" version = "0.4.4" @@ -572,9 +455,9 @@ checksum = "9cace84e55f07e7301bae1c519df89cdad8cc3cd868413d3fdbdeca9ff3db484" [[package]] name = "crypto-bigint" -version = "0.4.9" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" +checksum = "740fe28e594155f10cfc383984cbefd529d7396050557148f79cb0f621204124" dependencies = [ "generic-array", "rand_core", @@ -593,31 +476,22 @@ dependencies = [ "typenum", ] -[[package]] -name = "ctr" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "049bb91fb4aaf0e3c7efa6cd5ef877dbbbd15b39dad06d9948de4ec8a75761ea" -dependencies = [ - "cipher 0.3.0", -] - [[package]] name = "ctr" version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" dependencies = [ - "cipher 0.4.4", + "cipher", ] [[package]] name = "curve25519-dalek" -version = "4.0.0-rc.3" +version = "4.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436ace70fc06e06f7f689d2624dc4e2f0ea666efb5aa704215f7249ae6e047a7" +checksum = "e89b8c6a2e4b1f45971ad09761aafb85514a84744b67a95e32c3cc1352d1f65c" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "cpufeatures", "curve25519-dalek-derive", "fiat-crypto", @@ -646,36 +520,22 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" [[package]] name = "der" -version = "0.6.1" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" dependencies = [ "const-oid", "pem-rfc7468", "zeroize", ] -[[package]] -name = "der-parser" -version = "7.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe398ac75057914d7d07307bf67dc7f3f574a26783b4fc7805a20ffa9f506e82" -dependencies = [ - "asn1-rs 0.3.1", - "displaydoc", - "nom", - "num-bigint", - "num-traits", - "rusticata-macros", -] - [[package]] name = "der-parser" version = "8.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dbd676fbbab537128ef0278adb5576cf363cff6aa22a7b24effe97347cfab61e" dependencies = [ - "asn1-rs 0.5.2", + "asn1-rs", "displaydoc", "nom", "num-bigint", @@ -696,6 +556,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer", + "const-oid", "crypto-common", "subtle", ] @@ -713,25 +574,26 @@ dependencies = [ [[package]] name = "ecdsa" -version = "0.14.8" +version = "0.16.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" +checksum = "a4b1e0c257a9e9f25f90ff76d7a68360ed497ee519c8e428d1825ef0000799d4" dependencies = [ "der", + "digest", "elliptic-curve", "rfc6979", "signature", + "spki", ] [[package]] name = "elliptic-curve" -version = "0.12.3" +version = "0.13.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" +checksum = "d97ca172ae9dc9f9b779a6e3a65d308f2af74e5b8c921299075bdb4a0370e914" dependencies = [ "base16ct", "crypto-bigint", - "der", "digest", "ff", "generic-array", @@ -751,7 +613,7 @@ version = "0.8.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", ] [[package]] @@ -796,9 +658,9 @@ dependencies = [ [[package]] name = "ff" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" dependencies = [ "rand_core", "subtle", @@ -806,9 +668,9 @@ dependencies = [ [[package]] name = "fiat-crypto" -version = "0.1.20" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e825f6987101665dea6ec934c09ec6d721de7bc1bf92248e1d5810c8cd636b77" +checksum = "d0870c84016d4b481be5c9f323c24f65e31e901ae618f0e80f4308fb00de1d2d" [[package]] name = "fnv" @@ -922,6 +784,7 @@ checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", + "zeroize", ] [[package]] @@ -930,7 +793,7 @@ version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "libc", "wasi", ] @@ -953,9 +816,9 @@ checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" [[package]] name = "group" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ "ff", "rand_core", @@ -1117,7 +980,7 @@ dependencies = [ "futures-util", "http", "hyper", - "rustls 0.21.7", + "rustls", "tokio", "tokio-rustls", ] @@ -1158,13 +1021,15 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" dependencies = [ + "block-padding", "generic-array", ] [[package]] name = "interceptor" -version = "0.9.0" -source = "git+https://github.com/webrtc-rs/webrtc#73ce2b80973a373ca48c991b6ad9b348e8f7ae0c" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5927883184e6a819b22d5e4f5f7bc7ca134fde9b2026fbddd8d95249746ba21e" dependencies = [ "async-trait", "bytes", @@ -1228,7 +1093,7 @@ name = "libwish" version = "0.1.0" dependencies = [ "anyhow", - "base64 0.21.3", + "base64", "parse_link_header", "reqwest", "webrtc", @@ -1246,7 +1111,7 @@ version = "0.2.0" dependencies = [ "anyhow", "axum", - "base64 0.21.3", + "base64", "env_logger", "http", "http-body", @@ -1295,9 +1160,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.5.0" +version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" [[package]] name = "memoffset" @@ -1375,7 +1240,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a" dependencies = [ "bitflags 1.3.2", - "cfg-if 1.0.0", + "cfg-if", "libc", "memoffset", "pin-utils", @@ -1441,22 +1306,13 @@ dependencies = [ "memchr", ] -[[package]] -name = "oid-registry" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38e20717fa0541f39bd146692035c37bedfa532b3e5071b35761082407546b2a" -dependencies = [ - "asn1-rs 0.3.1", -] - [[package]] name = "oid-registry" version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9bedf36ffb6ba96c2eb7144ef6270557b52e54b20c0a8e1eb2ff99a6c6959bff" dependencies = [ - "asn1-rs 0.5.2", + "asn1-rs", ] [[package]] @@ -1473,23 +1329,25 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "p256" -version = "0.11.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51f44edd08f51e2ade572f141051021c5af22677e42b7dd28a88155151c33594" +checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" dependencies = [ "ecdsa", "elliptic-curve", + "primeorder", "sha2", ] [[package]] name = "p384" -version = "0.11.2" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc8c5bf642dde52bb9e87c0ecd8ca5a76faac2eeed98dedb7c717997e1080aa" +checksum = "70786f51bcc69f6a4c0360e063a4cac5419ef7c5cd5b3c99ad70f3be5ba79209" dependencies = [ "ecdsa", "elliptic-curve", + "primeorder", "sha2", ] @@ -1509,7 +1367,7 @@ version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "libc", "redox_syscall", "smallvec", @@ -1529,18 +1387,19 @@ dependencies = [ [[package]] name = "pem" -version = "1.1.1" +version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8835c273a76a90455d7344889b0964598e3316e2a79ede8e36f16bdcf2228b8" +checksum = "3163d2912b7c3b52d651a055f2c7eec9ba5cd22d26ef75b8dd3a59980b185923" dependencies = [ - "base64 0.13.1", + "base64", + "serde", ] [[package]] name = "pem-rfc7468" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d159833a9105500e0398934e205e0773f0b27529557134ecfc51c27646adac" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" dependencies = [ "base64ct", ] @@ -1585,9 +1444,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkcs8" -version = "0.9.0" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ "der", "spki", @@ -1605,7 +1464,7 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d52cff9d1d4dee5fe6d03729099f4a310a41179e0a10dbf542039873f2e826fb" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "cpufeatures", "opaque-debug", "universal-hash", @@ -1617,6 +1476,15 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +[[package]] +name = "primeorder" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c2fcef82c0ec6eefcc179b978446c399b3cdf73c392c35604e399eee6df1ee3" +dependencies = [ + "elliptic-curve", +] + [[package]] name = "proc-macro2" version = "1.0.63" @@ -1667,14 +1535,14 @@ dependencies = [ [[package]] name = "rcgen" -version = "0.10.0" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffbe84efe2f38dea12e9bfc1f65377fdf03e53a18cb3b995faedf7934c7e785b" +checksum = "52c4f3084aa3bc7dfbba4eff4fab2a54db4324965d8872ab933565e6fbd83bc6" dependencies = [ "pem", "ring", "time", - "x509-parser 0.14.0", + "x509-parser", "yasna", ] @@ -1689,9 +1557,21 @@ dependencies = [ [[package]] name = "regex" -version = "1.8.4" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0ab3ca65655bb1e41f2a8c8cd662eb4fb035e67c3f78da1d61dffe89d07300f" +checksum = "d119d7c7ca818f8a53c300863d4f87566aac09943aef5b355bb83969dae75d87" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "465c6fc0621e4abc4187a2bda0937bfd4f722c2730b29562e19689ea796c9a4b" dependencies = [ "aho-corasick", "memchr", @@ -1700,9 +1580,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.7.2" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" +checksum = "c3cbb081b9784b07cceb8824c8583f86db4814d172ab043f3c23f7dc600bf83d" [[package]] name = "reqwest" @@ -1710,7 +1590,7 @@ version = "0.11.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3e9ad3fe7488d7e34558a2033d45a0c90b72d97b4f80705666fea71472e2e6a1" dependencies = [ - "base64 0.21.3", + "base64", "bytes", "encoding_rs", "futures-core", @@ -1727,7 +1607,7 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", - "rustls 0.21.7", + "rustls", "rustls-pemfile", "serde", "serde_json", @@ -1745,13 +1625,12 @@ dependencies = [ [[package]] name = "rfc6979" -version = "0.3.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" dependencies = [ - "crypto-bigint", "hmac", - "zeroize", + "subtle", ] [[package]] @@ -1771,8 +1650,9 @@ dependencies = [ [[package]] name = "rtcp" -version = "0.9.0" -source = "git+https://github.com/webrtc-rs/webrtc#73ce2b80973a373ca48c991b6ad9b348e8f7ae0c" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3677908cadfbecb4cc1da9a56a32524fae4ebdfa7c2ea93886e1b1e846488cb9" dependencies = [ "bytes", "thiserror", @@ -1781,8 +1661,9 @@ dependencies = [ [[package]] name = "rtp" -version = "0.8.0" -source = "git+https://github.com/webrtc-rs/webrtc#73ce2b80973a373ca48c991b6ad9b348e8f7ae0c" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e60482acbe8afb31edf6b1413103b7bca7a65004c423b3c3993749a083994fbe" dependencies = [ "bytes", "rand", @@ -1865,19 +1746,6 @@ dependencies = [ "windows-sys", ] -[[package]] -name = "rustls" -version = "0.19.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35edb675feee39aec9c99fa5ff985081995a06d594114ae14cbe797ad7b7a6d7" -dependencies = [ - "base64 0.13.1", - "log", - "ring", - "sct 0.6.1", - "webpki", -] - [[package]] name = "rustls" version = "0.21.7" @@ -1887,7 +1755,7 @@ dependencies = [ "log", "ring", "rustls-webpki", - "sct 0.7.0", + "sct", ] [[package]] @@ -1896,7 +1764,7 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" dependencies = [ - "base64 0.21.3", + "base64", ] [[package]] @@ -1936,16 +1804,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" -[[package]] -name = "sct" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b362b83898e0e69f38515b82ee15aa80636befe47c3b6d3d89a911e78fc228ce" -dependencies = [ - "ring", - "untrusted", -] - [[package]] name = "sct" version = "0.7.0" @@ -1958,8 +1816,9 @@ dependencies = [ [[package]] name = "sdp" -version = "0.5.3" -source = "git+https://github.com/webrtc-rs/webrtc#73ce2b80973a373ca48c991b6ad9b348e8f7ae0c" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4653054c30ebce63658762eb0d64e27673868a95564474811ae6c220cf767640" dependencies = [ "rand", "substring", @@ -1969,9 +1828,9 @@ dependencies = [ [[package]] name = "sec1" -version = "0.3.0" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" dependencies = [ "base16ct", "der", @@ -2054,7 +1913,7 @@ version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "cpufeatures", "digest", ] @@ -2065,7 +1924,7 @@ version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "cpufeatures", "digest", ] @@ -2091,9 +1950,9 @@ dependencies = [ [[package]] name = "signature" -version = "1.6.4" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" +checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" dependencies = [ "digest", "rand_core", @@ -2157,9 +2016,9 @@ checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" [[package]] name = "spki" -version = "0.6.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" +checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" dependencies = [ "base64ct", "der", @@ -2179,10 +2038,11 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "stun" -version = "0.4.4" -source = "git+https://github.com/webrtc-rs/webrtc#73ce2b80973a373ca48c991b6ad9b348e8f7ae0c" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7beb1624a3ea34778d58d30e2b8606b4d29fe65e87c4d50b87ed30afd5c3830c" dependencies = [ - "base64 0.21.3", + "base64", "crc", "lazy_static", "md-5", @@ -2324,9 +2184,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.30.0" +version = "1.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d3ce25f50619af8b0aec2eb23deebe84249e19e2ddd393a6e16e3300a6dadfd" +checksum = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653" dependencies = [ "backtrace", "bytes", @@ -2358,7 +2218,7 @@ version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ - "rustls 0.21.7", + "rustls", "tokio", ] @@ -2432,7 +2292,7 @@ version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61c5bb1d698276a2443e5ecfabc1008bf15a36c12e6a7176e7bf089ea9131140" dependencies = [ - "base64 0.21.3", + "base64", "bitflags 2.3.3", "bytes", "futures-core", @@ -2470,7 +2330,7 @@ version = "0.1.37" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "log", "pin-project-lite", "tracing-core", @@ -2493,11 +2353,12 @@ checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" [[package]] name = "turn" -version = "0.6.1" -source = "git+https://github.com/webrtc-rs/webrtc#73ce2b80973a373ca48c991b6ad9b348e8f7ae0c" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58f4fcb97da0426e8146fe0e9b78cc13120161087256198701d12d9df77f7701" dependencies = [ "async-trait", - "base64 0.21.3", + "base64", "futures", "log", "md-5", @@ -2639,7 +2500,7 @@ version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "wasm-bindgen-macro", ] @@ -2664,7 +2525,7 @@ version = "0.4.37" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "js-sys", "wasm-bindgen", "web-sys", @@ -2709,16 +2570,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "webpki" -version = "0.21.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8e38c0608262c46d4a56202ebabdeb094cef7e560ca7a226c6bf055188aa4ea" -dependencies = [ - "ring", - "untrusted", -] - [[package]] name = "webpki-roots" version = "0.25.2" @@ -2727,13 +2578,14 @@ checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" [[package]] name = "webrtc" -version = "0.8.0" -source = "git+https://github.com/webrtc-rs/webrtc#73ce2b80973a373ca48c991b6ad9b348e8f7ae0c" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91e7cf018f7185552bf6a5dd839f4ed9827aea33b746763c9a215f84a0d0b34" dependencies = [ "arc-swap", "async-trait", "bytes", - "cfg-if 0.1.10", + "cfg-if", "hex", "interceptor", "lazy_static", @@ -2744,7 +2596,7 @@ dependencies = [ "ring", "rtcp", "rtp", - "rustls 0.19.1", + "rustls", "sdp", "serde", "serde_json", @@ -2769,8 +2621,9 @@ dependencies = [ [[package]] name = "webrtc-data" -version = "0.7.0" -source = "git+https://github.com/webrtc-rs/webrtc#73ce2b80973a373ca48c991b6ad9b348e8f7ae0c" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a45d2461d0e0bf93f181e30eb0b40df32b8bf3efb89c53cebb1990e603e2067d" dependencies = [ "bytes", "log", @@ -2782,17 +2635,18 @@ dependencies = [ [[package]] name = "webrtc-dtls" -version = "0.7.2" -source = "git+https://github.com/webrtc-rs/webrtc#73ce2b80973a373ca48c991b6ad9b348e8f7ae0c" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32b140b953f986e97828aa33ec6318186b05d862bee689efbc57af04a243e832" dependencies = [ - "aes 0.6.0", + "aes", "aes-gcm", "async-trait", "bincode", - "block-modes", "byteorder", + "cbc", "ccm", - "der-parser 8.2.0", + "der-parser", "hkdf", "hmac", "log", @@ -2802,7 +2656,7 @@ dependencies = [ "rand_core", "rcgen", "ring", - "rustls 0.19.1", + "rustls", "sec1", "serde", "sha1", @@ -2810,16 +2664,16 @@ dependencies = [ "subtle", "thiserror", "tokio", - "webpki", "webrtc-util", "x25519-dalek", - "x509-parser 0.13.2", + "x509-parser", ] [[package]] name = "webrtc-ice" -version = "0.9.1" -source = "git+https://github.com/webrtc-rs/webrtc#73ce2b80973a373ca48c991b6ad9b348e8f7ae0c" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66eb4b85646f1c52225779db3e1e7e873dede6db68cc9be080b648f1713083a3" dependencies = [ "arc-swap", "async-trait", @@ -2841,11 +2695,12 @@ dependencies = [ [[package]] name = "webrtc-mdns" -version = "0.5.2" -source = "git+https://github.com/webrtc-rs/webrtc#73ce2b80973a373ca48c991b6ad9b348e8f7ae0c" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bebbd40e7f8b630a0f1a74783dbfff1edfc0ccaae891c4689891156a8c4d8c" dependencies = [ "log", - "socket2 0.4.9", + "socket2 0.5.3", "thiserror", "tokio", "webrtc-util", @@ -2853,8 +2708,9 @@ dependencies = [ [[package]] name = "webrtc-media" -version = "0.6.1" -source = "git+https://github.com/webrtc-rs/webrtc#73ce2b80973a373ca48c991b6ad9b348e8f7ae0c" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cfde3c7b9450b67d466bb2f02c6d9ff9514d33535eb9994942afd1f828839d1" dependencies = [ "byteorder", "bytes", @@ -2865,8 +2721,9 @@ dependencies = [ [[package]] name = "webrtc-sctp" -version = "0.8.0" -source = "git+https://github.com/webrtc-rs/webrtc#73ce2b80973a373ca48c991b6ad9b348e8f7ae0c" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1af6116b7f9703560c3ad0b32f67220b171bb1b59633b03563db8404d0e482ea" dependencies = [ "arc-swap", "async-trait", @@ -2881,15 +2738,16 @@ dependencies = [ [[package]] name = "webrtc-srtp" -version = "0.10.0" -source = "git+https://github.com/webrtc-rs/webrtc#73ce2b80973a373ca48c991b6ad9b348e8f7ae0c" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1db1f36c1c81e4b1e531c0b9678ba0c93809e196ce62122d87259bb71c03b9f" dependencies = [ - "aead 0.4.3", - "aes 0.7.5", + "aead", + "aes", "aes-gcm", "byteorder", "bytes", - "ctr 0.8.0", + "ctr", "hmac", "log", "rtcp", @@ -2903,8 +2761,9 @@ dependencies = [ [[package]] name = "webrtc-util" -version = "0.7.0" -source = "git+https://github.com/webrtc-rs/webrtc#73ce2b80973a373ca48c991b6ad9b348e8f7ae0c" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1adc96bee68417e1f4d19dd7698124a7f859db55ae2fd3eedbbb7e732f614735" dependencies = [ "async-trait", "bitflags 1.3.2", @@ -3059,15 +2918,15 @@ version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "windows-sys", ] [[package]] name = "x25519-dalek" -version = "2.0.0-rc.3" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec7fae07da688e17059d5886712c933bb0520f15eff2e09cfa18e30968f4e63a" +checksum = "fb66477291e7e8d2b0ff1bcb900bf29489a9692816d79874bea351e7a8b6de96" dependencies = [ "curve25519-dalek", "rand_core", @@ -3077,35 +2936,16 @@ dependencies = [ [[package]] name = "x509-parser" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb9bace5b5589ffead1afb76e43e34cff39cd0f3ce7e170ae0c29e53b88eb1c" -dependencies = [ - "asn1-rs 0.3.1", - "base64 0.13.1", - "data-encoding", - "der-parser 7.0.0", - "lazy_static", - "nom", - "oid-registry 0.4.0", - "rusticata-macros", - "thiserror", - "time", -] - -[[package]] -name = "x509-parser" -version = "0.14.0" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0ecbeb7b67ce215e40e3cc7f2ff902f94a223acf44995934763467e7b1febc8" +checksum = "7069fba5b66b9193bd2c5d3d4ff12b839118f6bcbef5328efafafb5395cf63da" dependencies = [ - "asn1-rs 0.5.2", - "base64 0.13.1", + "asn1-rs", "data-encoding", - "der-parser 8.2.0", + "der-parser", "lazy_static", "nom", - "oid-registry 0.6.1", + "oid-registry", "ring", "rusticata-macros", "thiserror", diff --git a/Cargo.toml b/Cargo.toml index 4277e9e2..7f963802 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,7 @@ members = [ [dependencies] axum = { version = "0.6.20", features = ["multipart"] } tower-http = { version = "0.4.3", features = ["fs", "auth"] } -webrtc = { git = "https://github.com/webrtc-rs/webrtc" } +webrtc = "0.9.0" anyhow = "1.0" tokio = { version = "1.30", features = ["full"] } hyper = "0.14" diff --git a/Dockerfile.client b/Dockerfile.client index 1a2d94df..5fa51aaa 100644 --- a/Dockerfile.client +++ b/Dockerfile.client @@ -1,19 +1,25 @@ -FROM rust:1.71.1-slim-bookworm +FROM debian:sid-20230919-slim AS common -RUN apt update -y && apt install -y --no-install-recommends libglib2.0-dev libssl-dev \ +RUN apt update -y && apt install -y --no-install-recommends ca-certificates + +RUN apt install -y --no-install-recommends libglib2.0-dev libssl-dev \ libgstreamer1.0-dev gstreamer1.0-tools gstreamer1.0-libav \ libgstreamer-plugins-base1.0-dev gstreamer1.0-plugins-base \ gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly \ libpango1.0-dev libgstreamer-plugins-bad1.0-dev gstreamer1.0-nice -RUN cargo install cargo-c +FROM common AS builder + +# Now, rust version: 1.70 +RUN apt install -y --no-install-recommends cargo cargo-c WORKDIR /app -ADD https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/archive/gstreamer-1.22.5/gst-plugins-rs-gstreamer-1.22.5.tar.gz gst-plugins-rs-gstreamer.tar.gz +ADD https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/archive/gstreamer-1.22.6/gst-plugins-rs-gstreamer-1.22.6.tar.gz gst-plugins-rs-gstreamer.tar.gz RUN tar -xf gst-plugins-rs-gstreamer.tar.gz --strip-components 1 +# whip / whep: protocol support RUN cargo cinstall -p gst-plugin-webrtchttp --prefix=/usr --libdir=/usr/lib/$(gcc -dumpmachine) # rtpav1pay / rtpav1depay: RTP (de)payloader for the AV1 video codec. diff --git a/README.md b/README.md index 7798efc9..24cbb97a 100644 --- a/README.md +++ b/README.md @@ -1,91 +1,138 @@ -# Live777 +

+ Live777 +
Live777
+

[![Rust](https://github.com/binbat/live777/actions/workflows/rust.yml/badge.svg)](https://github.com/binbat/live777/actions/workflows/rust.yml) [![GitHub release](https://img.shields.io/github/tag/binbat/live777.svg?label=release)](https://github.com/binbat/live777/releases) -A very simple, high performance, support WHIP/WHEP edge WebRTC SFU (Selective Forwarding Unit) +Live777 is an SFU server for real-time video streaming for the `WHIP`/`WHEP` as first protocol. + +Live777 media server is used with [Gstreamer](https://gstreamer.freedesktop.org/), [FFmpeg](https://ffmpeg.org/), [OBS Studio](https://obsproject.com/), [VLC](https://www.videolan.org/), [WebRTC](https://webrtc.org/) and other clients to provide the ability to receive and distribute streams, and is a typical publishing (pushing) and subscription (playing) server model. + +Live777 supports the conversion of audio and video protocols widely used in the Internet, such as RTP to WHIP or WHEP and other protocols. ![live777-arch](./docs/live777-arch.excalidraw.svg#gh-light-mode-only) ![live777-arch](./docs/live777-arch.dark.svg#gh-dark-mode-only) -## Current +## Features -| protocol | video codecs | audio codecs | -| -------- | ------------ | ------------ | -| `WHIP` | `AV1`, `VP8`, `VP9`, `H264` | `Opus`, `G722` | -| `WHEP` | `AV1`, `VP8`, `VP9`, `H264` | `Opus`, `G722` | +Live777 has the following characteristics: -## Supports `WHIP`/`WHEP` applications +- 📚 **Support `WHIP`/`WHEP`** -![live777-apps](./docs/live777-apps.excalidraw.svg#gh-light-mode-only) -![live777-apps](./docs/live777-apps.dark.svg#gh-dark-mode-only) + The WHIP/WHEP protocol is implemented to improve interoperability with other WebRTC application modules without the need for custom adaptations. -### Live777 Server +- 🗃️ **SFU architecture** -```bash -docker run --name live777-server --rm --network host \ -ghcr.io/binbat/live777-server:latest live777 -``` + Only responsible for forwarding, do not do confluence, transcoding and other resource overhead of the media processing work, the encoding and decoding work are respectively placed on the sender and the receiver. -### Browser Demo Page +- 🌐 **Multiple platform support** -```bash -# open your browser -open http://localhost:3000/ -``` + With rich multi-platform native support. -## Use OBS Studio WHIP +- 🔍 **Multiple audio and video encoding formats support** -- OBS Studio >= 30 + Support a variety of video encoding and audio encoding formats, providing a wider range of compatibility to help enable adaptive streaming. -**OBS WHIP Current only support `H264` video codecs and `Opus` audio codecs** +## Current support encode +| protocol | video codecs | audio codecs | +| -------- | --------------------------- | -------------- | +| `WHIP` | `AV1`, `VP8`, `VP9`, `H264` | `Opus`, `G722` | +| `WHEP` | `AV1`, `VP8`, `VP9`, `H264` | `Opus`, `G722` | -![obs whip](./obs-whip.avif) +## Quickstart + +### Run Live777 using docker: + +```sh +docker run --name live777-server --rm --network host ghcr.io/binbat/live777-server:latest live777 +``` -## Use GStreamer `WHIP`/`WHEP` +### Gstreamer WHIP/WHEP client -This plugins from [gst-plugins-rs](https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/) +- Use docker of [Gstreamer](https://gstreamer.freedesktop.org/download/) to publish: -### Video: VP8 +This `WHIP`/ `WHEP` plugins from [gst-plugins-rs](https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/) + +> *Note: supports multiple encoding formats* + +#### Video: AV1 + +**Note: AV1 has a lot of problem** +- 🚧 browser whip av1 +- 🚧 browser whep av1 +- ✅ gstreamer whip av1 +- 🚧 gstreamer whep av1 +- ✅ gstreamer rtp av1 src +- ✅ gstreamer rtp av1 sink +- 🚧 ffmpeg rtp av1 src +- 🚧 ffmpeg rtp av1 sink `WHIP`: ```bash docker run --name live777-client-whip --rm --network host \ ghcr.io/binbat/live777-client:latest \ -gst-launch-1.0 videotestsrc ! videoconvert ! vp8enc ! rtpvp8pay ! whipsink whip-endpoint="http://localhost:3000/whip/777" +gst-launch-1.0 videotestsrc ! av1enc usage-profile=realtime ! av1parse ! rtpav1pay ! whipsink whip-endpoint="http://localhost:3000/whip/777" ``` `WHEP`: +I don't know why av1 and whep error + +But, you can: + +```bash +cargo run --package=whepfrom -- -c av1 -u http://localhost:3000/whep/777 -t 127.0.0.1:5004 +``` + ```bash docker run --name live777-client-whep --rm --network host \ ghcr.io/binbat/live777-client:latest \ -gst-launch-1.0 whepsrc whep-endpoint="http://localhost:3000/whep/777" audio-caps="application/x-rtp,payload=111,encoding-name=OPUS,media=audio,clock-rate=48000" video-caps="application/x-rtp,payload=96,encoding-name=VP8,media=video,clock-rate=90000" ! rtpvp8depay ! vp8dec ! videoconvert ! aasink +gst-launch-1.0 udpsrc port=5004 caps="application/x-rtp, media=(string)video, encoding-name=(string)AV1" ! rtpjitterbuffer ! rtpav1depay ! av1parse ! av1dec ! videoconvert ! aasink ``` -### Video: VP9 +#### Video: VP8 `WHIP`: + +```bash +docker run --name live777-client-whip --rm --network host \ +ghcr.io/binbat/live777-client:latest \ +gst-launch-1.0 videotestsrc ! videoconvert ! vp8enc ! rtpvp8pay ! whipsink whip-endpoint="http://localhost:3000/whip/777" +``` + +`WHEP`: + +```bash +docker run --name live777-client-whep --rm --network host \ +ghcr.io/binbat/live777-client:latest \ +gst-launch-1.0 whepsrc whep-endpoint="http://localhost:3000/whep/777" audio-caps="application/x-rtp,payload=111,encoding-name=OPUS,media=audio,clock-rate=48000" video-caps="application/x-rtp,payload=96,encoding-name=VP8,media=video,clock-rate=90000" ! rtpvp8depay ! vp8dec ! videoconvert ! aasink +``` + +#### Video: VP9 +`WHIP`: + ``` bash docker run --name live777-client --rm --network host \ ghcr.io/binbat/live777-client:latest \ gst-launch-1.0 videotestsrc ! videoconvert ! vp9enc ! rtpvp9pay ! whipsink whip-endpoint="http://localhost:3000/whip/777" ``` -`WHEP`: - + `WHEP`: + ```bash docker run --name live777-client-whep --rm --network host \ ghcr.io/binbat/live777-client:latest \ gst-launch-1.0 whepsrc whep-endpoint="http://localhost:3000/whep/777" audio-caps="application/x-rtp,payload=111,encoding-name=OPUS,media=audio,clock-rate=48000" video-caps="application/x-rtp,payload=98,encoding-name=VP9,media=video,clock-rate=90000" ! rtpvp9depay ! vp9dec ! videoconvert ! aasink ``` -### Video: H264 +#### Video: H264 `WHIP`: - + ```bash docker run --name live777-client --rm --network host \ ghcr.io/binbat/live777-client:latest \ @@ -105,10 +152,10 @@ Use `libav` ```bash docker run --name live777-client-whep --rm --network host \ ghcr.io/binbat/live777-client:latest \ -gst-launch-1.0 whepsrc whep-endpoint="http://localhost:3000/whep/777" audio-caps="application/x-rtp,payload=111,encoding-name=OPUS,media=audio,clock-rate=48000" video-caps="application/x-rtp,payload=102,encoding-name=H264,media=video,clock-rate=90000" ! rtph264depay ! avdec_h264 ! videoconvert ! aasink +gst-launch-1.0 whepsrc whep-endpoint="http://localhost:3000/whep/777" audio-caps="application/x-rtp,payload=111,encoding-name=OPUS,media=audio,clock-rate=48000" video-caps="application/x-rtp,payload=102,encoding-name=H264 media=video,clock-rate=90000" ! rtph264depay ! avdec_h264 ! videoconvert ! aasink ``` -### Audio: Opus +#### Audio: Opus `WHIP`: @@ -130,7 +177,7 @@ Maybe you can't play audio, we can audio to video display for ascii gst-launch-1.0 whepsrc whep-endpoint="http://localhost:3000/whep/777" audio-caps="application/x-rtp,payload=111,encoding-name=OPUS,media=audio,clock-rate=48000" video-caps="application/x-rtp,payload=102,encoding-name=H264,media=video,clock-rate=90000" ! rtpopusdepay ! opusdec ! audioconvert ! wavescope ! videoconvert ! aasink ``` -### Audio: G722 +#### Audio: G722 **GStreamer G722 need `avenc_g722` in `gstreamer-libav`** @@ -140,10 +187,26 @@ ghcr.io/binbat/live777-client:latest \ gst-launch-1.0 audiotestsrc ! audioconvert ! avenc_g722 ! rtpg722pay ! whipsink whip-endpoint="http://localhost:3000/whip/777 ``` +### OBS Studio WHIP client + +> Note: +> 1. OBS Studio version [**30 or higher**](https://obsproject.com/forum/threads/obs-studio-30-beta.168984/) +> 2. OBS WHIP Current only support **H264** video codecs and **Opus** audio codecs + +![obs whip](./obs-whip.avif) + +#### Play stream + +- open your browser, enter the URL: [`http://localhost:3000/`](http://localhost:3000/) + ## Tools We have tools for support rtp -> whip/whep convert +![live777-apps](./docs/live777-apps.excalidraw.svg#gh-light-mode-only) +![live777-apps](./docs/live777-apps.dark.svg#gh-dark-mode-only) + + For Example: ```bash @@ -154,7 +217,7 @@ ffmpeg -> whipinto -> live777 -> whepfrom -> ffplay This tool is `rtp2whip` -Build: +Build ```bash cargo build --package=whipinto --release @@ -177,7 +240,9 @@ cargo run --package=whipinto -- -c vp8 -u http://localhost:3000/whip/777 --comma "ffmpeg -re -f lavfi -i testsrc=size=640x480:rate=30 -vcodec libvpx -cpu-used 5 -deadline 1 -g 10 -error-resilient 1 -auto-alt-ref 1 -f rtp 'rtp://127.0.0.1:{port}?pkt_size=1200'" ``` -VLC RTP stream, **NOTE: VLC can't support all video codec** +VLC RTP stream + +**Note: VLC can't support all video codec** ```bash vlc -vvv --sout '#transcode{vcodec=h264}:rtp{dst=127.0.0.1,port=5003}' @@ -187,7 +252,7 @@ vlc -vvv --sout '#transcode{vcodec=h264}:rtp{dst=127.0.0.1,port=500 This tool is `whep2rtp` -Build: +Build ```bash cargo build --package=whepfrom --release @@ -216,7 +281,7 @@ Use ffplay ffplay -protocol_whitelist rtp,file,udp -i stream.sdp ``` -So. You can use this: +So. You can use this ```bash cargo run --package=whepfrom -- -c vp8 -u http://localhost:3000/whep/777 -t 127.0.0.1:5004 --command 'ffplay -protocol_whitelist rtp,file,udp -i stream.sdp' @@ -227,10 +292,15 @@ Use VLC player ```bash vlc stream.sdp ``` - ## Sponsors

- JetBrains Logo (Main) logo. + + JetBrains Logo (Main) logo. + +
+ + Hostker logo. +

diff --git a/docs/logo.svg b/docs/logo.svg new file mode 100644 index 00000000..0a35fb33 --- /dev/null +++ b/docs/logo.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libs/cli/Cargo.toml b/libs/cli/Cargo.toml index 19e83619..2d0fce32 100644 --- a/libs/cli/Cargo.toml +++ b/libs/cli/Cargo.toml @@ -9,6 +9,6 @@ crate-type = ["lib"] [dependencies] clap = { version = "4.4.1", features = ["derive"] } -webrtc = { git = "https://github.com/webrtc-rs/webrtc" } +webrtc = "0.9.0" shellwords = "1.1.0" anyhow = "1.0" diff --git a/libs/libwish/Cargo.toml b/libs/libwish/Cargo.toml index 368ff49b..b2b4f94a 100644 --- a/libs/libwish/Cargo.toml +++ b/libs/libwish/Cargo.toml @@ -8,7 +8,7 @@ edition = "2021" crate-type = ["lib"] [dependencies] -webrtc = { git = "https://github.com/webrtc-rs/webrtc" } +webrtc = "0.9.0" anyhow = "1.0" reqwest = { version = "0.11.20", features = ["rustls-tls"], default-features = false } parse_link_header = "0.3" diff --git a/src/forward/forward_internal.rs b/src/forward/forward_internal.rs index 365cc842..4d84711c 100644 --- a/src/forward/forward_internal.rs +++ b/src/forward/forward_internal.rs @@ -5,7 +5,7 @@ use std::time::Duration; use anyhow::Result; use log::info; -use tokio::sync::mpsc::{unbounded_channel, UnboundedSender}; +use tokio::sync::mpsc::{channel, unbounded_channel, Receiver, Sender, UnboundedSender}; use tokio::sync::RwLock; use webrtc::api::interceptor_registry::register_default_interceptors; use webrtc::api::media_engine::MediaEngine; @@ -23,6 +23,7 @@ use webrtc::rtp::packet::Packet; use webrtc::rtp_transceiver::rtp_codec::{ RTCRtpCodecCapability, RTCRtpHeaderExtensionCapability, RTPCodecType, }; +use webrtc::rtp_transceiver::rtp_sender::RTCRtpSender; use webrtc::rtp_transceiver::rtp_transceiver_direction::RTCRtpTransceiverDirection; use webrtc::rtp_transceiver::RTCRtpTransceiverInit; use webrtc::sdp::extmap::{SDES_MID_URI, SDES_RTP_STREAM_ID_URI}; @@ -33,6 +34,7 @@ use webrtc::track::track_local::{TrackLocal, TrackLocalWriter}; use webrtc::track::track_remote::TrackRemote; use crate::forward::track_match::{track_match_codec, track_sort}; +use crate::media; use super::track_match; @@ -100,13 +102,19 @@ impl Hash for TrackRemoteWrap { } } -type ForwardHandle = Arc>>; +type SubscriptionGroup = Arc>>; + +#[derive(Clone)] +struct TrackForward { + pli_send: Sender<()>, + subscription_group: SubscriptionGroup, +} pub(crate) struct PeerForwardInternal { pub(crate) id: String, anchor: RwLock>>, subscribe_group: RwLock>, - anchor_track_forward_map: Arc>>, + anchor_track_forward_map: Arc>>, ice_server: Vec, } @@ -130,7 +138,18 @@ impl PeerForwardInternal { let anchor = self.anchor.read().await; let anchor_track_forward_map = self.anchor_track_forward_map.read().await; anchor.is_some() - && !anchor_track_forward_map.is_empty() + && anchor_track_forward_map.len() + == media::count_sends( + &anchor + .as_ref() + .unwrap() + .remote_description() + .await + .unwrap() + .unmarshal() + .unwrap() + .media_descriptions, + ) && anchor.as_ref().unwrap().connection_state() == RTCPeerConnectionState::Connected } @@ -195,43 +214,39 @@ impl PeerForwardInternal { async fn subscribe_track_flush( peer: Weak, - anchor_track_forward_map: Arc>>, + anchor_track_forward_map: Arc>>, ) { let mut pre_report: Option = None; loop { - let timeout = tokio::time::sleep(Duration::from_secs(1)); + let timeout = tokio::time::sleep(Duration::from_secs(20)); tokio::pin!(timeout); let _ = timeout.as_mut().await; if let Some(pc) = peer.upgrade() { for (_, report) in pc.get_stats().await.reports { if let StatsReportType::RemoteInboundRTP(remote_inbound) = report { - if RTPCodecType::from(remote_inbound.kind) != RTPCodecType::Video - || remote_inbound.packets_received == 0 - { + if RTPCodecType::from(remote_inbound.kind) != RTPCodecType::Video { continue; } let mut packets_received = remote_inbound.packets_received; let mut packets_lost = remote_inbound.packets_lost; if let Some(pre_report) = &pre_report { packets_received -= pre_report.packets_received; - packets_lost -= pre_report.packets_lost; + packets_lost -= pre_report.packets_lost; } - if packets_received < 1000 { + if packets_received == 0 { continue; } let packet_loss_rate = packets_lost as f64 / packets_received as f64; if (0.05..=0.2).contains(&packet_loss_rate) { continue; } - if Self::subscribe_track_reallocate( + Self::subscribe_track_reallocate( pc.clone(), anchor_track_forward_map.clone(), packet_loss_rate < 0.05, ) - .await - { - pre_report = Some(remote_inbound); - } + .await; + pre_report = Some(remote_inbound); } } } else { @@ -242,41 +257,40 @@ impl PeerForwardInternal { async fn subscribe_track_reallocate( pc: Arc, - anchor_track_forward_map: Arc>>, + anchor_track_forward_map: Arc>>, upgrade: bool, - ) -> bool { + ) { let peer_wrap = PeerWrap(pc); let anchor_track_forward_map = anchor_track_forward_map.read().await; - let track_remotes: Vec> = anchor_track_forward_map + let tracks: Vec = anchor_track_forward_map .keys() .cloned() - .map(|t| t.0) + .filter(|t| t.0.kind() == RTPCodecType::Video) .collect(); - let mut original_track_remote_wrap = None; - for (track_remote_wrap, subscribes) in anchor_track_forward_map.iter() { - let subscribes = subscribes.read().await; - if subscribes.contains_key(&peer_wrap) { - original_track_remote_wrap = Some(track_remote_wrap.clone()); - break; + let mut original_track = None; + for track in tracks.iter() { + if let Some(track_forward) = anchor_track_forward_map.get(track) { + let subscribes = track_forward.subscription_group.read().await; + if subscribes.contains_key(&peer_wrap) { + original_track = Some(track.clone()); + break; + } } } - if let Some(original_track_remote_wrap) = original_track_remote_wrap { - let mut tracks = track_match_codec( - &[original_track_remote_wrap.0.codec().capability], - &track_remotes, - ); + if let Some(original_track) = original_track { + let tracks: Vec> = tracks.into_iter().map(|t| t.0).collect(); + let mut tracks = track_match_codec(&[original_track.0.codec().capability], &tracks); track_sort(&mut tracks); - let tracks: Vec = - tracks.into_iter().map(TrackRemoteWrap).collect(); + let tracks: Vec = tracks.into_iter().map(TrackRemoteWrap).collect(); let mut original_index = None; for (index, item) in tracks.iter().enumerate() { - if item == &original_track_remote_wrap { + if item == &original_track { original_index = Some(index); break; } } if original_index.is_none() { - return false; + return; } let original_index = original_index.unwrap(); let target_index = if upgrade { @@ -285,28 +299,26 @@ impl PeerForwardInternal { original_index - 1 }; if !(0..tracks.len()).contains(&target_index) { - return false; + return; } let target_track = tracks.get(target_index).unwrap(); - let original_subscribes = anchor_track_forward_map - .get(&original_track_remote_wrap) - .unwrap(); - let mut subscribes = original_subscribes.write().await; - if let Some(sender) = subscribes.remove(&peer_wrap) { - let target_subscribes = anchor_track_forward_map.get(target_track).unwrap(); - let mut target_subscribes = target_subscribes.write().await; - target_subscribes.insert(peer_wrap, sender); - return true; + let original_track_forward = anchor_track_forward_map.get(&original_track).unwrap(); + let mut subscription_group = original_track_forward.subscription_group.write().await; + if let Some(sender) = subscription_group.remove(&peer_wrap) { + let target_track_forward = anchor_track_forward_map.get(target_track).unwrap(); + let mut target_subscription_group = + target_track_forward.subscription_group.write().await; + target_subscription_group.insert(peer_wrap, sender); + let _ = target_track_forward.pli_send.try_send(()); } } - false } pub async fn remove_subscribe(&self, peer: Arc) -> Result<()> { let peer_wrap = PeerWrap(peer.clone()); - for (_, track_forward_map) in self.anchor_track_forward_map.write().await.iter() { - let mut track_forward_map = track_forward_map.write().await; - track_forward_map.remove(&peer_wrap); + for (_, track_forward) in self.anchor_track_forward_map.write().await.iter() { + let mut subscription_group = track_forward.subscription_group.write().await; + subscription_group.remove(&peer_wrap); } let mut subscribe_peers = self.subscribe_group.write().await; subscribe_peers.retain(|x| x != &peer_wrap); @@ -392,12 +404,13 @@ impl PeerForwardInternal { ) .await { - let mut subscription_map = anchor_track_forward_map + let mut subscription_group = anchor_track_forward_map .get(&TrackRemoteWrap(track)) .unwrap() + .subscription_group .write() .await; - subscription_map.insert(PeerWrap(peer.clone()), sender); + subscription_group.insert(PeerWrap(peer.clone()), sender); } } } @@ -429,7 +442,11 @@ impl PeerForwardInternal { ..Default::default() })]) .await; - tokio::spawn(async move { while(sender.read_rtcp().await).is_ok() {}}); + tokio::spawn(Self::subscribe_read_rtcp( + Arc::downgrade(&peer), + sender, + self.anchor_track_forward_map.clone(), + )); let (send, mut recv) = unbounded_channel::(); let self_id = self.id.clone(); let peer_stats_id = peer.get_stats_id().to_string(); @@ -459,6 +476,34 @@ impl PeerForwardInternal { Ok(send) } + async fn subscribe_read_rtcp( + pc: Weak, + sender: Arc, + track_forward_map: Arc>>, + ) { + while let Ok((packets, _)) = sender.read_rtcp().await { + if let Some(pc) = pc.upgrade() { + for packet in packets { + if let Some(_pli) = packet.as_any().downcast_ref::() { + if let Some(track) = sender.track().await { + let kind = track.kind(); + let track_forward_map = track_forward_map.read().await; + for (track_remote, track_forward) in track_forward_map.iter() { + if track_remote.0.kind() == kind { + let subscription_group = + track_forward.subscription_group.read().await; + if subscription_group.contains_key(&PeerWrap(pc.clone())) { + let _ = track_forward.pli_send.try_send(()); + } + } + } + } + } + } + } + } + } + pub(crate) async fn add_ice_candidate( &self, key: String, @@ -511,14 +556,22 @@ impl PeerForwardInternal { if anchor.as_ref().unwrap().get_stats_id() != peer.get_stats_id() { return Err(anyhow::anyhow!("anchor is not self")); } - tokio::spawn(Self::anchor_track_pli(Arc::downgrade(&peer), track.ssrc())); + let (send, recv) = channel(1); + tokio::spawn(Self::anchor_track_pli( + Arc::downgrade(&peer), + track.ssrc(), + recv, + )); let mut anchor_track_forward_map = self.anchor_track_forward_map.write().await; - let subscription: ForwardHandle = Default::default(); - anchor_track_forward_map.insert(TrackRemoteWrap(track.clone()), subscription.clone()); + let handle = TrackForward { + pli_send: send, + subscription_group: Default::default(), + }; + anchor_track_forward_map.insert(TrackRemoteWrap(track.clone()), handle.clone()); tokio::spawn(Self::anchor_track_forward( self.id.clone(), track, - subscription, + handle.subscription_group, )); Ok(()) } @@ -526,7 +579,7 @@ impl PeerForwardInternal { async fn anchor_track_forward( id: String, track: Arc, - subscription: ForwardHandle, + subscription: SubscriptionGroup, ) { let mut b = vec![0u8; 1500]; info!( @@ -553,11 +606,13 @@ impl PeerForwardInternal { ); } - async fn anchor_track_pli(peer: Weak, media_ssrc: u32) { + async fn anchor_track_pli( + peer: Weak, + media_ssrc: u32, + mut recv: Receiver<()>, + ) { loop { - let timeout = tokio::time::sleep(Duration::from_secs(1)); - tokio::pin!(timeout); - let _ = timeout.as_mut().await; + let _ = recv.recv().await; if let Some(pc) = peer.upgrade() { if pc .write_rtcp(&[Box::new(PictureLossIndication { diff --git a/src/forward/mod.rs b/src/forward/mod.rs index 7107a8f1..58c321e6 100644 --- a/src/forward/mod.rs +++ b/src/forward/mod.rs @@ -1,7 +1,6 @@ use std::io::Cursor; use std::sync::Arc; -use crate::forward::forward_internal::{get_peer_key, PeerForwardInternal}; use anyhow::Result; use log::info; use tokio::sync::Mutex; @@ -12,6 +11,10 @@ use webrtc::peer_connection::sdp::session_description::RTCSessionDescription; use webrtc::peer_connection::RTCPeerConnection; use webrtc::rtp_transceiver::rtp_codec::RTPCodecType; use webrtc::sdp::{MediaDescription, SessionDescription}; + +use crate::forward::forward_internal::{get_peer_key, PeerForwardInternal}; +use crate::media; + mod forward_internal; mod track_match; @@ -109,6 +112,9 @@ impl PeerForward { RTCPeerConnectionState::Failed | RTCPeerConnectionState::Disconnected => { let _ = pc.close().await; } + RTCPeerConnectionState::Connected => { + let _ = internal.add_subscribe(pc).await; + } RTCPeerConnectionState::Closed => { let _ = internal.remove_subscribe(pc).await; } @@ -118,7 +124,6 @@ impl PeerForward { } Box::pin(async {}) })); - let _ = self.internal.add_subscribe(peer.clone()).await; Ok(( peer_complete(offer, peer.clone()).await?, get_peer_key(peer), @@ -191,19 +196,7 @@ fn parse_ice_candidate(content: String) -> Result> { fn get_media_descriptions(sd: SessionDescription, publish: bool) -> Result> { let mut media_descriptions = sd.media_descriptions; - media_descriptions.retain(|media_description| { - let mut is_publish = false; - for attribute in &media_description.attributes { - match attribute.key.as_str() { - "sendonly" | "simulcast:send" => { - is_publish = true; - break; - } - _ => {} - } - } - publish == is_publish - }); + media_descriptions.retain(|md| publish == (media::count_send(md) > 0)); let mut video = false; let mut audio = false; for md in &media_descriptions { diff --git a/src/media/mod.rs b/src/media/mod.rs index dca514dd..57dff1aa 100644 --- a/src/media/mod.rs +++ b/src/media/mod.rs @@ -74,3 +74,34 @@ pub fn codecs_from_media_description( Ok(out) } + +pub fn count_sends(mds: &Vec) -> usize { + let mut count = 0; + for md in mds { + count += count_send(md); + } + count +} + +pub fn count_send(md: &MediaDescription) -> usize { + let mut count = 0; + let mut minus = 0; + for attribute in &md.attributes { + match attribute.key.as_str() { + "sendonly" => { + count += 1; + minus += 1; + } + "simulcast" => { + let val = attribute.value.clone().unwrap_or("".to_string()); + if !val.starts_with("send ") { + break; + } + count += val.replace("send ", "").split(';').count() - minus; + break; + } + _ => {} + } + } + count +} diff --git a/tools/whepfrom/Cargo.toml b/tools/whepfrom/Cargo.toml index 46cf04ae..a22a3a32 100644 --- a/tools/whepfrom/Cargo.toml +++ b/tools/whepfrom/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" [dependencies] clap = { version = "4.4.1", features = ["derive"] } -webrtc = { git = "https://github.com/webrtc-rs/webrtc" } +webrtc = "0.9.0" anyhow = "1.0" tokio = { version = "1.30", features = ["full"] } cli = { path = "../../libs/cli" } diff --git a/tools/whipinto/Cargo.toml b/tools/whipinto/Cargo.toml index b28acded..e1fa8d03 100644 --- a/tools/whipinto/Cargo.toml +++ b/tools/whipinto/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" [dependencies] clap = { version = "4.4.1", features = ["derive"] } -webrtc = { git = "https://github.com/webrtc-rs/webrtc" } +webrtc = "0.9.0" anyhow = "1.0" tokio = { version = "1.30", features = ["full"] } cli = { path = "../../libs/cli" }