init project
5
.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
.idea/
|
||||||
|
node_modules/
|
||||||
|
npm-debug.log
|
||||||
|
static/bower_components
|
||||||
|
keys/
|
BIN
.package.json.swp
Normal file
119
README.md
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
[![License badge](https://img.shields.io/badge/license-LGPL-blue.svg)](http://www.gnu.org/licenses/lgpl-2.1.html)
|
||||||
|
[![Documentation badge](https://readthedocs.org/projects/fiware-orion/badge/?version=latest)](http://doc-kurento.readthedocs.org/en/latest/)
|
||||||
|
[![Docker badge](https://img.shields.io/docker/pulls/fiware/orion.svg)](https://hub.docker.com/r/fiware/stream-oriented-kurento/)
|
||||||
|
[![Support badge]( https://img.shields.io/badge/support-sof-yellowgreen.svg)](http://stackoverflow.com/questions/tagged/kurento)
|
||||||
|
|
||||||
|
[![][KurentoImage]][Kurento]
|
||||||
|
|
||||||
|
Copyright © 2013-2016 [Kurento]. Licensed under [LGPL v2.1 License].
|
||||||
|
|
||||||
|
kurento-one2many-call
|
||||||
|
=====================
|
||||||
|
|
||||||
|
Kurento Java Tutorial: WebRTC one to many video call.
|
||||||
|
|
||||||
|
Running this tutorial
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
In order to run this tutorial, please read the following [instructions].
|
||||||
|
|
||||||
|
What is Kurento
|
||||||
|
---------------
|
||||||
|
|
||||||
|
Kurento is an open source software project providing a platform suitable
|
||||||
|
for creating modular applications with advanced real-time communication
|
||||||
|
capabilities. For knowing more about Kurento, please visit the Kurento
|
||||||
|
project website: http://www.kurento.org.
|
||||||
|
|
||||||
|
Kurento is part of [FIWARE]. For further information on the relationship of
|
||||||
|
FIWARE and Kurento check the [Kurento FIWARE Catalog Entry]
|
||||||
|
|
||||||
|
Kurento is part of the [NUBOMEDIA] research initiative.
|
||||||
|
|
||||||
|
Documentation
|
||||||
|
-------------
|
||||||
|
|
||||||
|
The Kurento project provides detailed [documentation] including tutorials,
|
||||||
|
installation and development guides. A simplified version of the documentation
|
||||||
|
can be found on [readthedocs.org]. The [Open API specification] a.k.a. Kurento
|
||||||
|
Protocol is also available on [apiary.io].
|
||||||
|
|
||||||
|
Source
|
||||||
|
------
|
||||||
|
|
||||||
|
Code for other Kurento projects can be found in the [GitHub Kurento Group].
|
||||||
|
|
||||||
|
News and Website
|
||||||
|
----------------
|
||||||
|
|
||||||
|
Check the [Kurento blog]
|
||||||
|
Follow us on Twitter @[kurentoms].
|
||||||
|
|
||||||
|
Issue tracker
|
||||||
|
-------------
|
||||||
|
|
||||||
|
Issues and bug reports should be posted to the [GitHub Kurento bugtracker]
|
||||||
|
|
||||||
|
Licensing and distribution
|
||||||
|
--------------------------
|
||||||
|
|
||||||
|
Software associated to Kurento is provided as open source under GNU Library or
|
||||||
|
"Lesser" General Public License, version 2.1 (LGPL-2.1). Please check the
|
||||||
|
specific terms and conditions linked to this open source license at
|
||||||
|
http://opensource.org/licenses/LGPL-2.1. Please note that software derived as a
|
||||||
|
result of modifying the source code of Kurento software in order to fix a bug
|
||||||
|
or incorporate enhancements is considered a derivative work of the product.
|
||||||
|
Software that merely uses or aggregates (i.e. links to) an otherwise unmodified
|
||||||
|
version of existing software is not considered a derivative work.
|
||||||
|
|
||||||
|
Contribution policy
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
You can contribute to the Kurento community through bug-reports, bug-fixes, new
|
||||||
|
code or new documentation. For contributing to the Kurento community, drop a
|
||||||
|
post to the [Kurento Public Mailing List] providing full information about your
|
||||||
|
contribution and its value. In your contributions, you must comply with the
|
||||||
|
following guidelines
|
||||||
|
|
||||||
|
* You must specify the specific contents of your contribution either through a
|
||||||
|
detailed bug description, through a pull-request or through a patch.
|
||||||
|
* You must specify the licensing restrictions of the code you contribute.
|
||||||
|
* For newly created code to be incorporated in the Kurento code-base, you must
|
||||||
|
accept Kurento to own the code copyright, so that its open source nature is
|
||||||
|
guaranteed.
|
||||||
|
* You must justify appropriately the need and value of your contribution. The
|
||||||
|
Kurento project has no obligations in relation to accepting contributions
|
||||||
|
from third parties.
|
||||||
|
* The Kurento project leaders have the right of asking for further
|
||||||
|
explanations, tests or validations of any code contributed to the community
|
||||||
|
before it being incorporated into the Kurento code-base. You must be ready to
|
||||||
|
addressing all these kind of concerns before having your code approved.
|
||||||
|
|
||||||
|
Support
|
||||||
|
-------
|
||||||
|
|
||||||
|
The Kurento project provides community support through the [Kurento Public
|
||||||
|
Mailing List] and through [StackOverflow] using the tags *kurento* and
|
||||||
|
*fiware-kurento*.
|
||||||
|
|
||||||
|
Before asking for support, please read first the [Kurento Netiquette Guidelines]
|
||||||
|
|
||||||
|
[documentation]: http://www.kurento.org/documentation
|
||||||
|
[FIWARE]: http://www.fiware.org
|
||||||
|
[GitHub Kurento bugtracker]: https://github.com/Kurento/bugtracker/issues
|
||||||
|
[GitHub Kurento Group]: https://github.com/kurento
|
||||||
|
[kurentoms]: http://twitter.com/kurentoms
|
||||||
|
[Kurento]: http://kurento.org
|
||||||
|
[Kurento Blog]: http://www.kurento.org/blog
|
||||||
|
[Kurento FIWARE Catalog Entry]: http://catalogue.fiware.org/enablers/stream-oriented-kurento
|
||||||
|
[Kurento Netiquette Guidelines]: http://www.kurento.org/blog/kurento-netiquette-guidelines
|
||||||
|
[Kurento Public Mailing list]: https://groups.google.com/forum/#!forum/kurento
|
||||||
|
[KurentoImage]: https://secure.gravatar.com/avatar/21a2a12c56b2a91c8918d5779f1778bf?s=120
|
||||||
|
[LGPL v2.1 License]: http://www.gnu.org/licenses/lgpl-2.1.html
|
||||||
|
[NUBOMEDIA]: http://www.nubomedia.eu
|
||||||
|
[StackOverflow]: http://stackoverflow.com/search?q=kurento
|
||||||
|
[Read-the-docs]: http://read-the-docs.readthedocs.org/
|
||||||
|
[readthedocs.org]: http://kurento.readthedocs.org/
|
||||||
|
[Open API specification]: http://kurento.github.io/doc-kurento/
|
||||||
|
[apiary.io]: http://docs.streamoriented.apiary.io/
|
||||||
|
[instructions]: http://www.kurento.org/docs/current/tutorials/node/tutorial-one2many.html
|
822
package-lock.json
generated
Normal file
@ -0,0 +1,822 @@
|
|||||||
|
{
|
||||||
|
"name": "kurento-one2many-call",
|
||||||
|
"version": "6.2.2-dev",
|
||||||
|
"lockfileVersion": 1,
|
||||||
|
"requires": true,
|
||||||
|
"dependencies": {
|
||||||
|
"accepts": {
|
||||||
|
"version": "1.2.13",
|
||||||
|
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.2.13.tgz",
|
||||||
|
"integrity": "sha1-5fHzkoxtlf2WVYw27D2dDeSm7Oo=",
|
||||||
|
"requires": {
|
||||||
|
"mime-types": "2.1.18",
|
||||||
|
"negotiator": "0.5.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"after": {
|
||||||
|
"version": "0.8.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz",
|
||||||
|
"integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8="
|
||||||
|
},
|
||||||
|
"arraybuffer.slice": {
|
||||||
|
"version": "0.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.6.tgz",
|
||||||
|
"integrity": "sha1-8zshWfBTKj8xB6JywMz70a0peco="
|
||||||
|
},
|
||||||
|
"asap": {
|
||||||
|
"version": "2.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
|
||||||
|
"integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY="
|
||||||
|
},
|
||||||
|
"async": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/async/-/async-2.0.1.tgz",
|
||||||
|
"integrity": "sha1-twnMAoCpw28J9FNr6CPIOKkEniU=",
|
||||||
|
"requires": {
|
||||||
|
"lodash": "4.17.10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"backo2": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz",
|
||||||
|
"integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc="
|
||||||
|
},
|
||||||
|
"backoff": {
|
||||||
|
"version": "2.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/backoff/-/backoff-2.3.0.tgz",
|
||||||
|
"integrity": "sha1-7nx+OAk/kuRyhZ22NedlJFT8Ieo="
|
||||||
|
},
|
||||||
|
"base64-arraybuffer": {
|
||||||
|
"version": "0.1.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz",
|
||||||
|
"integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg="
|
||||||
|
},
|
||||||
|
"base64id": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/base64id/-/base64id-1.0.0.tgz",
|
||||||
|
"integrity": "sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY="
|
||||||
|
},
|
||||||
|
"better-assert": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz",
|
||||||
|
"integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=",
|
||||||
|
"requires": {
|
||||||
|
"callsite": "1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"bindings": {
|
||||||
|
"version": "1.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/bindings/-/bindings-1.2.1.tgz",
|
||||||
|
"integrity": "sha1-FK1hE4EtLTfXLme0ystLtyZQXxE="
|
||||||
|
},
|
||||||
|
"blob": {
|
||||||
|
"version": "0.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/blob/-/blob-0.0.4.tgz",
|
||||||
|
"integrity": "sha1-vPEwUspURj8w+fx+lbmkdjCpSSE="
|
||||||
|
},
|
||||||
|
"bower": {
|
||||||
|
"version": "1.8.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/bower/-/bower-1.8.4.tgz",
|
||||||
|
"integrity": "sha1-54dqB23rgTf30GUl3F6MZtuC8oo=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"bufferutil": {
|
||||||
|
"version": "1.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-1.2.1.tgz",
|
||||||
|
"integrity": "sha1-N75dNuHgZJIiHmjUdLGsWOUQy9c=",
|
||||||
|
"requires": {
|
||||||
|
"bindings": "1.2.1",
|
||||||
|
"nan": "2.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"callsite": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz",
|
||||||
|
"integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA="
|
||||||
|
},
|
||||||
|
"commander": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/commander/-/commander-2.1.0.tgz",
|
||||||
|
"integrity": "sha1-0SG7roYNmZKj1Re6lvVliOR8Z4E="
|
||||||
|
},
|
||||||
|
"component-bind": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz",
|
||||||
|
"integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E="
|
||||||
|
},
|
||||||
|
"component-emitter": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.1.2.tgz",
|
||||||
|
"integrity": "sha1-KWWU8nU9qmOZbSrwjRWpURbJrsM="
|
||||||
|
},
|
||||||
|
"component-inherit": {
|
||||||
|
"version": "0.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz",
|
||||||
|
"integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM="
|
||||||
|
},
|
||||||
|
"content-disposition": {
|
||||||
|
"version": "0.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.0.tgz",
|
||||||
|
"integrity": "sha1-QoT+auBjCHRjnkToCkGMKTQTXp4="
|
||||||
|
},
|
||||||
|
"content-type": {
|
||||||
|
"version": "1.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
|
||||||
|
"integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
|
||||||
|
},
|
||||||
|
"cookie": {
|
||||||
|
"version": "0.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.1.2.tgz",
|
||||||
|
"integrity": "sha1-cv7D0k5Io0Mgc9kMEmQgBQYQBLE="
|
||||||
|
},
|
||||||
|
"cookie-signature": {
|
||||||
|
"version": "1.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
|
||||||
|
"integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
|
||||||
|
},
|
||||||
|
"crc": {
|
||||||
|
"version": "3.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/crc/-/crc-3.2.1.tgz",
|
||||||
|
"integrity": "sha1-XZyPt3okXNXsopHl0tAFM0urAII="
|
||||||
|
},
|
||||||
|
"debug": {
|
||||||
|
"version": "2.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz",
|
||||||
|
"integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=",
|
||||||
|
"requires": {
|
||||||
|
"ms": "0.7.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"depd": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/depd/-/depd-1.0.1.tgz",
|
||||||
|
"integrity": "sha1-gK7GTJ1tl+ZcwqnKqTwKpqv3Oqo="
|
||||||
|
},
|
||||||
|
"destroy": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.3.tgz",
|
||||||
|
"integrity": "sha1-tDO0ck5x/YVR2YhRdIUcX8N34sk="
|
||||||
|
},
|
||||||
|
"ee-first": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.0.tgz",
|
||||||
|
"integrity": "sha1-ag18YiHkkP7v2S7D9EHJzozQl/Q="
|
||||||
|
},
|
||||||
|
"engine.io": {
|
||||||
|
"version": "1.8.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/engine.io/-/engine.io-1.8.5.tgz",
|
||||||
|
"integrity": "sha512-j1DWIcktw4hRwrv6nWx++5nFH2X64x16MAG2P0Lmi5Dvdfi3I+Jhc7JKJIdAmDJa+5aZ/imHV7dWRPy2Cqjh3A==",
|
||||||
|
"requires": {
|
||||||
|
"accepts": "1.3.3",
|
||||||
|
"base64id": "1.0.0",
|
||||||
|
"cookie": "0.3.1",
|
||||||
|
"debug": "2.3.3",
|
||||||
|
"engine.io-parser": "1.3.2",
|
||||||
|
"ws": "1.1.5"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"accepts": {
|
||||||
|
"version": "1.3.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.3.tgz",
|
||||||
|
"integrity": "sha1-w8p0NJOGSMPg2cHjKN1otiLChMo=",
|
||||||
|
"requires": {
|
||||||
|
"mime-types": "2.1.18",
|
||||||
|
"negotiator": "0.6.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"cookie": {
|
||||||
|
"version": "0.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz",
|
||||||
|
"integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s="
|
||||||
|
},
|
||||||
|
"debug": {
|
||||||
|
"version": "2.3.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz",
|
||||||
|
"integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=",
|
||||||
|
"requires": {
|
||||||
|
"ms": "0.7.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ms": {
|
||||||
|
"version": "0.7.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz",
|
||||||
|
"integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U="
|
||||||
|
},
|
||||||
|
"negotiator": {
|
||||||
|
"version": "0.6.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz",
|
||||||
|
"integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"engine.io-client": {
|
||||||
|
"version": "1.8.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-1.8.5.tgz",
|
||||||
|
"integrity": "sha512-AYTgHyeVUPitsseqjoedjhYJapNVoSPShbZ+tEUX9/73jgZ/Z3sUlJf9oYgdEBBdVhupUpUqSxH0kBCXlQnmZg==",
|
||||||
|
"requires": {
|
||||||
|
"component-emitter": "1.2.1",
|
||||||
|
"component-inherit": "0.0.3",
|
||||||
|
"debug": "2.3.3",
|
||||||
|
"engine.io-parser": "1.3.2",
|
||||||
|
"has-cors": "1.1.0",
|
||||||
|
"indexof": "0.0.1",
|
||||||
|
"parsejson": "0.0.3",
|
||||||
|
"parseqs": "0.0.5",
|
||||||
|
"parseuri": "0.0.5",
|
||||||
|
"ws": "1.1.5",
|
||||||
|
"xmlhttprequest-ssl": "1.5.3",
|
||||||
|
"yeast": "0.1.2"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"component-emitter": {
|
||||||
|
"version": "1.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
|
||||||
|
"integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY="
|
||||||
|
},
|
||||||
|
"debug": {
|
||||||
|
"version": "2.3.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz",
|
||||||
|
"integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=",
|
||||||
|
"requires": {
|
||||||
|
"ms": "0.7.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ms": {
|
||||||
|
"version": "0.7.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz",
|
||||||
|
"integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"engine.io-parser": {
|
||||||
|
"version": "1.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-1.3.2.tgz",
|
||||||
|
"integrity": "sha1-k3sHnwAH0Ik+xW1GyyILjLQ1Igo=",
|
||||||
|
"requires": {
|
||||||
|
"after": "0.8.2",
|
||||||
|
"arraybuffer.slice": "0.0.6",
|
||||||
|
"base64-arraybuffer": "0.1.5",
|
||||||
|
"blob": "0.0.4",
|
||||||
|
"has-binary": "0.1.7",
|
||||||
|
"wtf-8": "1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"error-tojson": {
|
||||||
|
"version": "0.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/error-tojson/-/error-tojson-0.0.1.tgz",
|
||||||
|
"integrity": "sha1-p7GqlP/ADpB4wuuibiBL2Hzyy7k="
|
||||||
|
},
|
||||||
|
"es6-promise": {
|
||||||
|
"version": "4.2.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.4.tgz",
|
||||||
|
"integrity": "sha512-/NdNZVJg+uZgtm9eS3O6lrOLYmQag2DjdEXuPaHlZ6RuVqgqaVZfgYCepEIKsLqwdQArOPtC3XzRLqGGfT8KQQ=="
|
||||||
|
},
|
||||||
|
"escape-html": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.1.tgz",
|
||||||
|
"integrity": "sha1-GBoobq05ejmpKFfPsdQwUuNWv/A="
|
||||||
|
},
|
||||||
|
"etag": {
|
||||||
|
"version": "1.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/etag/-/etag-1.6.0.tgz",
|
||||||
|
"integrity": "sha1-i8ssavElTEgd/IuZfJBu9ORCwgc=",
|
||||||
|
"requires": {
|
||||||
|
"crc": "3.2.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"express": {
|
||||||
|
"version": "4.12.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/express/-/express-4.12.4.tgz",
|
||||||
|
"integrity": "sha1-j+wlECVbxrLlgQfEgjnA+jB8GqI=",
|
||||||
|
"requires": {
|
||||||
|
"accepts": "1.2.13",
|
||||||
|
"content-disposition": "0.5.0",
|
||||||
|
"content-type": "1.0.4",
|
||||||
|
"cookie": "0.1.2",
|
||||||
|
"cookie-signature": "1.0.6",
|
||||||
|
"debug": "2.2.0",
|
||||||
|
"depd": "1.0.1",
|
||||||
|
"escape-html": "1.0.1",
|
||||||
|
"etag": "1.6.0",
|
||||||
|
"finalhandler": "0.3.6",
|
||||||
|
"fresh": "0.2.4",
|
||||||
|
"merge-descriptors": "1.0.0",
|
||||||
|
"methods": "1.1.2",
|
||||||
|
"on-finished": "2.2.1",
|
||||||
|
"parseurl": "1.3.2",
|
||||||
|
"path-to-regexp": "0.1.3",
|
||||||
|
"proxy-addr": "1.0.10",
|
||||||
|
"qs": "2.4.2",
|
||||||
|
"range-parser": "1.0.3",
|
||||||
|
"send": "0.12.3",
|
||||||
|
"serve-static": "1.9.3",
|
||||||
|
"type-is": "1.6.16",
|
||||||
|
"utils-merge": "1.0.0",
|
||||||
|
"vary": "1.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"extend": {
|
||||||
|
"version": "3.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz",
|
||||||
|
"integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ="
|
||||||
|
},
|
||||||
|
"finalhandler": {
|
||||||
|
"version": "0.3.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-0.3.6.tgz",
|
||||||
|
"integrity": "sha1-2vnEFhsbBuABRmsUEd/baXO+E4s=",
|
||||||
|
"requires": {
|
||||||
|
"debug": "2.2.0",
|
||||||
|
"escape-html": "1.0.1",
|
||||||
|
"on-finished": "2.2.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"forwarded": {
|
||||||
|
"version": "0.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
|
||||||
|
"integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ="
|
||||||
|
},
|
||||||
|
"fresh": {
|
||||||
|
"version": "0.2.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.2.4.tgz",
|
||||||
|
"integrity": "sha1-NYJJkgbJcjcUGQ7ddLRgT+tKYUw="
|
||||||
|
},
|
||||||
|
"has-binary": {
|
||||||
|
"version": "0.1.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/has-binary/-/has-binary-0.1.7.tgz",
|
||||||
|
"integrity": "sha1-aOYesWIQyVRaClzOBqhzkS/h5ow=",
|
||||||
|
"requires": {
|
||||||
|
"isarray": "0.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"has-cors": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz",
|
||||||
|
"integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk="
|
||||||
|
},
|
||||||
|
"indexof": {
|
||||||
|
"version": "0.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz",
|
||||||
|
"integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10="
|
||||||
|
},
|
||||||
|
"inherits": {
|
||||||
|
"version": "2.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
|
||||||
|
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
|
||||||
|
},
|
||||||
|
"ipaddr.js": {
|
||||||
|
"version": "1.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.0.5.tgz",
|
||||||
|
"integrity": "sha1-X6eM8wG4JceKvDBC2BJyMEnqI8c="
|
||||||
|
},
|
||||||
|
"isarray": {
|
||||||
|
"version": "0.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
|
||||||
|
"integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
|
||||||
|
},
|
||||||
|
"isbuffer": {
|
||||||
|
"version": "0.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/isbuffer/-/isbuffer-0.0.0.tgz",
|
||||||
|
"integrity": "sha1-OMFG2d9Si4v5sHAcPUPPEt8/w5s="
|
||||||
|
},
|
||||||
|
"json3": {
|
||||||
|
"version": "3.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz",
|
||||||
|
"integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE="
|
||||||
|
},
|
||||||
|
"kurento-client": {
|
||||||
|
"version": "github:Kurento/kurento-client-js#efb160e85a4b1f376307fe1979c9fbcb5f978393",
|
||||||
|
"requires": {
|
||||||
|
"async": "2.0.1",
|
||||||
|
"error-tojson": "0.0.1",
|
||||||
|
"es6-promise": "4.2.4",
|
||||||
|
"extend": "3.0.1",
|
||||||
|
"inherits": "2.0.3",
|
||||||
|
"kurento-client-core": "github:Kurento/kurento-client-core-js#2160f8e6938f138b52b72a5c5c354d1e5fce1ca0",
|
||||||
|
"kurento-client-elements": "github:Kurento/kurento-client-elements-js#cbd1ff67fbf0faddc9f6f266bb33e449bc9e1f81",
|
||||||
|
"kurento-client-filters": "github:Kurento/kurento-client-filters-js#51308da53e432a2db9559dcdb308d87951417bf0",
|
||||||
|
"kurento-jsonrpc": "github:Kurento/kurento-jsonrpc-js#827827bbeb557e1c1901f5a562c4c700b9a51401",
|
||||||
|
"minimist": "1.2.0",
|
||||||
|
"promise": "7.1.1",
|
||||||
|
"promisecallback": "0.0.4",
|
||||||
|
"reconnect-ws": "github:KurentoForks/reconnect-ws#f287385d75861654528c352e60221f95c9209f8a"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"kurento-client-core": {
|
||||||
|
"version": "github:Kurento/kurento-client-core-js#2160f8e6938f138b52b72a5c5c354d1e5fce1ca0"
|
||||||
|
},
|
||||||
|
"kurento-client-elements": {
|
||||||
|
"version": "github:Kurento/kurento-client-elements-js#cbd1ff67fbf0faddc9f6f266bb33e449bc9e1f81"
|
||||||
|
},
|
||||||
|
"kurento-client-filters": {
|
||||||
|
"version": "github:Kurento/kurento-client-filters-js#51308da53e432a2db9559dcdb308d87951417bf0"
|
||||||
|
},
|
||||||
|
"kurento-jsonrpc": {
|
||||||
|
"version": "github:Kurento/kurento-jsonrpc-js#827827bbeb557e1c1901f5a562c4c700b9a51401",
|
||||||
|
"requires": {
|
||||||
|
"bufferutil": "1.2.1",
|
||||||
|
"inherits": "2.0.3",
|
||||||
|
"utf-8-validate": "1.2.2",
|
||||||
|
"ws": "1.1.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"reconnect-core": {
|
||||||
|
"version": "github:KurentoForks/reconnect-core#921d43e91578abb2fb2613f585c010c1939cf734",
|
||||||
|
"requires": {
|
||||||
|
"backoff": "2.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"reconnect-ws": {
|
||||||
|
"version": "github:KurentoForks/reconnect-ws#f287385d75861654528c352e60221f95c9209f8a",
|
||||||
|
"requires": {
|
||||||
|
"reconnect-core": "github:KurentoForks/reconnect-core#921d43e91578abb2fb2613f585c010c1939cf734",
|
||||||
|
"websocket-stream": "0.5.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"lodash": {
|
||||||
|
"version": "4.17.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz",
|
||||||
|
"integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg=="
|
||||||
|
},
|
||||||
|
"media-typer": {
|
||||||
|
"version": "0.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
|
||||||
|
"integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
|
||||||
|
},
|
||||||
|
"merge-descriptors": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.0.tgz",
|
||||||
|
"integrity": "sha1-IWnPdTjhsMyH+4jhUC2EdLv3mGQ="
|
||||||
|
},
|
||||||
|
"methods": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
|
||||||
|
"integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
|
||||||
|
},
|
||||||
|
"mime": {
|
||||||
|
"version": "1.3.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz",
|
||||||
|
"integrity": "sha1-EV+eO2s9rylZmDyzjxSaLUDrXVM="
|
||||||
|
},
|
||||||
|
"mime-db": {
|
||||||
|
"version": "1.33.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz",
|
||||||
|
"integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ=="
|
||||||
|
},
|
||||||
|
"mime-types": {
|
||||||
|
"version": "2.1.18",
|
||||||
|
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz",
|
||||||
|
"integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==",
|
||||||
|
"requires": {
|
||||||
|
"mime-db": "1.33.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"minimist": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
|
||||||
|
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
|
||||||
|
},
|
||||||
|
"ms": {
|
||||||
|
"version": "0.7.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz",
|
||||||
|
"integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg="
|
||||||
|
},
|
||||||
|
"nan": {
|
||||||
|
"version": "2.10.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz",
|
||||||
|
"integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA=="
|
||||||
|
},
|
||||||
|
"negotiator": {
|
||||||
|
"version": "0.5.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.5.3.tgz",
|
||||||
|
"integrity": "sha1-Jp1cR2gQ7JLtvntsLygxY4T5p+g="
|
||||||
|
},
|
||||||
|
"object-assign": {
|
||||||
|
"version": "4.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.0.tgz",
|
||||||
|
"integrity": "sha1-ejs9DpgGPUP0wD8uiubNUahog6A="
|
||||||
|
},
|
||||||
|
"object-component": {
|
||||||
|
"version": "0.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz",
|
||||||
|
"integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE="
|
||||||
|
},
|
||||||
|
"on-finished": {
|
||||||
|
"version": "2.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.2.1.tgz",
|
||||||
|
"integrity": "sha1-XIXBzDYpn3gCllP2Z/J7a5nrwCk=",
|
||||||
|
"requires": {
|
||||||
|
"ee-first": "1.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"version": "0.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/options/-/options-0.0.6.tgz",
|
||||||
|
"integrity": "sha1-7CLTEoBrtT5zF3Pnza788cZDEo8="
|
||||||
|
},
|
||||||
|
"parsejson": {
|
||||||
|
"version": "0.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/parsejson/-/parsejson-0.0.3.tgz",
|
||||||
|
"integrity": "sha1-q343WfIJ7OmUN5c/fQ8fZK4OZKs=",
|
||||||
|
"requires": {
|
||||||
|
"better-assert": "1.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"parseqs": {
|
||||||
|
"version": "0.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz",
|
||||||
|
"integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=",
|
||||||
|
"requires": {
|
||||||
|
"better-assert": "1.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"parseuri": {
|
||||||
|
"version": "0.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz",
|
||||||
|
"integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=",
|
||||||
|
"requires": {
|
||||||
|
"better-assert": "1.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"parseurl": {
|
||||||
|
"version": "1.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz",
|
||||||
|
"integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M="
|
||||||
|
},
|
||||||
|
"path-to-regexp": {
|
||||||
|
"version": "0.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.3.tgz",
|
||||||
|
"integrity": "sha1-IbmrgidCed4lsVbqCP0SylG4rss="
|
||||||
|
},
|
||||||
|
"promise": {
|
||||||
|
"version": "7.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/promise/-/promise-7.1.1.tgz",
|
||||||
|
"integrity": "sha1-SJZUxpJha4qlWwck+oCbt9tJxb8=",
|
||||||
|
"requires": {
|
||||||
|
"asap": "2.0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"promisecallback": {
|
||||||
|
"version": "0.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/promisecallback/-/promisecallback-0.0.4.tgz",
|
||||||
|
"integrity": "sha1-uTTxPATkQ2IrTWbeTkLqX2zmbnQ="
|
||||||
|
},
|
||||||
|
"proxy-addr": {
|
||||||
|
"version": "1.0.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-1.0.10.tgz",
|
||||||
|
"integrity": "sha1-DUCoL4Afw1VWfS7LZe/j8HfxIcU=",
|
||||||
|
"requires": {
|
||||||
|
"forwarded": "0.1.2",
|
||||||
|
"ipaddr.js": "1.0.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"qs": {
|
||||||
|
"version": "2.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/qs/-/qs-2.4.2.tgz",
|
||||||
|
"integrity": "sha1-9854jld33wtQENp/fE5zujJHD1o="
|
||||||
|
},
|
||||||
|
"range-parser": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.0.3.tgz",
|
||||||
|
"integrity": "sha1-aHKCNTXGkuLCoBA4Jq/YLC4P8XU="
|
||||||
|
},
|
||||||
|
"send": {
|
||||||
|
"version": "0.12.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/send/-/send-0.12.3.tgz",
|
||||||
|
"integrity": "sha1-zRLcWP3iHk+RkCs5sv2gWnptm9w=",
|
||||||
|
"requires": {
|
||||||
|
"debug": "2.2.0",
|
||||||
|
"depd": "1.0.1",
|
||||||
|
"destroy": "1.0.3",
|
||||||
|
"escape-html": "1.0.1",
|
||||||
|
"etag": "1.6.0",
|
||||||
|
"fresh": "0.2.4",
|
||||||
|
"mime": "1.3.4",
|
||||||
|
"ms": "0.7.1",
|
||||||
|
"on-finished": "2.2.1",
|
||||||
|
"range-parser": "1.0.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"serve-static": {
|
||||||
|
"version": "1.9.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.9.3.tgz",
|
||||||
|
"integrity": "sha1-X42gcyOtOF/z3FQfGnkXsuQ261c=",
|
||||||
|
"requires": {
|
||||||
|
"escape-html": "1.0.1",
|
||||||
|
"parseurl": "1.3.2",
|
||||||
|
"send": "0.12.3",
|
||||||
|
"utils-merge": "1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"socket.io": {
|
||||||
|
"version": "1.7.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/socket.io/-/socket.io-1.7.4.tgz",
|
||||||
|
"integrity": "sha1-L37O3DORvy1cc+KR/iM+bjTU3QA=",
|
||||||
|
"requires": {
|
||||||
|
"debug": "2.3.3",
|
||||||
|
"engine.io": "1.8.5",
|
||||||
|
"has-binary": "0.1.7",
|
||||||
|
"object-assign": "4.1.0",
|
||||||
|
"socket.io-adapter": "0.5.0",
|
||||||
|
"socket.io-client": "1.7.4",
|
||||||
|
"socket.io-parser": "2.3.1"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"debug": {
|
||||||
|
"version": "2.3.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz",
|
||||||
|
"integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=",
|
||||||
|
"requires": {
|
||||||
|
"ms": "0.7.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ms": {
|
||||||
|
"version": "0.7.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz",
|
||||||
|
"integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"socket.io-adapter": {
|
||||||
|
"version": "0.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-0.5.0.tgz",
|
||||||
|
"integrity": "sha1-y21LuL7IHhB4uZZ3+c7QBGBmu4s=",
|
||||||
|
"requires": {
|
||||||
|
"debug": "2.3.3",
|
||||||
|
"socket.io-parser": "2.3.1"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"debug": {
|
||||||
|
"version": "2.3.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz",
|
||||||
|
"integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=",
|
||||||
|
"requires": {
|
||||||
|
"ms": "0.7.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ms": {
|
||||||
|
"version": "0.7.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz",
|
||||||
|
"integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"socket.io-client": {
|
||||||
|
"version": "1.7.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-1.7.4.tgz",
|
||||||
|
"integrity": "sha1-7J+CA1btme9tNX8HVtZIcXvdQoE=",
|
||||||
|
"requires": {
|
||||||
|
"backo2": "1.0.2",
|
||||||
|
"component-bind": "1.0.0",
|
||||||
|
"component-emitter": "1.2.1",
|
||||||
|
"debug": "2.3.3",
|
||||||
|
"engine.io-client": "1.8.5",
|
||||||
|
"has-binary": "0.1.7",
|
||||||
|
"indexof": "0.0.1",
|
||||||
|
"object-component": "0.0.3",
|
||||||
|
"parseuri": "0.0.5",
|
||||||
|
"socket.io-parser": "2.3.1",
|
||||||
|
"to-array": "0.1.4"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"component-emitter": {
|
||||||
|
"version": "1.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
|
||||||
|
"integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY="
|
||||||
|
},
|
||||||
|
"debug": {
|
||||||
|
"version": "2.3.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz",
|
||||||
|
"integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=",
|
||||||
|
"requires": {
|
||||||
|
"ms": "0.7.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ms": {
|
||||||
|
"version": "0.7.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz",
|
||||||
|
"integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"socket.io-parser": {
|
||||||
|
"version": "2.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-2.3.1.tgz",
|
||||||
|
"integrity": "sha1-3VMgJRA85Clpcya+/WQAX8/ltKA=",
|
||||||
|
"requires": {
|
||||||
|
"component-emitter": "1.1.2",
|
||||||
|
"debug": "2.2.0",
|
||||||
|
"isarray": "0.0.1",
|
||||||
|
"json3": "3.3.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"through": {
|
||||||
|
"version": "2.3.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
|
||||||
|
"integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU="
|
||||||
|
},
|
||||||
|
"tinycolor": {
|
||||||
|
"version": "0.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/tinycolor/-/tinycolor-0.0.1.tgz",
|
||||||
|
"integrity": "sha1-MgtaUtg6u1l42Bo+iH1K77FaYWQ="
|
||||||
|
},
|
||||||
|
"to-array": {
|
||||||
|
"version": "0.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz",
|
||||||
|
"integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA="
|
||||||
|
},
|
||||||
|
"type-is": {
|
||||||
|
"version": "1.6.16",
|
||||||
|
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz",
|
||||||
|
"integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==",
|
||||||
|
"requires": {
|
||||||
|
"media-typer": "0.3.0",
|
||||||
|
"mime-types": "2.1.18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ultron": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/ultron/-/ultron-1.0.2.tgz",
|
||||||
|
"integrity": "sha1-rOEWq1V80Zc4ak6I9GhTeMiy5Po="
|
||||||
|
},
|
||||||
|
"utf-8-validate": {
|
||||||
|
"version": "1.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-1.2.2.tgz",
|
||||||
|
"integrity": "sha1-i7hxpHQeCFxwSHynrNvX1tNgKes=",
|
||||||
|
"requires": {
|
||||||
|
"bindings": "1.2.1",
|
||||||
|
"nan": "2.4.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"nan": {
|
||||||
|
"version": "2.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/nan/-/nan-2.4.0.tgz",
|
||||||
|
"integrity": "sha1-+zxZ1F/k7/4hXwuJD4rfbrMtIjI="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"utils-merge": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.0.tgz",
|
||||||
|
"integrity": "sha1-ApT7kiu5N1FTVBxPcJYjHyh8ivg="
|
||||||
|
},
|
||||||
|
"vary": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/vary/-/vary-1.0.1.tgz",
|
||||||
|
"integrity": "sha1-meSYFWaihhGN+yuBc1ffeZM3bRA="
|
||||||
|
},
|
||||||
|
"websocket-stream": {
|
||||||
|
"version": "0.5.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/websocket-stream/-/websocket-stream-0.5.1.tgz",
|
||||||
|
"integrity": "sha1-YizR8FZvuEzgpNb4VFJvPcTXDkg=",
|
||||||
|
"requires": {
|
||||||
|
"isbuffer": "0.0.0",
|
||||||
|
"through": "2.3.8",
|
||||||
|
"ws": "0.4.32"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"nan": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/nan/-/nan-1.0.0.tgz",
|
||||||
|
"integrity": "sha1-riT4hQgY1mL8q1rPfzuVv6oszzg="
|
||||||
|
},
|
||||||
|
"ws": {
|
||||||
|
"version": "0.4.32",
|
||||||
|
"resolved": "https://registry.npmjs.org/ws/-/ws-0.4.32.tgz",
|
||||||
|
"integrity": "sha1-eHphVEFPPJntg8V3IVOyD+sM7DI=",
|
||||||
|
"requires": {
|
||||||
|
"commander": "2.1.0",
|
||||||
|
"nan": "1.0.0",
|
||||||
|
"options": "0.0.6",
|
||||||
|
"tinycolor": "0.0.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ws": {
|
||||||
|
"version": "1.1.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/ws/-/ws-1.1.5.tgz",
|
||||||
|
"integrity": "sha512-o3KqipXNUdS7wpQzBHSe180lBGO60SoK0yVo3CYJgb2MkobuWuBX6dhkYP5ORCLd55y+SaflMOV5fqAB53ux4w==",
|
||||||
|
"requires": {
|
||||||
|
"options": "0.0.6",
|
||||||
|
"ultron": "1.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"wtf-8": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/wtf-8/-/wtf-8-1.0.0.tgz",
|
||||||
|
"integrity": "sha1-OS2LotDxw00e4tYw8V0O+2jhBIo="
|
||||||
|
},
|
||||||
|
"xmlhttprequest-ssl": {
|
||||||
|
"version": "1.5.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.3.tgz",
|
||||||
|
"integrity": "sha1-GFqIjATspGw+QHDZn3tJ3jUomS0="
|
||||||
|
},
|
||||||
|
"yeast": {
|
||||||
|
"version": "0.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz",
|
||||||
|
"integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
17
package.json
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"name": "kurento-one2many-call",
|
||||||
|
"version": "6.2.2-dev",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"postinstall": "cd static && bower install"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"express": "~4.12.4",
|
||||||
|
"kurento-client": "Kurento/kurento-client-js",
|
||||||
|
"minimist": "^1.1.1",
|
||||||
|
"socket.io": "^1.4.5"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"bower": "^1.4.1"
|
||||||
|
}
|
||||||
|
}
|
446
server.js
Executable file
@ -0,0 +1,446 @@
|
|||||||
|
/*
|
||||||
|
* (C) Copyright 2014-2015 Kurento (http://kurento.org/)
|
||||||
|
*
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the GNU Lesser General Public License
|
||||||
|
* (LGPL) version 2.1 which accompanies this distribution, and is available at
|
||||||
|
* http://www.gnu.org/licenses/lgpl-2.1.html
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
var path = require('path');
|
||||||
|
var url = require('url');
|
||||||
|
var express = require('express');
|
||||||
|
var minimist = require('minimist');
|
||||||
|
var kurento = require('kurento-client');
|
||||||
|
var fs = require('fs');
|
||||||
|
var http = require('http');
|
||||||
|
var socketio = require('socket.io');
|
||||||
|
|
||||||
|
var argv = minimist(process.argv.slice(2), {
|
||||||
|
default: {
|
||||||
|
as_uri: 'http://localhost:8443/',
|
||||||
|
ws_uri: 'ws://localhost:8888/kurento'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var app = express();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Definition of global variables.
|
||||||
|
*/
|
||||||
|
var candidatesQueue = {};
|
||||||
|
var kurentoClient = null;
|
||||||
|
var noPresenterMessage = 'No active presenter. Try again later...';
|
||||||
|
var anotherPresenterIsActive = "Another user is currently acting as presenter. Try again later ...";
|
||||||
|
|
||||||
|
var rooms = [];
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Server startup
|
||||||
|
*/
|
||||||
|
var asUrl = url.parse(argv.as_uri);
|
||||||
|
var port = asUrl.port;
|
||||||
|
var server = http.createServer(app);
|
||||||
|
var io = socketio(server);
|
||||||
|
|
||||||
|
server.listen(port, function() {
|
||||||
|
console.log('Open ' + url.format(asUrl) + ' with a WebRTC capable browser');
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Rooms related methods
|
||||||
|
*/
|
||||||
|
|
||||||
|
function getRoom(socket) {
|
||||||
|
if (rooms[socket.room] == undefined) {
|
||||||
|
createRoom(socket.room);
|
||||||
|
}
|
||||||
|
return rooms[socket.room];
|
||||||
|
}
|
||||||
|
|
||||||
|
function createRoom(room) {
|
||||||
|
rooms[room] = {
|
||||||
|
presenter: null,
|
||||||
|
pipeline: null,
|
||||||
|
viewers: [],
|
||||||
|
chat: []
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function joinRoom(socket, data) {
|
||||||
|
// leave all other socket.id rooms
|
||||||
|
while(socket.rooms.length) {
|
||||||
|
socket.leave(socket.rooms[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// join new socket.io room
|
||||||
|
socket.join(data.room);
|
||||||
|
socket.room = data.room;
|
||||||
|
socket.username = data.username;
|
||||||
|
|
||||||
|
socket.emit('joinedRoom');
|
||||||
|
|
||||||
|
console.log('Join room: ' + data.room + ' with username ' + data.username);
|
||||||
|
}
|
||||||
|
|
||||||
|
function newChatMessage(socket, message){
|
||||||
|
var message = {message: message, username: socket.username}
|
||||||
|
io.in(socket.room).emit('chat:newMessage', message)
|
||||||
|
|
||||||
|
var room = getRoom(socket);
|
||||||
|
room.chat.push(message);
|
||||||
|
|
||||||
|
if (room.chat.length > 30)
|
||||||
|
room.chat.shift()
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Define possible actions which we'll send thru Websocket
|
||||||
|
*/
|
||||||
|
function acceptPeerResponse(peerType, sdpAnswer) {
|
||||||
|
return {
|
||||||
|
id : peerType + 'Response',
|
||||||
|
response : 'accepted',
|
||||||
|
sdpAnswer : sdpAnswer
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function rejectPeerResponse(peerType, reason) {
|
||||||
|
return {
|
||||||
|
id : peerType + 'Response',
|
||||||
|
response : 'rejected',
|
||||||
|
message : reason
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Socket pipeline
|
||||||
|
*/
|
||||||
|
io.on('connection', function(socket) {
|
||||||
|
console.log('Connection received with sessionId - ' + socket.id);
|
||||||
|
|
||||||
|
socket.on('error', function(error) {
|
||||||
|
console.error('Connection ' + socket.id + ' error', error);
|
||||||
|
stop(socket);
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on('disconnect', function() {
|
||||||
|
console.log('Connection ' + socket.id + ' closed');
|
||||||
|
stop(socket);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Handle events from clients
|
||||||
|
socket.on('presenter', function (data) {
|
||||||
|
startPresenter(socket, data.sdpOffer, function(error, sdpAnswer) {
|
||||||
|
var response = (error) ? rejectPeerResponse('presenter', error) : acceptPeerResponse('presenter', sdpAnswer);
|
||||||
|
socket.emit(response.id, response);
|
||||||
|
if (!error) {
|
||||||
|
console.log(socket.username + ' starting publishing to ' + socket.room + ' room');
|
||||||
|
socket.broadcast.emit('streamStarted');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on('viewer', function (data){
|
||||||
|
startViewer(socket, data.sdpOffer, function(error, sdpAnswer) {
|
||||||
|
response = (error) ? rejectPeerResponse('viewer', error) : acceptPeerResponse('viewer', sdpAnswer);
|
||||||
|
socket.emit(response.id, response);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on('stop', function(){
|
||||||
|
stop(socket);
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on('onIceCandidate', function (data){
|
||||||
|
onIceCandidate(socket, data.candidate);
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on('subscribeToStream', function (data){
|
||||||
|
joinRoom(socket, data);
|
||||||
|
var room = getRoom(socket);
|
||||||
|
if (room.presenter) {
|
||||||
|
socket.emit('streamStarted');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on('joinRoom', function (data){
|
||||||
|
joinRoom(socket, data)
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// Chat methods
|
||||||
|
socket.on('chat:newMessage', function(message) {
|
||||||
|
newChatMessage(socket, message);
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on('chat:loadMessages', function() {
|
||||||
|
var room = getRoom(socket);
|
||||||
|
|
||||||
|
socket.emit('chat:messages', room.chat);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Definition of functions
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Recover kurentoClient for the first time.
|
||||||
|
function getKurentoClient(callback) {
|
||||||
|
if (kurentoClient !== null) {
|
||||||
|
return callback(null, kurentoClient);
|
||||||
|
}
|
||||||
|
|
||||||
|
kurento(argv.ws_uri, function(error, _kurentoClient) {
|
||||||
|
if (error) {
|
||||||
|
console.log("Could not find media server at address " + argv.ws_uri);
|
||||||
|
return callback("Could not find media server at address" + argv.ws_uri
|
||||||
|
+ ". Exiting with error " + error);
|
||||||
|
}
|
||||||
|
|
||||||
|
kurentoClient = _kurentoClient;
|
||||||
|
callback(null, kurentoClient);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function startPresenter(socket, sdpOffer, callback) {
|
||||||
|
clearCandidatesQueue(socket);
|
||||||
|
|
||||||
|
var room = getRoom(socket);
|
||||||
|
if (room.presenter !== null) {
|
||||||
|
stop(socket);
|
||||||
|
return callback(anotherPresenterIsActive);
|
||||||
|
}
|
||||||
|
|
||||||
|
room.presenter = {
|
||||||
|
webRtcEndpoint : null,
|
||||||
|
id: socket.id
|
||||||
|
};
|
||||||
|
|
||||||
|
getKurentoClient(function(error, kurentoClient) {
|
||||||
|
if (error) {
|
||||||
|
stop(socket);
|
||||||
|
return callback(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (room.presenter === null) {
|
||||||
|
stop(socket);
|
||||||
|
return callback(noPresenterMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
kurentoClient.create('MediaPipeline', function(error, pipeline) {
|
||||||
|
if (error) {
|
||||||
|
stop(socket);
|
||||||
|
return callback(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (room.presenter === null) {
|
||||||
|
stop(socket);
|
||||||
|
return callback(noPresenterMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
room.pipeline = pipeline;
|
||||||
|
pipeline.create('WebRtcEndpoint', function(error, webRtcEndpoint) {
|
||||||
|
if (error) {
|
||||||
|
stop(socket);
|
||||||
|
return callback(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (room.presenter === null) {
|
||||||
|
stop(socket);
|
||||||
|
return callback(noPresenterMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
room.presenter.webRtcEndpoint = webRtcEndpoint;
|
||||||
|
|
||||||
|
if (candidatesQueue[socket.id]) {
|
||||||
|
while(candidatesQueue[socket.id].length) {
|
||||||
|
var candidate = candidatesQueue[socket.id].shift();
|
||||||
|
webRtcEndpoint.addIceCandidate(candidate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
webRtcEndpoint.on('OnIceCandidate', function(event) {
|
||||||
|
var candidate = kurento.register.complexTypes.IceCandidate(event.candidate);
|
||||||
|
socket.emit('iceCandidate', { candidate : candidate });
|
||||||
|
});
|
||||||
|
|
||||||
|
webRtcEndpoint.processOffer(sdpOffer, function(error, sdpAnswer) {
|
||||||
|
if (error) {
|
||||||
|
stop(socket);
|
||||||
|
return callback(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (room.presenter === null) {
|
||||||
|
stop(socket);
|
||||||
|
return callback(noPresenterMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
callback(null, sdpAnswer);
|
||||||
|
});
|
||||||
|
|
||||||
|
webRtcEndpoint.gatherCandidates(function(error) {
|
||||||
|
if (error) {
|
||||||
|
stop(socket);
|
||||||
|
return callback(error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function startViewer(socket, sdpOffer, callback) {
|
||||||
|
clearCandidatesQueue(socket);
|
||||||
|
|
||||||
|
var room = getRoom(socket);
|
||||||
|
|
||||||
|
if (room.presenter === null) {
|
||||||
|
stop(socket);
|
||||||
|
return callback(noPresenterMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
room.pipeline.create('WebRtcEndpoint', function(error, webRtcEndpoint) {
|
||||||
|
if (error) {
|
||||||
|
stop(socket);
|
||||||
|
return callback(error);
|
||||||
|
}
|
||||||
|
room.viewers[socket.id] = {
|
||||||
|
"webRtcEndpoint" : webRtcEndpoint,
|
||||||
|
"socket" : socket
|
||||||
|
};
|
||||||
|
|
||||||
|
if (room.presenter === null) {
|
||||||
|
stop(socket);
|
||||||
|
return callback(noPresenterMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (candidatesQueue[socket.id]) {
|
||||||
|
while(candidatesQueue[socket.id].length) {
|
||||||
|
var candidate = candidatesQueue[socket.id].shift();
|
||||||
|
webRtcEndpoint.addIceCandidate(candidate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
webRtcEndpoint.on('OnIceCandidate', function(event) {
|
||||||
|
var candidate = kurento.register.complexTypes.IceCandidate(event.candidate);
|
||||||
|
socket.emit('iceCandidate', { candidate : candidate });
|
||||||
|
});
|
||||||
|
|
||||||
|
webRtcEndpoint.processOffer(sdpOffer, function(error, sdpAnswer) {
|
||||||
|
if (error) {
|
||||||
|
stop(socket.id);
|
||||||
|
return callback(error);
|
||||||
|
}
|
||||||
|
if (room.presenter === null) {
|
||||||
|
stop(socket.id);
|
||||||
|
return callback(noPresenterMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
room.presenter.webRtcEndpoint.connect(webRtcEndpoint, function(error) {
|
||||||
|
if (error) {
|
||||||
|
stop(socket.id);
|
||||||
|
return callback(error);
|
||||||
|
}
|
||||||
|
if (room.presenter === null) {
|
||||||
|
stop(socket.id);
|
||||||
|
return callback(noPresenterMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
callback(null, sdpAnswer);
|
||||||
|
webRtcEndpoint.gatherCandidates(function(error) {
|
||||||
|
if (error) {
|
||||||
|
stop(socket.id);
|
||||||
|
return callback(error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearCandidatesQueue(socket) {
|
||||||
|
if (candidatesQueue[socket.id]) {
|
||||||
|
delete candidatesQueue[socket.id];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function stop(socket) {
|
||||||
|
var room = getRoom(socket);
|
||||||
|
|
||||||
|
if (room.presenter !== null && room.presenter.id == socket.id) {
|
||||||
|
stopPresenter(socket);
|
||||||
|
} else if (room.viewers[socket.id]) {
|
||||||
|
stopViewing(socket);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function stopPresenter(socket){
|
||||||
|
var room = getRoom(socket);
|
||||||
|
var viewers = room.viewers;
|
||||||
|
|
||||||
|
for (var i in viewers) {
|
||||||
|
var viewer = viewers[i];
|
||||||
|
if (viewer.socket) {
|
||||||
|
clearCandidatesQueue(socket);
|
||||||
|
viewer.webRtcEndpoint.release();
|
||||||
|
viewer.socket.emit('stopCommunication');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
room.presenter.webRtcEndpoint.release();
|
||||||
|
room.presenter = null;
|
||||||
|
room.pipeline.release();
|
||||||
|
room.viewers = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
function stopViewing(socket){
|
||||||
|
var room = getRoom(socket);
|
||||||
|
|
||||||
|
clearCandidatesQueue(socket.id);
|
||||||
|
room.viewers[socket.id].webRtcEndpoint.release();
|
||||||
|
delete room.viewers[socket.id];
|
||||||
|
}
|
||||||
|
|
||||||
|
function onIceCandidate(socket, _candidate) {
|
||||||
|
var room = getRoom(socket);
|
||||||
|
|
||||||
|
var candidate = kurento.register.complexTypes.IceCandidate(_candidate);
|
||||||
|
|
||||||
|
if (room.presenter && room.presenter.id === socket.id && room.presenter.webRtcEndpoint) {
|
||||||
|
console.info('Sending presenter candidate');
|
||||||
|
room.presenter.webRtcEndpoint.addIceCandidate(candidate);
|
||||||
|
}
|
||||||
|
else if (room.viewers[socket.id] && room.viewers[socket.id].webRtcEndpoint) {
|
||||||
|
console.info('Sending viewer candidate');
|
||||||
|
room.viewers[socket.id].webRtcEndpoint.addIceCandidate(candidate);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
console.info('Queueing candidate');
|
||||||
|
if (!candidatesQueue[socket.id]) {
|
||||||
|
candidatesQueue[socket.id] = [];
|
||||||
|
}
|
||||||
|
candidatesQueue[socket.id].push(candidate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
app.use(function (req, res, next) {
|
||||||
|
// Website you wish to allow to connect
|
||||||
|
res.setHeader('Access-Control-Allow-Origin', '*');
|
||||||
|
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
|
||||||
|
app.use(express.static(path.join(__dirname, 'static')));
|
BIN
static/.bower.json.swp
Normal file
29
static/bower.json
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
{
|
||||||
|
"name": "kurento-one2many-call",
|
||||||
|
"description": "Kurento Browser JavaScript Tutorial",
|
||||||
|
"authors": [
|
||||||
|
"Kurento <info@kurento.org>"
|
||||||
|
],
|
||||||
|
"main": "index.html",
|
||||||
|
"moduleType": [
|
||||||
|
"globals"
|
||||||
|
],
|
||||||
|
"license": "LGPL",
|
||||||
|
"homepage": "http://www.kurento.org/",
|
||||||
|
"private": true,
|
||||||
|
"ignore": [
|
||||||
|
"**/.*",
|
||||||
|
"node_modules",
|
||||||
|
"bower_components",
|
||||||
|
"test",
|
||||||
|
"tests"
|
||||||
|
],
|
||||||
|
"dependencies": {
|
||||||
|
"adapter.js": "v0.2.9",
|
||||||
|
"bootstrap": "~3.3.0",
|
||||||
|
"ekko-lightbox": "~3.3.0",
|
||||||
|
"demo-console": "1.5.1",
|
||||||
|
"kurento-utils": "master",
|
||||||
|
"socket.io-client": "^1.4.5"
|
||||||
|
}
|
||||||
|
}
|
77
static/css/kurento.css
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
/*
|
||||||
|
* (C) Copyright 2014-2015 Kurento (http://kurento.org/)
|
||||||
|
*
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the GNU Lesser General Public License
|
||||||
|
* (LGPL) version 2.1 which accompanies this distribution, and is available at
|
||||||
|
* http://www.gnu.org/licenses/lgpl-2.1.html
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@CHARSET "UTF-8";
|
||||||
|
|
||||||
|
html {
|
||||||
|
position: relative;
|
||||||
|
min-height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
padding-top: 40px;
|
||||||
|
body
|
||||||
|
}
|
||||||
|
|
||||||
|
video,#console {
|
||||||
|
display: block;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 1.42857143;
|
||||||
|
color: #555;
|
||||||
|
background-color: #fff;
|
||||||
|
background-image: none;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 4px;
|
||||||
|
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
|
||||||
|
box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
|
||||||
|
-webkit-transition: border-color ease-in-out .15s, box-shadow
|
||||||
|
ease-in-out .15s;
|
||||||
|
transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
|
||||||
|
}
|
||||||
|
|
||||||
|
#console {
|
||||||
|
min-height: 120px;
|
||||||
|
max-height: 360px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#videoContainer {
|
||||||
|
position: absolute;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
#videoBig {
|
||||||
|
width: 640px;
|
||||||
|
height: 480px;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
div#videoSmall {
|
||||||
|
width: 240px;
|
||||||
|
height: 180px;
|
||||||
|
padding: 0px;
|
||||||
|
position: absolute;
|
||||||
|
top: 15px;
|
||||||
|
left: 400px;
|
||||||
|
cursor: pointer;
|
||||||
|
z-index: 10;
|
||||||
|
padding: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.dragged {
|
||||||
|
cursor: all-scroll !important;
|
||||||
|
border-color: blue !important;
|
||||||
|
z-index: 10 !important;
|
||||||
|
}
|
BIN
static/img/kurento.png
Normal file
After Width: | Height: | Size: 6.3 KiB |
BIN
static/img/naevatec.png
Normal file
After Width: | Height: | Size: 51 KiB |
BIN
static/img/pipeline.png
Normal file
After Width: | Height: | Size: 64 KiB |
BIN
static/img/spinner.gif
Normal file
After Width: | Height: | Size: 8.3 KiB |
BIN
static/img/transparent-1px.png
Normal file
After Width: | Height: | Size: 68 B |
BIN
static/img/urjc.gif
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
static/img/webrtc.png
Normal file
After Width: | Height: | Size: 12 KiB |
91
static/index.html
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="cache-control" content="no-cache">
|
||||||
|
<meta http-equiv="pragma" content="no-cache">
|
||||||
|
<meta http-equiv="expires" content="0">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<link rel="shortcut icon" href="img/kurento.png" type="image/png" />
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="bower_components/bootstrap/dist/css/bootstrap.min.css">
|
||||||
|
<link rel="stylesheet" href="bower_components/demo-console/index.css">
|
||||||
|
<link rel="stylesheet" href="bower_components/ekko-lightbox/dist/ekko-lightbox.min.css">
|
||||||
|
<link rel="stylesheet" href="css/kurento.css">
|
||||||
|
|
||||||
|
<script src="bower_components/adapter.js/adapter.js"></script>
|
||||||
|
<script src="bower_components/jquery/dist/jquery.min.js"></script>
|
||||||
|
<script src="bower_components/bootstrap/dist/js/bootstrap.min.js"></script>
|
||||||
|
<script src="bower_components/demo-console/index.js"></script>
|
||||||
|
<script src="bower_components/ekko-lightbox/dist/ekko-lightbox.min.js"></script>
|
||||||
|
|
||||||
|
<script src="bower_components/kurento-utils/js/kurento-utils.js"></script>
|
||||||
|
<script src="bower_components/io/dist/socket.io.js"></script>
|
||||||
|
|
||||||
|
<script src="js/index.js"></script>
|
||||||
|
<title>Kurento </title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<header>
|
||||||
|
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<div class="page-header">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-5">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<label for="roomName">Room:</label>
|
||||||
|
<input class="input" id="roomName" value="default"/>
|
||||||
|
<a id="call" href="#" class="btn btn-success">
|
||||||
|
<span class="glyphicon glyphicon-play"></span> Presenter</a>
|
||||||
|
<a id="viewer" href="#" class="btn btn-primary">
|
||||||
|
<span class="glyphicon glyphicon-user"></span> Viewer</a>
|
||||||
|
<a id="terminate" href="#" class="btn btn-danger">
|
||||||
|
<span class="glyphicon glyphicon-stop"></span> Stop</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<br/>
|
||||||
|
<label class="control-label" for="console">Console</label><br><br>
|
||||||
|
<div id="console" class="democonsole">
|
||||||
|
<ul></ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-7">
|
||||||
|
<div id="videoBig">
|
||||||
|
<video id="video" autoplay width="640px" height="480px" poster="img/webrtc.png"></video>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<footer>
|
||||||
|
<div class="foot-fixed-bottom">
|
||||||
|
<div class="container text-center">
|
||||||
|
<hr/>
|
||||||
|
<div class="row">© 2014-2015 Kurento</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-4">
|
||||||
|
<a href="http://www.urjc.es">
|
||||||
|
<img src="img/urjc.gif" alt="Universidad Rey Juan Carlos" height="50px"/>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<a href="http://www.kurento.org">
|
||||||
|
<img src="img/kurento.png" alt="Kurento" height="50px"/>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<a href="http://www.naevatec.com">
|
||||||
|
<img src="img/naevatec.png" alt="Naevatec" height="50px"/>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
205
static/js/index.js
Normal file
@ -0,0 +1,205 @@
|
|||||||
|
/*
|
||||||
|
* (C) Copyright 2014-2015 Kurento (http://kurento.org/)
|
||||||
|
*
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the GNU Lesser General Public License
|
||||||
|
* (LGPL) version 2.1 which accompanies this distribution, and is available at
|
||||||
|
* http://www.gnu.org/licenses/lgpl-2.1.html
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
//var ws = new WebSocket('wss://' + location.host + '/one2many');
|
||||||
|
|
||||||
|
|
||||||
|
var video;
|
||||||
|
var webRtcPeer;
|
||||||
|
var socket;
|
||||||
|
var autoView = true;
|
||||||
|
var room;
|
||||||
|
|
||||||
|
$(function() {
|
||||||
|
socket = io();
|
||||||
|
console = new Console();
|
||||||
|
video = $('#video')[0];
|
||||||
|
room = $('#roomName');
|
||||||
|
|
||||||
|
$('#call').on('click', function(e) { presenter(); e.preventDefault(); } );
|
||||||
|
$('#viewer').on('click', function(e) { viewer(); e.preventDefault(); } );
|
||||||
|
$('#terminate').on('click', function(e) { stop(); e.preventDefault();} );
|
||||||
|
|
||||||
|
|
||||||
|
socket.on('connect', function(){
|
||||||
|
console.log('Connected to socket');
|
||||||
|
|
||||||
|
socket.emit('subscribeToStream', currentRoom());
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on('disconnect', function(){
|
||||||
|
console.log('Disconnected from socket');
|
||||||
|
dispose();
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on('presenterResponse', function(data) {
|
||||||
|
presenterResponse(data);
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on('viewerResponse', function(data) {
|
||||||
|
viewerResponse(data);
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on('stopCommunication', function(data) {
|
||||||
|
console.log('stopCommunication');
|
||||||
|
dispose();
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on('iceCandidate', function(data) {
|
||||||
|
webRtcPeer.addIceCandidate(data.candidate)
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on('streamStarted', function(data) {
|
||||||
|
if (autoView) {
|
||||||
|
viewer();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
function presenterResponse(message) {
|
||||||
|
if (message.response != 'accepted') {
|
||||||
|
var errorMsg = message.message ? message.message : 'Unknown error';
|
||||||
|
console.warn('Call not accepted for the following reason: ' + errorMsg);
|
||||||
|
dispose();
|
||||||
|
} else {
|
||||||
|
webRtcPeer.processAnswer(message.sdpAnswer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function viewerResponse(message) {
|
||||||
|
if (message.response != 'accepted') {
|
||||||
|
var errorMsg = message.message ? message.message : 'Unknown error';
|
||||||
|
console.warn('Call not accepted for the following reason: ' + errorMsg);
|
||||||
|
dispose();
|
||||||
|
} else {
|
||||||
|
webRtcPeer.processAnswer(message.sdpAnswer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onError(obj) {
|
||||||
|
console.log(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
function presenter() {
|
||||||
|
if (!webRtcPeer) {
|
||||||
|
showSpinner(video);
|
||||||
|
|
||||||
|
var options = {
|
||||||
|
localVideo: video,
|
||||||
|
onicecandidate : onIceCandidate
|
||||||
|
};
|
||||||
|
|
||||||
|
webRtcPeer = kurentoUtils.WebRtcPeer.WebRtcPeerSendonly(options, function(error) {
|
||||||
|
if(error) return onError(error);
|
||||||
|
|
||||||
|
this.generateOffer(onOfferPresenter);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onOfferPresenter(error, offerSdp) {
|
||||||
|
if (error) return onError(error);
|
||||||
|
|
||||||
|
var message = {
|
||||||
|
sdpOffer : offerSdp,
|
||||||
|
room: currentRoom()
|
||||||
|
};
|
||||||
|
|
||||||
|
socket.emit('presenter', message);
|
||||||
|
}
|
||||||
|
|
||||||
|
function viewer() {
|
||||||
|
autoView = true;
|
||||||
|
if (!webRtcPeer) {
|
||||||
|
showSpinner(video);
|
||||||
|
|
||||||
|
var options = {
|
||||||
|
remoteVideo: video,
|
||||||
|
onicecandidate : onIceCandidate
|
||||||
|
};
|
||||||
|
|
||||||
|
webRtcPeer = kurentoUtils.WebRtcPeer.WebRtcPeerRecvonly(options, function(error) {
|
||||||
|
if(error) return onError(error);
|
||||||
|
|
||||||
|
this.generateOffer(onOfferViewer);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onOfferViewer(error, offerSdp) {
|
||||||
|
if (error) return onError(error);
|
||||||
|
|
||||||
|
var message = {
|
||||||
|
sdpOffer : offerSdp,
|
||||||
|
room: currentRoom()
|
||||||
|
};
|
||||||
|
socket.emit('viewer', message);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onIceCandidate(candidate) {
|
||||||
|
//console.log('Local candidate' + JSON.stringify(candidate));
|
||||||
|
socket.emit('onIceCandidate', {candidate : candidate});
|
||||||
|
}
|
||||||
|
|
||||||
|
function stop() {
|
||||||
|
autoView = false;
|
||||||
|
if (webRtcPeer) {
|
||||||
|
socket.emit('stop');
|
||||||
|
dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function dispose() {
|
||||||
|
if (webRtcPeer) {
|
||||||
|
webRtcPeer.dispose();
|
||||||
|
webRtcPeer = null;
|
||||||
|
}
|
||||||
|
hideSpinner(video);
|
||||||
|
}
|
||||||
|
|
||||||
|
function sendMessage(payload) {
|
||||||
|
var event = payload.id,
|
||||||
|
message = payload;
|
||||||
|
console.log('Sending message - ' + event + ': ', message);
|
||||||
|
|
||||||
|
socket.emit(event, payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
function showSpinner() {
|
||||||
|
for (var i = 0; i < arguments.length; i++) {
|
||||||
|
arguments[i].poster = './img/transparent-1px.png';
|
||||||
|
arguments[i].style.background = 'center transparent url("./img/spinner.gif") no-repeat';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function hideSpinner() {
|
||||||
|
for (var i = 0; i < arguments.length; i++) {
|
||||||
|
arguments[i].src = '';
|
||||||
|
arguments[i].poster = './img/webrtc.png';
|
||||||
|
arguments[i].style.background = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function currentRoom() {
|
||||||
|
return $('#roomName').val();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lightbox utility (to display media pipeline image in a modal dialog)
|
||||||
|
*/
|
||||||
|
$(document).delegate('*[data-toggle="lightbox"]', 'click', function(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
$(this).ekkoLightbox();
|
||||||
|
});
|