mirror of
https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git
synced 2024-06-16 21:20:33 +00:00
Implement the GstNavigation interface using a dedicated DataChannel protocol
This allows interacting with the source element from within the browser very easily
This commit is contained in:
parent
7b66b21f47
commit
689bd93055
203
Cargo.lock
generated
203
Cargo.lock
generated
|
@ -13,9 +13,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.48"
|
||||
version = "1.0.52"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62e1f47f7dc0422027a4e370dd4548d4d66b26782e513e98dca1e689e058a80e"
|
||||
checksum = "84450d0b4a8bd1ba4144ce8ce718fbc5d071358b1e5384bace6536b3d1f2d5b3"
|
||||
|
||||
[[package]]
|
||||
name = "async-channel"
|
||||
|
@ -160,9 +160,9 @@ checksum = "e91831deabf0d6d7ec49552e489aed63b7456a7a3c46cff62adad428110b0af0"
|
|||
|
||||
[[package]]
|
||||
name = "async-tungstenite"
|
||||
version = "0.16.0"
|
||||
version = "0.16.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a0d06e9a20f1c0d64b6067ef6aa9fdf59e194ecde93575591fb4c78063692324"
|
||||
checksum = "5682ea0913e5c20780fe5785abacb85a411e7437bf52a1bedb93ddb3972cb8dd"
|
||||
dependencies = [
|
||||
"async-native-tls",
|
||||
"async-std",
|
||||
|
@ -251,9 +251,9 @@ checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8"
|
|||
|
||||
[[package]]
|
||||
name = "cache-padded"
|
||||
version = "1.1.1"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "631ae5198c9be5e753e5cc215e1bd73c2b466a3565173db433f52bb9d3e66dba"
|
||||
checksum = "c1db59621ec70f09c5e9b597b220c7a2b43611f4710dc03ceb8748637775692c"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
|
@ -290,9 +290,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "3.0.0-rc.1"
|
||||
version = "3.0.0-rc.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c068998524e6d40ea78c8d2a4b00398f0a8b818c2d484bcb3cbeb2cff2c105ae"
|
||||
checksum = "e6f243c7279f09ffed852a0a564c72091331651484cdbb32b7287f16df8611a7"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"bitflags",
|
||||
|
@ -307,11 +307,11 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clap_derive"
|
||||
version = "3.0.0-rc.1"
|
||||
version = "3.0.0-rc.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0152ba3ee01fa5a9133d4e15a1d9659c75d2270365768dd5a880cc7e68871874"
|
||||
checksum = "8cd9992739777a4a23535089a8d235eac43044ba8b431d9f54fe334dfa779930"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"heck 0.3.3",
|
||||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -389,9 +389,9 @@ checksum = "f7531096570974c3a9dcf9e4b8e1cede1ec26cf5046219fb3b9d897503b9be59"
|
|||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
version = "1.5.0"
|
||||
version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b394ed3d285a429378d3b384b9eb1285267e7df4b166df24b7a6939a04dc392e"
|
||||
checksum = "779d043b6a0b90cc4c0ed7ee380a6504394cee7efd7db050e3774eee387324b2"
|
||||
dependencies = [
|
||||
"instant",
|
||||
]
|
||||
|
@ -435,9 +435,9 @@ checksum = "69a039c3498dc930fe810151a34ba0c1c70b02b8625035592e74432f678591f2"
|
|||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.3.17"
|
||||
version = "0.3.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a12aa0eb539080d55c3f2d45a67c3b58b6b0773c1a3ca2dfec66d58c97fd66ca"
|
||||
checksum = "28560757fe2bb34e79f907794bb6b22ae8b0e5c669b638a1132f2592b19035b4"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
|
@ -450,9 +450,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "futures-channel"
|
||||
version = "0.3.17"
|
||||
version = "0.3.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5da6ba8c3bb3c165d3c7319fc1cc8304facf1fb8db99c5de877183c08a273888"
|
||||
checksum = "ba3dda0b6588335f360afc675d0564c17a77a2bda81ca178a4b6081bd86c7f0b"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
|
@ -460,15 +460,15 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "futures-core"
|
||||
version = "0.3.17"
|
||||
version = "0.3.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "88d1c26957f23603395cd326b0ffe64124b818f4449552f960d815cfba83a53d"
|
||||
checksum = "d0c8ff0461b82559810cdccfde3215c3f373807f5e5232b71479bff7bb2583d7"
|
||||
|
||||
[[package]]
|
||||
name = "futures-executor"
|
||||
version = "0.3.17"
|
||||
version = "0.3.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "45025be030969d763025784f7f355043dc6bc74093e4ecc5000ca4dc50d8745c"
|
||||
checksum = "29d6d2ff5bb10fb95c85b8ce46538a2e5f5e7fdc755623a7d4529ab8a4ed9d2a"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-task",
|
||||
|
@ -477,9 +477,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "futures-io"
|
||||
version = "0.3.17"
|
||||
version = "0.3.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "522de2a0fe3e380f1bc577ba0474108faf3f6b18321dbf60b3b9c39a75073377"
|
||||
checksum = "b1f9d34af5a1aac6fb380f735fe510746c38067c5bf16c7fd250280503c971b2"
|
||||
|
||||
[[package]]
|
||||
name = "futures-lite"
|
||||
|
@ -498,12 +498,10 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "futures-macro"
|
||||
version = "0.3.17"
|
||||
version = "0.3.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "18e4a4b95cea4b4ccbcf1c5675ca7c4ee4e9e75eb79944d07defde18068f79bb"
|
||||
checksum = "6dbd947adfffb0efc70599b3ddcf7b5597bb5fa9e245eb99f62b3a5f7bb8bd3c"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"proc-macro-hack",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
|
@ -511,23 +509,22 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "futures-sink"
|
||||
version = "0.3.17"
|
||||
version = "0.3.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "36ea153c13024fe480590b3e3d4cad89a0cfacecc24577b68f86c6ced9c2bc11"
|
||||
checksum = "e3055baccb68d74ff6480350f8d6eb8fcfa3aa11bdc1a1ae3afdd0514617d508"
|
||||
|
||||
[[package]]
|
||||
name = "futures-task"
|
||||
version = "0.3.17"
|
||||
version = "0.3.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d3d00f4eddb73e498a54394f228cd55853bdf059259e8e7bc6e69d408892e99"
|
||||
checksum = "6ee7c6485c30167ce4dfb83ac568a849fe53274c831081476ee13e0dce1aad72"
|
||||
|
||||
[[package]]
|
||||
name = "futures-util"
|
||||
version = "0.3.17"
|
||||
version = "0.3.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "36568465210a3a6ee45e1f165136d68671471a501e632e9a98d96872222b5481"
|
||||
checksum = "d9b5cf40b47a271f77a8b1bec03ca09044d99d2372c0de244e66430761127164"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
|
@ -537,8 +534,6 @@ dependencies = [
|
|||
"memchr",
|
||||
"pin-project-lite",
|
||||
"pin-utils",
|
||||
"proc-macro-hack",
|
||||
"proc-macro-nested",
|
||||
"slab",
|
||||
]
|
||||
|
||||
|
@ -566,7 +561,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "glib"
|
||||
version = "0.15.0"
|
||||
source = "git+https://github.com/gtk-rs/gtk-rs-core#88de0f7cdffd391893918861eb16e65ef714977a"
|
||||
source = "git+https://github.com/gtk-rs/gtk-rs-core#9c59482b4bc1d3d46ca7ddaf40f9e9e04964b4c6"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"futures-channel",
|
||||
|
@ -579,15 +574,16 @@ dependencies = [
|
|||
"libc",
|
||||
"once_cell",
|
||||
"smallvec",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glib-macros"
|
||||
version = "0.15.0"
|
||||
source = "git+https://github.com/gtk-rs/gtk-rs-core#88de0f7cdffd391893918861eb16e65ef714977a"
|
||||
source = "git+https://github.com/gtk-rs/gtk-rs-core#9c59482b4bc1d3d46ca7ddaf40f9e9e04964b4c6"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"heck",
|
||||
"heck 0.4.0",
|
||||
"proc-macro-crate",
|
||||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
|
@ -598,7 +594,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "glib-sys"
|
||||
version = "0.15.0"
|
||||
source = "git+https://github.com/gtk-rs/gtk-rs-core#88de0f7cdffd391893918861eb16e65ef714977a"
|
||||
source = "git+https://github.com/gtk-rs/gtk-rs-core#9c59482b4bc1d3d46ca7ddaf40f9e9e04964b4c6"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"system-deps",
|
||||
|
@ -606,9 +602,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "gloo-timers"
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "47204a46aaff920a1ea58b11d03dec6f704287d27561724a4631e450654a891f"
|
||||
checksum = "6f16c88aa13d2656ef20d1c042086b8767bbe2bdb62526894275a1b062161b2e"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
|
@ -620,7 +616,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "gobject-sys"
|
||||
version = "0.15.0"
|
||||
source = "git+https://github.com/gtk-rs/gtk-rs-core#88de0f7cdffd391893918861eb16e65ef714977a"
|
||||
source = "git+https://github.com/gtk-rs/gtk-rs-core#9c59482b4bc1d3d46ca7ddaf40f9e9e04964b4c6"
|
||||
dependencies = [
|
||||
"glib-sys",
|
||||
"libc",
|
||||
|
@ -639,7 +635,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "gstreamer"
|
||||
version = "0.18.0"
|
||||
source = "git+https://gitlab.freedesktop.org/gstreamer/gstreamer-rs#f31aa2efee1ff84439ae199dcef58ce841809e14"
|
||||
source = "git+https://gitlab.freedesktop.org/gstreamer/gstreamer-rs#1dae136ae3b0d935f4cf336f111d8aad2feab723"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cfg-if",
|
||||
|
@ -665,7 +661,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "gstreamer-app"
|
||||
version = "0.18.0"
|
||||
source = "git+https://gitlab.freedesktop.org/gstreamer/gstreamer-rs#f31aa2efee1ff84439ae199dcef58ce841809e14"
|
||||
source = "git+https://gitlab.freedesktop.org/gstreamer/gstreamer-rs#1dae136ae3b0d935f4cf336f111d8aad2feab723"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"futures-core",
|
||||
|
@ -681,7 +677,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "gstreamer-app-sys"
|
||||
version = "0.18.0"
|
||||
source = "git+https://gitlab.freedesktop.org/gstreamer/gstreamer-rs#f31aa2efee1ff84439ae199dcef58ce841809e14"
|
||||
source = "git+https://gitlab.freedesktop.org/gstreamer/gstreamer-rs#1dae136ae3b0d935f4cf336f111d8aad2feab723"
|
||||
dependencies = [
|
||||
"glib-sys",
|
||||
"gstreamer-base-sys",
|
||||
|
@ -693,7 +689,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "gstreamer-base"
|
||||
version = "0.18.0"
|
||||
source = "git+https://gitlab.freedesktop.org/gstreamer/gstreamer-rs#f31aa2efee1ff84439ae199dcef58ce841809e14"
|
||||
source = "git+https://gitlab.freedesktop.org/gstreamer/gstreamer-rs#1dae136ae3b0d935f4cf336f111d8aad2feab723"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cfg-if",
|
||||
|
@ -706,7 +702,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "gstreamer-base-sys"
|
||||
version = "0.18.0"
|
||||
source = "git+https://gitlab.freedesktop.org/gstreamer/gstreamer-rs#f31aa2efee1ff84439ae199dcef58ce841809e14"
|
||||
source = "git+https://gitlab.freedesktop.org/gstreamer/gstreamer-rs#1dae136ae3b0d935f4cf336f111d8aad2feab723"
|
||||
dependencies = [
|
||||
"glib-sys",
|
||||
"gobject-sys",
|
||||
|
@ -718,7 +714,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "gstreamer-rtp"
|
||||
version = "0.18.0"
|
||||
source = "git+https://gitlab.freedesktop.org/gstreamer/gstreamer-rs#f31aa2efee1ff84439ae199dcef58ce841809e14"
|
||||
source = "git+https://gitlab.freedesktop.org/gstreamer/gstreamer-rs#1dae136ae3b0d935f4cf336f111d8aad2feab723"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"glib",
|
||||
|
@ -730,7 +726,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "gstreamer-rtp-sys"
|
||||
version = "0.18.0"
|
||||
source = "git+https://gitlab.freedesktop.org/gstreamer/gstreamer-rs#f31aa2efee1ff84439ae199dcef58ce841809e14"
|
||||
source = "git+https://gitlab.freedesktop.org/gstreamer/gstreamer-rs#1dae136ae3b0d935f4cf336f111d8aad2feab723"
|
||||
dependencies = [
|
||||
"glib-sys",
|
||||
"gstreamer-base-sys",
|
||||
|
@ -742,7 +738,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "gstreamer-sdp"
|
||||
version = "0.18.0"
|
||||
source = "git+https://gitlab.freedesktop.org/gstreamer/gstreamer-rs#f31aa2efee1ff84439ae199dcef58ce841809e14"
|
||||
source = "git+https://gitlab.freedesktop.org/gstreamer/gstreamer-rs#1dae136ae3b0d935f4cf336f111d8aad2feab723"
|
||||
dependencies = [
|
||||
"glib",
|
||||
"gstreamer",
|
||||
|
@ -752,7 +748,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "gstreamer-sdp-sys"
|
||||
version = "0.18.0"
|
||||
source = "git+https://gitlab.freedesktop.org/gstreamer/gstreamer-rs#f31aa2efee1ff84439ae199dcef58ce841809e14"
|
||||
source = "git+https://gitlab.freedesktop.org/gstreamer/gstreamer-rs#1dae136ae3b0d935f4cf336f111d8aad2feab723"
|
||||
dependencies = [
|
||||
"glib-sys",
|
||||
"gstreamer-sys",
|
||||
|
@ -763,7 +759,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "gstreamer-sys"
|
||||
version = "0.18.0"
|
||||
source = "git+https://gitlab.freedesktop.org/gstreamer/gstreamer-rs#f31aa2efee1ff84439ae199dcef58ce841809e14"
|
||||
source = "git+https://gitlab.freedesktop.org/gstreamer/gstreamer-rs#1dae136ae3b0d935f4cf336f111d8aad2feab723"
|
||||
dependencies = [
|
||||
"glib-sys",
|
||||
"gobject-sys",
|
||||
|
@ -774,7 +770,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "gstreamer-video"
|
||||
version = "0.18.0"
|
||||
source = "git+https://gitlab.freedesktop.org/gstreamer/gstreamer-rs#f31aa2efee1ff84439ae199dcef58ce841809e14"
|
||||
source = "git+https://gitlab.freedesktop.org/gstreamer/gstreamer-rs#1dae136ae3b0d935f4cf336f111d8aad2feab723"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cfg-if",
|
||||
|
@ -786,12 +782,13 @@ dependencies = [
|
|||
"gstreamer-video-sys",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gstreamer-video-sys"
|
||||
version = "0.18.0"
|
||||
source = "git+https://gitlab.freedesktop.org/gstreamer/gstreamer-rs#f31aa2efee1ff84439ae199dcef58ce841809e14"
|
||||
source = "git+https://gitlab.freedesktop.org/gstreamer/gstreamer-rs#1dae136ae3b0d935f4cf336f111d8aad2feab723"
|
||||
dependencies = [
|
||||
"glib-sys",
|
||||
"gobject-sys",
|
||||
|
@ -804,7 +801,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "gstreamer-webrtc"
|
||||
version = "0.18.0"
|
||||
source = "git+https://gitlab.freedesktop.org/gstreamer/gstreamer-rs#f31aa2efee1ff84439ae199dcef58ce841809e14"
|
||||
source = "git+https://gitlab.freedesktop.org/gstreamer/gstreamer-rs#1dae136ae3b0d935f4cf336f111d8aad2feab723"
|
||||
dependencies = [
|
||||
"glib",
|
||||
"gstreamer",
|
||||
|
@ -816,7 +813,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "gstreamer-webrtc-sys"
|
||||
version = "0.18.0"
|
||||
source = "git+https://gitlab.freedesktop.org/gstreamer/gstreamer-rs#f31aa2efee1ff84439ae199dcef58ce841809e14"
|
||||
source = "git+https://gitlab.freedesktop.org/gstreamer/gstreamer-rs#1dae136ae3b0d935f4cf336f111d8aad2feab723"
|
||||
dependencies = [
|
||||
"glib-sys",
|
||||
"gstreamer-sdp-sys",
|
||||
|
@ -839,6 +836,12 @@ dependencies = [
|
|||
"unicode-segmentation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.19"
|
||||
|
@ -850,9 +853,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "http"
|
||||
version = "0.2.5"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1323096b05d41827dadeaee54c9981958c0f94e670bc94ed80037d1a7b8b186b"
|
||||
checksum = "31f4c6746584866f0feabcc69893c5b51beef3831656a968ed7ae254cdc4fd03"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"fnv",
|
||||
|
@ -897,9 +900,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "0.4.8"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4"
|
||||
checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35"
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
|
@ -927,9 +930,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
|||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.108"
|
||||
version = "0.2.112"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8521a1b57e76b1ec69af7599e75e38e7b7fad6610f037db8c79b127201b5d119"
|
||||
checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
|
@ -1019,9 +1022,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "num_cpus"
|
||||
version = "1.13.0"
|
||||
version = "1.13.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3"
|
||||
checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
|
@ -1029,9 +1032,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.8.0"
|
||||
version = "1.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56"
|
||||
checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5"
|
||||
|
||||
[[package]]
|
||||
name = "opaque-debug"
|
||||
|
@ -1061,9 +1064,9 @@ checksum = "28988d872ab76095a6e6ac88d99b54fd267702734fd7ffe610ca27f533ddb95a"
|
|||
|
||||
[[package]]
|
||||
name = "openssl-sys"
|
||||
version = "0.9.71"
|
||||
version = "0.9.72"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7df13d165e607909b363a4757a6f133f8a818a74e9d3a98d09c6128e15fa4c73"
|
||||
checksum = "7e46109c383602735fa0a2e48dd2b7c892b048e1bf69e5c3b1d804b7d9c203cb"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cc",
|
||||
|
@ -1122,9 +1125,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
|||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.22"
|
||||
version = "0.3.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "12295df4f294471248581bc09bef3c38a5e46f1e36d6a37353621a0c6c357e1f"
|
||||
checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe"
|
||||
|
||||
[[package]]
|
||||
name = "polling"
|
||||
|
@ -1141,9 +1144,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.15"
|
||||
version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed0cfbc8191465bed66e1718596ee0b0b35d5ee1f41c5df2189d0fe8bde535ba"
|
||||
checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872"
|
||||
|
||||
[[package]]
|
||||
name = "pretty-hex"
|
||||
|
@ -1185,32 +1188,20 @@ dependencies = [
|
|||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-hack"
|
||||
version = "0.5.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-nested"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.32"
|
||||
version = "1.0.36"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba508cc11742c0dc5c1659771673afbab7a0efab23aa17e854cbab0837ed0b43"
|
||||
checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.10"
|
||||
version = "1.0.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05"
|
||||
checksum = "47aa80447ce4daf1717500037052af176af5d38cc3e571d9ec1c7353fc10c87d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
@ -1299,9 +1290,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.5"
|
||||
version = "1.0.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
|
||||
checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f"
|
||||
|
||||
[[package]]
|
||||
name = "schannel"
|
||||
|
@ -1338,9 +1329,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.130"
|
||||
version = "1.0.132"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913"
|
||||
checksum = "8b9875c23cf305cd1fd7eb77234cbb705f21ea6a72c637a5c6db5fe4b8e7f008"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
@ -1356,9 +1347,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.130"
|
||||
version = "1.0.132"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b"
|
||||
checksum = "ecc0db5cb2556c0e558887d9bbdcf6ac4471e83ff66cf696e5419024d1606276"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -1367,9 +1358,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.71"
|
||||
version = "1.0.73"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "063bf466a64011ac24040a49009724ee60a57da1b437617ceb32e53ad61bfb19"
|
||||
checksum = "bcbd0344bc6533bc7ec56df11d42fb70f1b912351c0825ccb7211b59d8af7cf5"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
|
@ -1400,9 +1391,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "signal-hook"
|
||||
version = "0.3.10"
|
||||
version = "0.3.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c98891d737e271a2954825ef19e46bd16bdb98e2746f2eec4f7a4ef7946efd1"
|
||||
checksum = "647c97df271007dcea485bb74ffdb57f2e683f1306c854f468a0c244badabf2d"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"signal-hook-registry",
|
||||
|
@ -1447,9 +1438,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
|||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.81"
|
||||
version = "1.0.84"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2afee18b8beb5a596ecb4a2dce128c719b4ba399d34126b9e4396e3f9860966"
|
||||
checksum = "ecb2e6da8ee5eb9a61068762a32fa9619cc591ceb055b3687f4cd4051ec2e06b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -1463,7 +1454,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "7b1487aaddaacbc5d60a2a507ba1617c5ca66c57dd0dd07d0c5efd5b693841d4"
|
||||
dependencies = [
|
||||
"cfg-expr",
|
||||
"heck",
|
||||
"heck 0.3.3",
|
||||
"pkg-config",
|
||||
"toml",
|
||||
"version-compare",
|
||||
|
@ -1649,9 +1640,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.14.0"
|
||||
version = "1.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec"
|
||||
checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-bidi"
|
||||
|
@ -1731,9 +1722,9 @@ checksum = "fe88247b92c1df6b6de80ddc290f3976dbdf2f5f5d3fd049a9fb598c6dd5ca73"
|
|||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.3"
|
||||
version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
|
||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||
|
||||
[[package]]
|
||||
name = "waker-fn"
|
||||
|
|
21
README.md
21
README.md
|
@ -135,6 +135,27 @@ for the list of properties.
|
|||
|
||||
[the source code]: plugins/src/signaller/imp.rs
|
||||
|
||||
|
||||
### Enable 'navigation' a.k.a user interactivity with the content
|
||||
|
||||
`webrtcsink` implements the [`GstNavigation`] interface which allows interacting
|
||||
with the content, for example move with your mouse, entering keys with the
|
||||
keyboard, etc... On top of that a `WebRTCDataChannel` based protocol has been
|
||||
implemented and can be activated with the `enable-data-channel-navigation=true`
|
||||
property. The [demo](www/) implements the protocol and you can easily test this
|
||||
feature, using the [`wpesrc`] for example.
|
||||
|
||||
As an example, the following pipeline allows you to navigate the GStreamer
|
||||
documentation inside the video running within your web browser (in
|
||||
http://127.0.0.1:8000 if you followed previous steps of that readme):
|
||||
|
||||
```
|
||||
gst-launch-1.0 wpesrc location=https://gstreamer.freedesktop.org/documentation/ ! webrtcsink enable-data-channel-navigation=true
|
||||
```
|
||||
|
||||
[`GstNavigation`]: https://gstreamer.freedesktop.org/documentation/video/gstnavigation.html
|
||||
[`wpesrc`]: https://gstreamer.freedesktop.org/documentation/wpe/wpesrc.html
|
||||
|
||||
## Testing congestion control
|
||||
|
||||
For the purpose of testing congestion in a reproducible manner, a
|
||||
|
|
|
@ -11,7 +11,7 @@ build = "build.rs"
|
|||
[dependencies]
|
||||
gst = { package = "gstreamer", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs", features = ["v1_20", "ser_de"] }
|
||||
gst-app = { package = "gstreamer-app", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs", features = ["v1_20"] }
|
||||
gst-video = { package = "gstreamer-video", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs", features = ["v1_20"] }
|
||||
gst-video = { package = "gstreamer-video", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs", features = ["v1_20", "ser_de"] }
|
||||
gst-webrtc = { package = "gstreamer-webrtc", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs", features = ["v1_20"] }
|
||||
gst-sdp = { package = "gstreamer-sdp", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs", features = ["v1_20"] }
|
||||
gst-rtp = { package = "gstreamer-rtp", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs", features = ["v1_20"] }
|
||||
|
|
|
@ -2,8 +2,11 @@ use anyhow::Context;
|
|||
use gst::glib;
|
||||
use gst::prelude::*;
|
||||
use gst::subclass::prelude::*;
|
||||
use gst_video::prelude::*;
|
||||
use gst_video::subclass::prelude::*;
|
||||
use gst::{gst_debug, gst_error, gst_info, gst_log, gst_trace, gst_warning};
|
||||
use gst_rtp::prelude::*;
|
||||
use gst_webrtc::WebRTCDataChannel;
|
||||
|
||||
use async_std::task;
|
||||
use futures::prelude::*;
|
||||
|
@ -44,6 +47,7 @@ const DEFAULT_CONGESTION_CONTROL: WebRTCSinkCongestionControl =
|
|||
WebRTCSinkCongestionControl::Homegrown;
|
||||
const DEFAULT_DO_FEC: bool = true;
|
||||
const DEFAULT_DO_RETRANSMISSION: bool = true;
|
||||
const DEFAULT_ENABLE_DATA_CHANNEL_NAVIGATION: bool = false;
|
||||
|
||||
/// User configuration
|
||||
struct Settings {
|
||||
|
@ -56,6 +60,7 @@ struct Settings {
|
|||
max_bitrate: u32,
|
||||
do_fec: bool,
|
||||
do_retransmission: bool,
|
||||
enable_data_channel_navigation: bool,
|
||||
}
|
||||
|
||||
/// Represents a codec we can offer
|
||||
|
@ -190,11 +195,30 @@ struct State {
|
|||
audio_serial: u32,
|
||||
video_serial: u32,
|
||||
streams: HashMap<String, InputStream>,
|
||||
navigation_handler: Option<NavigationEventHandler>,
|
||||
}
|
||||
|
||||
fn create_navigation_event<N: IsA< gst_video::Navigation>>(sink: &N, msg: &str) {
|
||||
let event: Result<gst_video::NavigationEvent, _> = serde_json::from_str(msg);
|
||||
|
||||
if let Ok(event) = event {
|
||||
sink.send_event(event.structure());
|
||||
} else {
|
||||
gst_error!(CAT, "Invalid navigation event: {:?}", msg);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
/// Simple utility for tearing down a pipeline cleanly
|
||||
struct PipelineWrapper(gst::Pipeline);
|
||||
|
||||
// Structure to generate GstNavigation event from a WebRTCDataChannel
|
||||
#[derive(Debug)]
|
||||
struct NavigationEventHandler {
|
||||
channel: WebRTCDataChannel,
|
||||
message_sig: glib::SignalHandlerId,
|
||||
}
|
||||
|
||||
/// Our instance structure
|
||||
#[derive(Default)]
|
||||
pub struct WebRTCSink {
|
||||
|
@ -220,6 +244,7 @@ impl Default for Settings {
|
|||
max_bitrate: DEFAULT_MAX_BITRATE,
|
||||
do_fec: DEFAULT_DO_FEC,
|
||||
do_retransmission: DEFAULT_DO_RETRANSMISSION,
|
||||
enable_data_channel_navigation: DEFAULT_ENABLE_DATA_CHANNEL_NAVIGATION,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -239,6 +264,7 @@ impl Default for State {
|
|||
audio_serial: 0,
|
||||
video_serial: 0,
|
||||
streams: HashMap::new(),
|
||||
navigation_handler: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1167,6 +1193,33 @@ impl InputStream {
|
|||
}
|
||||
}
|
||||
|
||||
impl NavigationEventHandler {
|
||||
pub fn new(
|
||||
element: &super::WebRTCSink,
|
||||
webrtcbin: &gst::Element,
|
||||
) -> Self {
|
||||
|
||||
let channel = webrtcbin.emit_by_name::<WebRTCDataChannel>(
|
||||
"create-data-channel",
|
||||
&[&"input", &None::<gst::Structure>],
|
||||
);
|
||||
|
||||
let weak_element = element.downgrade();
|
||||
Self {
|
||||
message_sig: channel.connect("on-message-string", false, move |values| {
|
||||
if let Some(element) = weak_element.upgrade() {
|
||||
let _channel = values[0].get::<WebRTCDataChannel>().unwrap();
|
||||
let msg = values[1].get::<&str>().unwrap();
|
||||
create_navigation_event(&element, msg);
|
||||
}
|
||||
|
||||
None
|
||||
}),
|
||||
channel,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl WebRTCSink {
|
||||
/// Build an ordered map of Codecs, given user-provided audio / video caps */
|
||||
fn lookup_codecs(&self) -> BTreeMap<i32, Codec> {
|
||||
|
@ -1664,6 +1717,11 @@ impl WebRTCSink {
|
|||
})?;
|
||||
|
||||
element.emit_by_name::<()>("new-webrtcbin", &[&peer_id, &webrtcbin]);
|
||||
if settings.enable_data_channel_navigation {
|
||||
state.navigation_handler = Some(
|
||||
NavigationEventHandler::new(&element, &webrtcbin)
|
||||
);
|
||||
}
|
||||
|
||||
pipeline.set_state(gst::State::Playing).map_err(|err| {
|
||||
WebRTCSinkError::ConsumerPipelineError {
|
||||
|
@ -2161,7 +2219,7 @@ impl ObjectSubclass for WebRTCSink {
|
|||
const NAME: &'static str = "RsWebRTCSink";
|
||||
type Type = super::WebRTCSink;
|
||||
type ParentType = gst::Bin;
|
||||
type Interfaces = (gst::ChildProxy,);
|
||||
type Interfaces = (gst::ChildProxy, gst_video::Navigation);
|
||||
}
|
||||
|
||||
impl ObjectImpl for WebRTCSink {
|
||||
|
@ -2243,6 +2301,13 @@ impl ObjectImpl for WebRTCSink {
|
|||
DEFAULT_DO_RETRANSMISSION,
|
||||
glib::ParamFlags::READWRITE | gst::PARAM_FLAG_MUTABLE_READY
|
||||
),
|
||||
glib::ParamSpecBoolean::new(
|
||||
"enable-data-channel-navigation",
|
||||
"Enable data channel navigation",
|
||||
"Enable navigation events through a dedicated WebRTCDataChannel",
|
||||
DEFAULT_ENABLE_DATA_CHANNEL_NAVIGATION,
|
||||
glib::ParamFlags::READWRITE | gst::PARAM_FLAG_MUTABLE_READY
|
||||
),
|
||||
]
|
||||
});
|
||||
|
||||
|
@ -2331,6 +2396,10 @@ impl ObjectImpl for WebRTCSink {
|
|||
let mut settings = self.settings.lock().unwrap();
|
||||
settings.do_retransmission = value.get::<bool>().expect("type checked upstream");
|
||||
}
|
||||
"enable-data-channel-navigation" => {
|
||||
let mut settings = self.settings.lock().unwrap();
|
||||
settings.enable_data_channel_navigation = value.get::<bool>().expect("type checked upstream");
|
||||
}
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
|
@ -2373,6 +2442,10 @@ impl ObjectImpl for WebRTCSink {
|
|||
let settings = self.settings.lock().unwrap();
|
||||
settings.do_retransmission.to_value()
|
||||
}
|
||||
"enable-data-channel-navigation" => {
|
||||
let settings = self.settings.lock().unwrap();
|
||||
settings.enable_data_channel_navigation.to_value()
|
||||
}
|
||||
"stats" => self.gather_stats().to_value(),
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
|
@ -2585,3 +2658,23 @@ impl ChildProxyImpl for WebRTCSink {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl NavigationImpl for WebRTCSink {
|
||||
fn send_event(&self, _imp: &Self::Type, event_def: gst::Structure) {
|
||||
let mut state = self.state.lock().unwrap();
|
||||
let event = gst::event::Navigation::new(event_def);
|
||||
|
||||
state
|
||||
.streams
|
||||
.iter_mut()
|
||||
.for_each(|(_, stream)| {
|
||||
if stream.sink_pad.name().starts_with("video_") {
|
||||
gst_log!(CAT, "Navigating to: {:?}", event);
|
||||
// FIXME: Handle multi tracks.
|
||||
if !stream.sink_pad.push_event(event.clone()) {
|
||||
gst_info!(CAT, "Could not send event: {:?}", event);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ mod imp;
|
|||
mod utils;
|
||||
|
||||
glib::wrapper! {
|
||||
pub struct WebRTCSink(ObjectSubclass<imp::WebRTCSink>) @extends gst::Bin, gst::Element, gst::Object, @implements gst::ChildProxy;
|
||||
pub struct WebRTCSink(ObjectSubclass<imp::WebRTCSink>) @extends gst::Bin, gst::Element, gst::Object, @implements gst::ChildProxy, gst_video::Navigation;
|
||||
}
|
||||
|
||||
unsafe impl Send for WebRTCSink {}
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
</style>
|
||||
<link rel="stylesheet" type="text/css" href="theme.css">
|
||||
<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
|
||||
<script src="keyboard.js"></script>
|
||||
<script src="input.js"></script>
|
||||
<script src="webrtc.js"></script>
|
||||
<script>window.onload = setup;</script>
|
||||
</head>
|
||||
|
|
192
www/input.js
192
www/input.js
|
@ -55,7 +55,7 @@ class Input {
|
|||
this.buttonMask = 0;
|
||||
|
||||
/**
|
||||
* @type {Guacamole.Keyboard}
|
||||
* @type {Keyboard}
|
||||
*/
|
||||
this.keyboard = null;
|
||||
|
||||
|
@ -117,7 +117,7 @@ class Input {
|
|||
*/
|
||||
_mouseButtonMovement(event) {
|
||||
const down = (event.type === 'mousedown' ? 1 : 0);
|
||||
var mtype = "m";
|
||||
var data = {};
|
||||
|
||||
if (event.type === 'mousemove' && !this.m) return;
|
||||
|
||||
|
@ -133,12 +133,20 @@ class Input {
|
|||
}
|
||||
|
||||
if (document.pointerLockElement) {
|
||||
mtype = "m2";
|
||||
// FIXME - mark as relative!
|
||||
console.warn("FIXME: Make event relative!")
|
||||
this.x = event.movementX;
|
||||
this.y = event.movementY;
|
||||
} else if (event.type === 'mousemove') {
|
||||
this.x = this._clientToServerX(event.clientX);
|
||||
this.y = this._clientToServerY(event.clientY);
|
||||
data["event"] = "MouseMove"
|
||||
}
|
||||
|
||||
if (event.type === 'mousedown') {
|
||||
data["event"] = "MouseButtonPress";
|
||||
} else if (event.type === 'mouseup') {
|
||||
data["event"] = "MouseButtonRelease";
|
||||
}
|
||||
|
||||
if (event.type === 'mousedown' || event.type === 'mouseup') {
|
||||
|
@ -148,16 +156,14 @@ class Input {
|
|||
} else {
|
||||
this.buttonMask &= ~mask;
|
||||
}
|
||||
|
||||
data["button"] = this.buttonMask;
|
||||
}
|
||||
|
||||
var toks = [
|
||||
mtype,
|
||||
this.x,
|
||||
this.y,
|
||||
this.buttonMask
|
||||
];
|
||||
data["x"] = this.x;
|
||||
data["y"] = this.y;
|
||||
|
||||
this.send(toks.join(","));
|
||||
this.send(JSON.stringify(data));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -165,56 +171,45 @@ class Input {
|
|||
* @param {TouchEvent} event
|
||||
*/
|
||||
_touch(event) {
|
||||
var mtype = "m";
|
||||
var mask = 1;
|
||||
var data = {};
|
||||
|
||||
if (event.type === 'touchstart') {
|
||||
this.buttonMask |= mask;
|
||||
data["event"] = "MouseButtonPress";
|
||||
data["button"] = this.buttonMask;
|
||||
} else if (event.type === 'touchend') {
|
||||
this.buttonMask &= ~mask;
|
||||
data["event"] = "MouseButtonRelease";
|
||||
data["button"] = this.buttonMask;
|
||||
} else if (event.type === 'touchmove') {
|
||||
event.preventDefault();
|
||||
data["event"] = "MouseMove";
|
||||
}
|
||||
|
||||
this.x = this._clientToServerX(event.changedTouches[0].clientX);
|
||||
this.y = this._clientToServerY(event.changedTouches[0].clientY);
|
||||
|
||||
var toks = [
|
||||
mtype,
|
||||
this.x,
|
||||
this.y,
|
||||
this.buttonMask
|
||||
];
|
||||
data["x"] = this.x;
|
||||
data["y"] = this.y;
|
||||
|
||||
this.send(toks.join(","));
|
||||
this.send(JSON.stringify(data));
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles mouse wheel events and sends them to WebRTC app.
|
||||
* @param {MouseWheelEvent} event
|
||||
* @param {MouseEvent} event
|
||||
*/
|
||||
_mouseWheel(event) {
|
||||
var mtype = (document.pointerLockElement ? "m2" : "m");
|
||||
var button = 3;
|
||||
if (event.deltaY < 0) {
|
||||
button = 4;
|
||||
}
|
||||
var mask = 1 << button;
|
||||
var toks;
|
||||
// Simulate button press and release.
|
||||
for (var i = 0; i < 2; i++) {
|
||||
if (i === 0)
|
||||
this.buttonMask |= mask;
|
||||
else
|
||||
this.buttonMask &= ~mask;
|
||||
toks = [
|
||||
mtype,
|
||||
this.x,
|
||||
this.y,
|
||||
this.buttonMask
|
||||
];
|
||||
this.send(toks.join(","));
|
||||
}
|
||||
_wheel(event) {
|
||||
let data = {
|
||||
"event": "MouseScroll",
|
||||
"x": this.x,
|
||||
"y": this.y,
|
||||
"delta_x": -event.deltaX,
|
||||
"delta_y": -event.deltaY,
|
||||
};
|
||||
|
||||
this.send(JSON.stringify(data));
|
||||
|
||||
event.preventDefault();
|
||||
}
|
||||
|
@ -261,24 +256,11 @@ class Input {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends WebRTC app command to toggle display of the remote mouse pointer.
|
||||
*/
|
||||
_pointerLock() {
|
||||
if (document.pointerLockElement) {
|
||||
this.send("p,1");
|
||||
} else {
|
||||
this.send("p,0");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends WebRTC app command to hide the remote pointer when exiting pointer lock.
|
||||
*/
|
||||
_exitPointerLock() {
|
||||
document.exitPointerLock();
|
||||
// hide the pointer.
|
||||
this.send("p,0");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -295,13 +277,26 @@ class Input {
|
|||
const vpWidth = frameW * multi;
|
||||
const vpHeight = (frameH * multi);
|
||||
|
||||
var elem = this.element;
|
||||
var offsetLeft = 0;
|
||||
var offsetTop = 0;
|
||||
do {
|
||||
if (!isNaN(elem.offsetLeft)) {
|
||||
offsetLeft += elem.offsetLeft;
|
||||
}
|
||||
|
||||
if (!isNaN(elem.offsetTop)) {
|
||||
offsetTop += elem.offsetTop;
|
||||
}
|
||||
} while (elem = elem.offsetParent);
|
||||
|
||||
this.m = {
|
||||
mouseMultiX: frameW / vpWidth,
|
||||
mouseMultiY: frameH / vpHeight,
|
||||
mouseOffsetX: Math.max((windowW - vpWidth) / 2.0, 0),
|
||||
mouseOffsetY: Math.max((windowH - vpHeight) / 2.0, 0),
|
||||
centerOffsetX: (document.documentElement.clientWidth - this.element.offsetWidth) / 2.0,
|
||||
centerOffsetY: (document.documentElement.clientHeight - this.element.offsetHeight) / 2.0,
|
||||
offsetLeft: offsetLeft,
|
||||
offsetTop: offsetTop,
|
||||
scrollX: window.scrollX,
|
||||
scrollY: window.scrollY,
|
||||
frameW,
|
||||
|
@ -314,7 +309,7 @@ class Input {
|
|||
* @param {Integer} clientX
|
||||
*/
|
||||
_clientToServerX(clientX) {
|
||||
let serverX = Math.round((clientX - this.m.mouseOffsetX - this.m.centerOffsetX + this.m.scrollX) * this.m.mouseMultiX);
|
||||
var serverX = Math.round((clientX - this.m.mouseOffsetX - this.m.offsetLeft + this.m.scrollX) * this.m.mouseMultiX);
|
||||
|
||||
if (serverX === this.m.frameW - 1) serverX = this.m.frameW;
|
||||
if (serverX > this.m.frameW) serverX = this.m.frameW;
|
||||
|
@ -328,7 +323,7 @@ class Input {
|
|||
* @param {Integer} clientY
|
||||
*/
|
||||
_clientToServerY(clientY) {
|
||||
let serverY = Math.round((clientY - this.m.mouseOffsetY - this.m.centerOffsetY + this.m.scrollY) * this.m.mouseMultiY);
|
||||
let serverY = Math.round((clientY - this.m.mouseOffsetY - this.m.offsetTop + this.m.scrollY) * this.m.mouseMultiY);
|
||||
|
||||
if (serverY === this.m.frameH - 1) serverY = this.m.frameH;
|
||||
if (serverY > this.m.frameH) serverY = this.m.frameH;
|
||||
|
@ -337,61 +332,6 @@ class Input {
|
|||
return serverY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends command to WebRTC app to connect virtual joystick and initializes the local GamepadManger.
|
||||
* @param {GamepadEvent} event
|
||||
*/
|
||||
_gamepadConnected(event) {
|
||||
console.log("Gamepad connected at index %d: %s. %d buttons, %d axes.",
|
||||
event.gamepad.index, event.gamepad.id,
|
||||
event.gamepad.buttons.length, event.gamepad.axes.length);
|
||||
|
||||
if (this.ongamepadconnected !== null) {
|
||||
this.ongamepadconnected(event.gamepad.id);
|
||||
}
|
||||
|
||||
// Initialize the gamepad manager.
|
||||
this.gamepadManager = new GamepadManager(event.gamepad, this._gamepadButton.bind(this), this._gamepadAxis.bind(this), this._gamepadDisconnect.bind(this));
|
||||
|
||||
// Send joystick connect message over data channel.
|
||||
this.send("js,c," + this.gamepadManager.numAxes + "," + this.gamepadManager.numButtons);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends joystick disconnect command to WebRTC app.
|
||||
*/
|
||||
_gamepadDisconnect() {
|
||||
console.log("Gamepad disconnected");
|
||||
|
||||
if (this.ongamepaddisconneceted !== null) {
|
||||
this.ongamepaddisconneceted();
|
||||
}
|
||||
|
||||
this.send("js,d")
|
||||
}
|
||||
|
||||
/**
|
||||
* Send gamepad button to WebRTC app.
|
||||
*
|
||||
* @param {number} gp_num - the gamepad number
|
||||
* @param {number} btn_num - the uinput converted button number
|
||||
* @param {number} val - the button value, 1 or 0 for pressed or not-pressed.
|
||||
*/
|
||||
_gamepadButton(gp_num, btn_num, val) {
|
||||
this.send("js,b," + btn_num + "," + val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the gamepad axis to the WebRTC app.
|
||||
*
|
||||
* @param {number} gp_num - the gamepad number
|
||||
* @param {number} axis_num - the uinput converted axis number
|
||||
* @param {number} val - the normalize value between [0, 255]
|
||||
*/
|
||||
_gamepadAxis(gp_num, axis_num, val) {
|
||||
this.send("js,a," + axis_num + "," + val)
|
||||
}
|
||||
|
||||
/**
|
||||
* When fullscreen is entered, request keyboard and pointer lock.
|
||||
*/
|
||||
|
@ -405,7 +345,8 @@ class Input {
|
|||
this.keyboard.reset();
|
||||
|
||||
// Reset stuck keys on server side.
|
||||
this.send("kr");
|
||||
// FIXME: How to implement resetting keyboard with the GstNavigation interface
|
||||
// this.send("kr");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -438,26 +379,16 @@ class Input {
|
|||
*/
|
||||
attach() {
|
||||
this.listeners.push(addListener(this.element, 'resize', this._windowMath, this));
|
||||
this.listeners.push(addListener(this.element, 'mousewheel', this._mouseWheel, this));
|
||||
this.listeners.push(addListener(this.element, 'wheel', this._wheel, this));
|
||||
this.listeners.push(addListener(this.element, 'contextmenu', this._contextMenu, this));
|
||||
this.listeners.push(addListener(this.element.parentElement, 'fullscreenchange', this._onFullscreenChange, this));
|
||||
this.listeners.push(addListener(document, 'pointerlockchange', this._pointerLock, this));
|
||||
this.listeners.push(addListener(window, 'keydown', this._key, this));
|
||||
this.listeners.push(addListener(window, 'keyup', this._key, this));
|
||||
this.listeners.push(addListener(window, 'resize', this._windowMath, this));
|
||||
this.listeners.push(addListener(window, 'resize', this._resizeStart, this));
|
||||
|
||||
// Gamepad support
|
||||
this.listeners.push(addListener(window, 'gamepadconnected', this._gamepadConnected, this));
|
||||
this.listeners.push(addListener(window, 'gamepaddisconnected', this._gamepadDisconnect, this));
|
||||
|
||||
if ('ontouchstart' in window) {
|
||||
this.listeners.push(addListener(window, 'touchstart', this._touch, this));
|
||||
this.listeners.push(addListener(this.element, 'touchend', this._touch, this));
|
||||
this.listeners.push(addListener(this.element, 'touchmove', this._touch, this));
|
||||
|
||||
console.log("Enabling mouse pointer display for touch devices.");
|
||||
this.send("p,1");
|
||||
console.warning("FIXME: Enabling mouse pointer display for touch devices.");
|
||||
} else {
|
||||
this.listeners.push(addListener(this.element, 'mousemove', this._mouseButtonMovement, this));
|
||||
this.listeners.push(addListener(this.element, 'mousedown', this._mouseButtonMovement, this));
|
||||
|
@ -471,12 +402,12 @@ class Input {
|
|||
}, this));
|
||||
|
||||
// Using guacamole keyboard because it has the keysym translations.
|
||||
this.keyboard = new Guacamole.Keyboard(window);
|
||||
this.keyboard = new Keyboard(window);
|
||||
this.keyboard.onkeydown = (keysym) => {
|
||||
this.send("kd," + keysym);
|
||||
this.send(JSON.stringify( {"event": "KeyPress", "key": keysym}));
|
||||
};
|
||||
this.keyboard.onkeyup = (keysym) => {
|
||||
this.send("ku," + keysym);
|
||||
this.send(JSON.stringify( {"event": "KeyRelease", "key": keysym}));
|
||||
};
|
||||
|
||||
this._windowMath();
|
||||
|
@ -490,7 +421,8 @@ class Input {
|
|||
this.keyboard.onkeyup = null;
|
||||
this.keyboard.reset();
|
||||
delete this.keyboard;
|
||||
this.send("kr");
|
||||
// FIXME: How to implement resetting keyboard with the GstNavigation interface
|
||||
// this.send("kr");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
3280
www/keyboard.js
Normal file
3280
www/keyboard.js
Normal file
File diff suppressed because it is too large
Load diff
|
@ -52,6 +52,8 @@ function Session(our_id, peer_id, closed_callback) {
|
|||
this.peer_id = peer_id;
|
||||
this.our_id = our_id;
|
||||
this.closed_callback = closed_callback;
|
||||
this.data_channel = null;
|
||||
this.input = null;
|
||||
|
||||
this.getVideoElement = function() {
|
||||
return document.getElementById("stream-" + this.our_id);
|
||||
|
@ -76,6 +78,9 @@ function Session(our_id, peer_id, closed_callback) {
|
|||
this.ws_conn.close();
|
||||
this.ws_conn = null;
|
||||
}
|
||||
|
||||
this.input && this.input.detach();
|
||||
this.data_channel = null;
|
||||
};
|
||||
|
||||
this.handleIncomingError = function(error) {
|
||||
|
@ -240,20 +245,36 @@ function Session(our_id, peer_id, closed_callback) {
|
|||
this.peer_connection.onaddstream = this.onRemoteStreamAdded.bind(this);
|
||||
|
||||
this.peer_connection.ondatachannel = (event) => {
|
||||
console.log('Data channel created');
|
||||
let receive_channel = event.channel;
|
||||
let buffer = [];
|
||||
console.log(`Data channel created: ${event.channel.label}`);
|
||||
this.data_channel = event.channel;
|
||||
|
||||
receive_channel.onopen = (event) => {
|
||||
console.log ("Receive channel opened");
|
||||
video_element = this.getVideoElement();
|
||||
if (video_element) {
|
||||
this.input = new Input(video_element, (data) => {
|
||||
if (this.data_channel) {
|
||||
console.log(`Navigation data: ${data}`);
|
||||
this.data_channel.send(data);
|
||||
}
|
||||
});
|
||||
}
|
||||
receive_channel.onclose = (event) => {
|
||||
console.log ("Receive channel closed");
|
||||
|
||||
this.data_channel.onopen = (event) => {
|
||||
console.log("Receive channel opened, attaching input");
|
||||
this.input.attach();
|
||||
}
|
||||
receive_channel.onerror = (event) => {
|
||||
console.log ("Error on receive channel", event.data);
|
||||
this.data_channel.onclose = (event) => {
|
||||
console.info("Receive channel closed");
|
||||
this.input && this.input.detach();
|
||||
this.data_channel = null;
|
||||
}
|
||||
receive_channel.onmessage = (event) => {
|
||||
this.data_channel.onerror = (event) => {
|
||||
this.input && this.input.detach();
|
||||
console.warn("Error on receive channel", event.data);
|
||||
this.data_channel = null;
|
||||
}
|
||||
|
||||
let buffer = [];
|
||||
this.data_channel.onmessage = (event) => {
|
||||
if (typeof event.data === 'string' || event.data instanceof String) {
|
||||
if (event.data == 'BEGIN_IMAGE')
|
||||
buffer = [];
|
||||
|
|
Loading…
Reference in a new issue