Compare commits
19 Commits
4d36c2c429
...
97b6f50b7c
Author | SHA1 | Date |
---|---|---|
knotteye | 97b6f50b7c | |
knotteye | 94f240d4d6 | |
knotteye | d8b327752e | |
knotteye | 7107cb4c8f | |
knotteye | 90cce68581 | |
knotteye | 1fa6bf7e81 | |
knotteye | ab9a9b4585 | |
knotteye | 01744df3cd | |
knotteye | ab082e5f95 | |
knotteye | de17128cd2 | |
knotteye | cfa7c5ab13 | |
knotteye | 81afb7493b | |
knotteye | 9a6e5c8798 | |
knotteye | 06dc05eb8b | |
knotteye | dfd0bc4881 | |
knotteye | 30a62e6378 | |
knotteye | cc3876ff4a | |
knotteye | 56c4b94a80 | |
knotteye | a5c1adfffc |
|
@ -4,7 +4,7 @@ System dependencies: A stable version of node>=10, mysql3 (or a compatible imple
|
|||
|
||||
### Setup Instructions
|
||||
```bash
|
||||
git clone https://gitlab.com/knotteye/satyr.git
|
||||
git clone https://pond.waldn.net/git/knotteye/satyr.git
|
||||
cd satyr
|
||||
npm install
|
||||
npm run setup
|
||||
|
|
10
docs/CHAT.md
10
docs/CHAT.md
|
@ -3,7 +3,7 @@ This is not a guide to using the webchat, this a reference point for writing cli
|
|||
|
||||
Satyr's webchat is based on [socket.io](https://socket.io/), you can find clients for [Java](https://github.com/socketio/socket.io-client-java), [C++](https://github.com/socketio/socket.io-client-cpp), [Swift](https://github.com/socketio/socket.io-client-swift), [Dart](https://github.com/rikulo/socket.io-client-dart), and probably more.
|
||||
|
||||
Socket.IO is loosely reminiscent of IRC in that you will receive events from the server and sent events to it. The following is a list of incoming and outgoing events you will need to handle or send. If you would like to see examples, templates/chat.html is implementation used in the webclient by satyr.
|
||||
Socket.IO is loosely reminiscent of IRC in that you will receive events from the server and sent events to it. The following is a list of incoming and outgoing events you will need to handle or send. If you would like to see examples, templates/chat.html is the implementation used in the webclient by satyr.
|
||||
|
||||
# Incoming Events
|
||||
These are events you will recieve from the server that need to be handled in some way.
|
||||
|
@ -53,12 +53,12 @@ This is a request to set the client's nickname. The data attached to a NICK even
|
|||
password: "the optional password"
|
||||
}
|
||||
```
|
||||
During the initial connect of the client, the server will check for the "Authorization" cookie. If the cookie is a valid, signed JWT, the client will be assigned the nickname of the user that cookie belongs to. If it doesn't exist or is invalid, the client will be assigned a nickname of the form Guest+some integer.
|
||||
During the initial connect of the client, the server will check for the "Authorization" cookie. If the cookie is a valid, signed JWT the client will be assigned the nickname of the user that cookie belongs to. If it doesn't exist or is invalid, the client will be assigned a nickname of the form Guest+some integer.
|
||||
|
||||
The server will send an alert notifying the client of either the nickname change, or some error.
|
||||
|
||||
## MSG
|
||||
This is a chat message to send to room. It should be a JSON object in the following format:
|
||||
This is a chat message to send to a room. It should be a JSON object in the following format:
|
||||
```
|
||||
{
|
||||
room: "the room to send the messag to",
|
||||
|
@ -117,10 +117,10 @@ A request to unban an IP address. It can only be done by the owner of the room.
|
|||
|
||||
# Final Notes
|
||||
|
||||
Sending more than 10 messages a second will cause the server to kick your client. If kicked this way 3 times, the client will be banned for 20 minutes.
|
||||
Sending more than 10 messages per second will cause the server to kick your client. If kicked this way 3 times, the client will be banned for 20 minutes.
|
||||
|
||||
Kicked or banned users will not be notified of this through an event.
|
||||
|
||||
The server *will* send your own MSG events back to you, you will need to parse them out if you want to append them immediately.
|
||||
The server *will* send your own MSG events back to you, you will need to parse them out if you want to display them immediately.
|
||||
|
||||
Clients who successfully authenticate as a registered user, through either a password or a signed JWT, can ignore nickname collision and have as many connections as they wish.
|
|
@ -7,11 +7,23 @@ Some values you might want to change are
|
|||
satyr:
|
||||
registration: true
|
||||
# allow new users to register
|
||||
port: 8000
|
||||
# the port to serve http on
|
||||
|
||||
http:
|
||||
hsts: true
|
||||
# enable strict transport security
|
||||
|
||||
rtmp:
|
||||
port: 1935
|
||||
# change the port to serve rtmp on
|
||||
cluster: false
|
||||
# enable clustering for the RTMP server
|
||||
# clustering is an attempt to take better advantage of multi threaded systems in spite of node.js being single-threaded
|
||||
# satyr will spawn one RTMP Worker per CPU core, and round-robin incoming connections between workers
|
||||
# If you turn this on, satyr will no longer be able to reliably serve RTMP streams to clients
|
||||
# Your users will have to use DASH instead
|
||||
|
||||
media:
|
||||
record: true
|
||||
# allow users to record VODs
|
||||
|
@ -36,7 +48,7 @@ transcode:
|
|||
# https://trac.ffmpeg.org/wiki/HWAccelIntro is a good place to start
|
||||
|
||||
# having more than 4-5 variants will start giving diminishing returns on stream quality for cpu load
|
||||
# if you can't afford to generate at least 3 variants, it's reccomended to leave adaptive streaming off
|
||||
# if you can't afford to generate at least 3 variants, it's recommended to leave adaptive streaming off
|
||||
|
||||
crypto:
|
||||
saltRounds: 12
|
||||
|
@ -44,12 +56,11 @@ crypto:
|
|||
# if you don't understand the implications, don't change this
|
||||
|
||||
chat:
|
||||
# the following settings are for chat mirroring bots
|
||||
# users will still need to choose which channel to mirror
|
||||
# the following settings are for chat bridging bots
|
||||
# users will still need to choose which channel to bridge
|
||||
# for their chat at /profile/chat
|
||||
irc:
|
||||
enabled: true
|
||||
# enable irc mirroring
|
||||
server: chat.freenode.net
|
||||
port: 6697
|
||||
tls: true
|
||||
|
@ -61,7 +72,6 @@ chat:
|
|||
|
||||
discord:
|
||||
enabled: true
|
||||
# enabled discord integration
|
||||
token: abcdefghijklmnopqrstuvwxyz
|
||||
# the access token for the bot
|
||||
# note that the bot will mirror every channel matching the name the user has chosen
|
||||
|
@ -74,6 +84,20 @@ chat:
|
|||
# access token for the twitch chat bot
|
||||
# this is not the account password, you will need to generate a token here:
|
||||
# https://twitchapps.com/tmi/
|
||||
|
||||
xmpp:
|
||||
enabled: true
|
||||
server: 'example.com'
|
||||
port: 5222
|
||||
jid: 'exampleBot@example.com'
|
||||
password: 'abcde'
|
||||
# connection settings for the bot
|
||||
nickname: 'SatyrChat
|
||||
# the nickname the bot will join MUCs with
|
||||
|
||||
# note that for the best experience you should set the default number of history messages to 0 for the MUC
|
||||
# The bot will attempt to request 0 history messages anyway, and will also attempt to ignore any history messages it receives
|
||||
# but both of these things are unreliable
|
||||
```
|
||||
|
||||
### Web Frontend
|
||||
|
|
|
@ -4,14 +4,14 @@ A more detailed walkthrough.
|
|||
### System Dependencies
|
||||
Install ffmpeg(>= 4.2.1) and mysql through your distribution's package manager.
|
||||
See [this page](https://nodejs.org/en/download/package-manager/) for instructions on installing node v10.
|
||||
If the version in your distro's package manager is different, you can install 'n' through npm to manage node versions.
|
||||
If the version in your distro's package manager is different, you can install [n](https://www.npmjs.com/package/n) through npm to manage node versions.
|
||||
|
||||
### Installing Satyr
|
||||
Before starting, you should create a system user to run the satyr service.
|
||||
|
||||
Clone the repository and change to the directory
|
||||
```bash
|
||||
git clone https://gitlab.com/knotteye/satyr.git
|
||||
git clone https://pond.waldn.net/git/knotteye/satyr.git
|
||||
cd satyr
|
||||
```
|
||||
Install nodejs dependencies
|
||||
|
|
|
@ -32,6 +32,7 @@ Configuration of the instance relating to media
|
|||
```
|
||||
{
|
||||
rtmp: {
|
||||
cluster: false,
|
||||
port: 1935,
|
||||
ping_timeout: 60
|
||||
},
|
||||
|
|
|
@ -1,30 +1,19 @@
|
|||
## Satyr Usage
|
||||
|
||||
### Administration
|
||||
Satyr needs access to port 1935 for RTMP streams, and will serve HTTP on port 8000. The ports can be changed with follow config lines.
|
||||
Satyr needs access to port 1935 for RTMP streams, and will serve HTTP on port 8000. See CONFIGURATION.md for details on changing this.
|
||||
|
||||
For HTTPS, run a reverse proxy in front of satyr. An example nginx block is shown below.
|
||||
```
|
||||
server {
|
||||
port 80;
|
||||
port [::]80;
|
||||
server_name example.tld;
|
||||
return https://$server_name$request_uri 301;
|
||||
}
|
||||
server {
|
||||
port 443 ssl;
|
||||
port [::]443 ssl;
|
||||
server_name example.tld;
|
||||
For HTTPS, run a reverse proxy in front of satyr. An example nginx config can be found at install/satyr.nginx
|
||||
An example systemd service can also be at install/satyr.service
|
||||
|
||||
ssl_trusted_certificate /etc/letsencrypt/live/example.tld/chain.pem;
|
||||
ssl_certificate /etc/letsencrypt/live/example.tld/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/example.tld/privkey.pem;
|
||||
#### CLI
|
||||
Satyr's CLI tool can be run with `npm run cli` or `node_modules/.bin/ts-node src/cli.ts`
|
||||
|
||||
It's not very complex. The following commands are available:
|
||||
* `npm run cli -- --adduser sally --password "hunter12"` to create user sally with the password hunter12
|
||||
* `npm run cli -- --rmuser sally` to remove user sally
|
||||
* `npm run cli -- --invite` to generate an invite code used for creating account even when registration is closed
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:8000/;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Users
|
||||
|
||||
|
@ -35,13 +24,14 @@ Stream keys can be changed at example.tld/changesk, and passwords at /changepwd
|
|||
#### Chat
|
||||
Chat is based on Socket.IO, and can be accessed through the webclient at /chat.
|
||||
Chatting and changing a nickname do not require authentication, but the usernames of streamers are reserved.
|
||||
|
||||
The following commands are available:
|
||||
`/nick sally (password)` Password is only required if sally is a registered user.
|
||||
`/join sally` Join the chatroom for sally's stream and leave the previous room.
|
||||
`/kick bob` Available only in your own room if you are a streamer. Forcefully disconnect the user.
|
||||
`/ban bob (time)` Ban a user from your room. Bans are based on IP address. The optional time is in minutes. The default is 30.
|
||||
`/banlist` List the IPs currently banned from your room.
|
||||
`/unban (ip)` self explanatory
|
||||
* `/nick sally (password)` Password is only required if sally is a registered user.
|
||||
* `/join sally` Join the chatroom for sally's stream and leave the previous room.
|
||||
* `/kick bob` Available only in your own room if you are a streamer. Forcefully disconnect the user.
|
||||
* `/ban bob (time)` Ban a user from your room. Bans are based on IP address. The optional time is in minutes. The default is 30.
|
||||
* `/banlist` List the IPs currently banned from your room.
|
||||
* `/unban (ip)` self explanatory
|
||||
|
||||
You can set up mirroring to and from webchat rooms and IRC channels, twitch streams, and discord server channels.
|
||||
More information is in CONFIGURATION.md
|
||||
|
|
|
@ -51,10 +51,11 @@ chat:
|
|||
|
||||
xmpp:
|
||||
enabled: false
|
||||
server:
|
||||
server:
|
||||
port: 5222
|
||||
nickname: 'SatyrChat'
|
||||
username: 'SatyrChat'
|
||||
jid:
|
||||
password:
|
||||
nickname:
|
||||
|
||||
twitch:
|
||||
enabled: false
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
server {
|
||||
port 80;
|
||||
port [::]80;
|
||||
server_name example.tld;
|
||||
return https://$server_name$request_uri 301;
|
||||
}
|
||||
server {
|
||||
port 443 ssl;
|
||||
port [::]443 ssl;
|
||||
server_name example.tld;
|
||||
|
||||
ssl_trusted_certificate /etc/letsencrypt/live/example.tld/chain.pem;
|
||||
ssl_certificate /etc/letsencrypt/live/example.tld/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/example.tld/privkey.pem;
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:8000/;
|
||||
}
|
||||
|
||||
location ~* \.(mpd|m4s|mp4)$ {
|
||||
# nginx can serve static files faster than node
|
||||
# this should improve performance
|
||||
root /opt/satyr/site/;
|
||||
}
|
||||
}
|
|
@ -22,6 +22,30 @@
|
|||
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.67.tgz",
|
||||
"integrity": "sha512-R48tgL2izApf+9rYNH+3RBMbRpPeW3N8f0I9HMhggeq4UXwBDqumJ14SDs4ctTMhG11pIOduZ4z3QWGOiMc9Vg=="
|
||||
},
|
||||
"@xmpp/jid": {
|
||||
"version": "0.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@xmpp/jid/-/jid-0.0.2.tgz",
|
||||
"integrity": "sha1-DVKMqdWNr8gzZlVk/+YvMyoxZ/I="
|
||||
},
|
||||
"@xmpp/streamparser": {
|
||||
"version": "0.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@xmpp/streamparser/-/streamparser-0.0.6.tgz",
|
||||
"integrity": "sha1-EYAz6p23yGoctGED8mnr/3n28eo=",
|
||||
"requires": {
|
||||
"@xmpp/xml": "^0.1.3",
|
||||
"inherits": "^2.0.3",
|
||||
"ltx": "^2.5.0"
|
||||
}
|
||||
},
|
||||
"@xmpp/xml": {
|
||||
"version": "0.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@xmpp/xml/-/xml-0.1.3.tgz",
|
||||
"integrity": "sha1-HxQ5nlPkGWiFWGmPbGLnHjmoam4=",
|
||||
"requires": {
|
||||
"inherits": "^2.0.3",
|
||||
"ltx": "^2.6.2"
|
||||
}
|
||||
},
|
||||
"a-sync-waterfall": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/a-sync-waterfall/-/a-sync-waterfall-1.0.1.tgz",
|
||||
|
@ -46,6 +70,17 @@
|
|||
"resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz",
|
||||
"integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8="
|
||||
},
|
||||
"ajv": {
|
||||
"version": "6.12.6",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
|
||||
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
|
||||
"requires": {
|
||||
"fast-deep-equal": "^3.1.1",
|
||||
"fast-json-stable-stringify": "^2.0.0",
|
||||
"json-schema-traverse": "^0.4.1",
|
||||
"uri-js": "^4.2.2"
|
||||
}
|
||||
},
|
||||
"ansi-regex": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
|
||||
|
@ -108,6 +143,14 @@
|
|||
"resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
|
||||
"integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY="
|
||||
},
|
||||
"asn1": {
|
||||
"version": "0.2.4",
|
||||
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
|
||||
"integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
|
||||
"requires": {
|
||||
"safer-buffer": "~2.1.0"
|
||||
}
|
||||
},
|
||||
"asn1.js": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.2.0.tgz",
|
||||
|
@ -118,16 +161,41 @@
|
|||
"minimalistic-assert": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"assert-plus": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
|
||||
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
|
||||
},
|
||||
"async-limiter": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz",
|
||||
"integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ=="
|
||||
},
|
||||
"asynckit": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
|
||||
},
|
||||
"aws-sign2": {
|
||||
"version": "0.7.0",
|
||||
"resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
|
||||
"integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg="
|
||||
},
|
||||
"aws4": {
|
||||
"version": "1.10.1",
|
||||
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.10.1.tgz",
|
||||
"integrity": "sha512-zg7Hz2k5lI8kb7U32998pRRFin7zJlkfezGJjUc2heaD4Pw2wObakCDVzkKztTm/Ln7eiVvYsjqak0Ed4LkMDA=="
|
||||
},
|
||||
"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="
|
||||
},
|
||||
"balanced-match": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
|
||||
|
@ -157,6 +225,21 @@
|
|||
"node-pre-gyp": "0.15.0"
|
||||
}
|
||||
},
|
||||
"bcrypt-pbkdf": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
|
||||
"integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
|
||||
"requires": {
|
||||
"tweetnacl": "^0.14.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"tweetnacl": {
|
||||
"version": "0.14.5",
|
||||
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
|
||||
"integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q="
|
||||
}
|
||||
}
|
||||
},
|
||||
"better-assert": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz",
|
||||
|
@ -236,6 +319,11 @@
|
|||
"fill-range": "^7.0.1"
|
||||
}
|
||||
},
|
||||
"browser-request": {
|
||||
"version": "0.3.3",
|
||||
"resolved": "https://registry.npmjs.org/browser-request/-/browser-request-0.3.3.tgz",
|
||||
"integrity": "sha1-ns5bWsqJopkyJC4Yv5M975h2zBc="
|
||||
},
|
||||
"buffer-from": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
|
||||
|
@ -251,6 +339,11 @@
|
|||
"resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz",
|
||||
"integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA="
|
||||
},
|
||||
"caseless": {
|
||||
"version": "0.12.0",
|
||||
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
|
||||
"integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
|
||||
},
|
||||
"chalk": {
|
||||
"version": "2.4.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
|
||||
|
@ -300,6 +393,14 @@
|
|||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
|
||||
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
|
||||
},
|
||||
"combined-stream": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
|
||||
"requires": {
|
||||
"delayed-stream": "~1.0.0"
|
||||
}
|
||||
},
|
||||
"commander": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz",
|
||||
|
@ -390,6 +491,14 @@
|
|||
"ts-toolbelt": "^6.9.0"
|
||||
}
|
||||
},
|
||||
"dashdash": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
|
||||
"integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
|
||||
"requires": {
|
||||
"assert-plus": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"dateformat": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz",
|
||||
|
@ -431,6 +540,11 @@
|
|||
"resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
|
||||
"integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA=="
|
||||
},
|
||||
"delayed-stream": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
|
||||
},
|
||||
"delegates": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
|
||||
|
@ -506,6 +620,15 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"ecc-jsbn": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
|
||||
"integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
|
||||
"requires": {
|
||||
"jsbn": "~0.1.0",
|
||||
"safer-buffer": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"ee-first": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
|
||||
|
@ -685,6 +808,26 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"extend": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
|
||||
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
|
||||
},
|
||||
"extsprintf": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
|
||||
"integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU="
|
||||
},
|
||||
"fast-deep-equal": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
||||
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
|
||||
},
|
||||
"fast-json-stable-stringify": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
|
||||
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
|
||||
},
|
||||
"fill-range": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
||||
|
@ -728,6 +871,21 @@
|
|||
"resolved": "https://registry.npmjs.org/flags/-/flags-0.1.3.tgz",
|
||||
"integrity": "sha1-lh0vyM3zZp1jBB4w5bJK2tNvV1g="
|
||||
},
|
||||
"forever-agent": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
|
||||
"integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE="
|
||||
},
|
||||
"form-data": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
|
||||
"integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
|
||||
"requires": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.6",
|
||||
"mime-types": "^2.1.12"
|
||||
}
|
||||
},
|
||||
"forwarded": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
|
||||
|
@ -772,6 +930,14 @@
|
|||
"wide-align": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"getpass": {
|
||||
"version": "0.1.7",
|
||||
"resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
|
||||
"integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
|
||||
"requires": {
|
||||
"assert-plus": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"glob": {
|
||||
"version": "7.1.6",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
|
||||
|
@ -794,6 +960,20 @@
|
|||
"is-glob": "^4.0.1"
|
||||
}
|
||||
},
|
||||
"har-schema": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
|
||||
"integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI="
|
||||
},
|
||||
"har-validator": {
|
||||
"version": "5.1.5",
|
||||
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz",
|
||||
"integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==",
|
||||
"requires": {
|
||||
"ajv": "^6.12.3",
|
||||
"har-schema": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"has-binary2": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz",
|
||||
|
@ -824,6 +1004,33 @@
|
|||
"resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
|
||||
"integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk="
|
||||
},
|
||||
"hash-base": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz",
|
||||
"integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==",
|
||||
"requires": {
|
||||
"inherits": "^2.0.4",
|
||||
"readable-stream": "^3.6.0",
|
||||
"safe-buffer": "^5.2.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"readable-stream": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
|
||||
"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
|
||||
"requires": {
|
||||
"inherits": "^2.0.3",
|
||||
"string_decoder": "^1.1.1",
|
||||
"util-deprecate": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"safe-buffer": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"http-errors": {
|
||||
"version": "1.7.2",
|
||||
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
|
||||
|
@ -843,6 +1050,16 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"http-signature": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
|
||||
"integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
|
||||
"requires": {
|
||||
"assert-plus": "^1.0.0",
|
||||
"jsprim": "^1.2.2",
|
||||
"sshpk": "^1.7.0"
|
||||
}
|
||||
},
|
||||
"iconv": {
|
||||
"version": "2.2.3",
|
||||
"resolved": "https://registry.npmjs.org/iconv/-/iconv-2.2.3.tgz",
|
||||
|
@ -955,11 +1172,21 @@
|
|||
"resolved": "https://registry.npmjs.org/is-port-available/-/is-port-available-0.1.5.tgz",
|
||||
"integrity": "sha512-/r7UZAQtfgDFdhxzM71jG0mkC4oSRA513cImMILdRe/+UOIe0Se/D/Z7XCua4AFg5k4Zt3ALMGaC1W3FzlrR2w=="
|
||||
},
|
||||
"is-typedarray": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
|
||||
"integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
|
||||
},
|
||||
"isarray": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
|
||||
},
|
||||
"isstream": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
|
||||
"integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
|
||||
},
|
||||
"jose": {
|
||||
"version": "1.15.1",
|
||||
"resolved": "https://registry.npmjs.org/jose/-/jose-1.15.1.tgz",
|
||||
|
@ -968,11 +1195,47 @@
|
|||
"asn1.js": "^5.2.0"
|
||||
}
|
||||
},
|
||||
"jsbn": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
|
||||
"integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM="
|
||||
},
|
||||
"json-schema": {
|
||||
"version": "0.2.3",
|
||||
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
|
||||
"integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM="
|
||||
},
|
||||
"json-schema-traverse": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
|
||||
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
|
||||
},
|
||||
"json-stringify-safe": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
|
||||
"integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
|
||||
},
|
||||
"jsprim": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
|
||||
"integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
|
||||
"requires": {
|
||||
"assert-plus": "1.0.0",
|
||||
"extsprintf": "1.3.0",
|
||||
"json-schema": "0.2.3",
|
||||
"verror": "1.10.0"
|
||||
}
|
||||
},
|
||||
"lodash": {
|
||||
"version": "4.17.20",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
|
||||
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA=="
|
||||
},
|
||||
"lodash.assign": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz",
|
||||
"integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc="
|
||||
},
|
||||
"lodash.camelcase": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
|
||||
|
@ -988,6 +1251,14 @@
|
|||
"resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz",
|
||||
"integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA=="
|
||||
},
|
||||
"ltx": {
|
||||
"version": "2.10.0",
|
||||
"resolved": "https://registry.npmjs.org/ltx/-/ltx-2.10.0.tgz",
|
||||
"integrity": "sha512-RB4zR6Mrp/0wTNS9WxMvpgfht/7u/8QAC9DpPD19opL/4OASPa28uoliFqeDkLUU8pQ4aeAfATBZmz1aSAHkMw==",
|
||||
"requires": {
|
||||
"inherits": "^2.0.4"
|
||||
}
|
||||
},
|
||||
"make-error": {
|
||||
"version": "1.3.5",
|
||||
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz",
|
||||
|
@ -1001,6 +1272,16 @@
|
|||
"make-error": "^1.3.5"
|
||||
}
|
||||
},
|
||||
"md5.js": {
|
||||
"version": "1.3.5",
|
||||
"resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
|
||||
"integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==",
|
||||
"requires": {
|
||||
"hash-base": "^3.0.0",
|
||||
"inherits": "^2.0.1",
|
||||
"safe-buffer": "^5.1.2"
|
||||
}
|
||||
},
|
||||
"media-typer": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
|
||||
|
@ -1171,6 +1452,79 @@
|
|||
"tar": "^4.4.2"
|
||||
}
|
||||
},
|
||||
"node-xmpp-client": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/node-xmpp-client/-/node-xmpp-client-3.2.0.tgz",
|
||||
"integrity": "sha1-r0Un3wzFq9JpDLohOcwezcgeoYk=",
|
||||
"requires": {
|
||||
"browser-request": "^0.3.3",
|
||||
"debug": "^2.2.0",
|
||||
"md5.js": "^1.3.3",
|
||||
"minimist": "^1.2.0",
|
||||
"node-xmpp-core": "^5.0.9",
|
||||
"request": "^2.65.0",
|
||||
"ws": "^1.1.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "2.6.9",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
||||
"requires": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
|
||||
},
|
||||
"ws": {
|
||||
"version": "1.1.5",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-1.1.5.tgz",
|
||||
"integrity": "sha512-o3KqipXNUdS7wpQzBHSe180lBGO60SoK0yVo3CYJgb2MkobuWuBX6dhkYP5ORCLd55y+SaflMOV5fqAB53ux4w==",
|
||||
"requires": {
|
||||
"options": ">=0.0.5",
|
||||
"ultron": "1.0.x"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"node-xmpp-core": {
|
||||
"version": "5.0.9",
|
||||
"resolved": "https://registry.npmjs.org/node-xmpp-core/-/node-xmpp-core-5.0.9.tgz",
|
||||
"integrity": "sha1-XCjCjtsfs/i+uixnYHd2E/SPNCo=",
|
||||
"requires": {
|
||||
"@xmpp/jid": "^0.0.2",
|
||||
"@xmpp/streamparser": "^0.0.6",
|
||||
"@xmpp/xml": "^0.1.3",
|
||||
"debug": "^2.2.0",
|
||||
"inherits": "^2.0.1",
|
||||
"lodash.assign": "^4.0.0",
|
||||
"node-xmpp-tls-connect": "^1.0.1",
|
||||
"reconnect-core": "https://github.com/dodo/reconnect-core/tarball/merged"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "2.6.9",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
||||
"requires": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
|
||||
}
|
||||
}
|
||||
},
|
||||
"node-xmpp-tls-connect": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/node-xmpp-tls-connect/-/node-xmpp-tls-connect-1.0.1.tgz",
|
||||
"integrity": "sha1-kazkOsJrE4hhsr5HjfnfGdYdxcM="
|
||||
},
|
||||
"nopt": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz",
|
||||
|
@ -1236,6 +1590,11 @@
|
|||
"commander": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"oauth-sign": {
|
||||
"version": "0.9.0",
|
||||
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
|
||||
"integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ=="
|
||||
},
|
||||
"object-assign": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||
|
@ -1262,6 +1621,11 @@
|
|||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"version": "0.0.6",
|
||||
"resolved": "https://registry.npmjs.org/options/-/options-0.0.6.tgz",
|
||||
"integrity": "sha1-7CLTEoBrtT5zF3Pnza788cZDEo8="
|
||||
},
|
||||
"os-homedir": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
|
||||
|
@ -1317,6 +1681,11 @@
|
|||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
|
||||
"integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
|
||||
},
|
||||
"performance-now": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
|
||||
"integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
|
||||
},
|
||||
"picomatch": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz",
|
||||
|
@ -1342,6 +1711,21 @@
|
|||
"ipaddr.js": "1.9.0"
|
||||
}
|
||||
},
|
||||
"psl": {
|
||||
"version": "1.8.0",
|
||||
"resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
|
||||
"integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ=="
|
||||
},
|
||||
"punycode": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
|
||||
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
|
||||
},
|
||||
"qbox": {
|
||||
"version": "0.1.7",
|
||||
"resolved": "https://registry.npmjs.org/qbox/-/qbox-0.1.7.tgz",
|
||||
"integrity": "sha1-6A8NxdCfhp2IghaMP2asjdKEDwI="
|
||||
},
|
||||
"qs": {
|
||||
"version": "6.7.0",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
|
||||
|
@ -1418,6 +1802,13 @@
|
|||
"picomatch": "^2.2.1"
|
||||
}
|
||||
},
|
||||
"reconnect-core": {
|
||||
"version": "https://github.com/dodo/reconnect-core/tarball/merged",
|
||||
"integrity": "sha512-wZK/v5ZaNaSUs2Wnwh2YSX/Jqv6bQHKNEwojdzV11tByKziR9ikOssf5tvUhx+8/oCBz6AakOFAjZuqPoiRHJQ==",
|
||||
"requires": {
|
||||
"backoff": "~2.3.0"
|
||||
}
|
||||
},
|
||||
"recursive-readdir": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.2.tgz",
|
||||
|
@ -1426,6 +1817,40 @@
|
|||
"minimatch": "3.0.4"
|
||||
}
|
||||
},
|
||||
"request": {
|
||||
"version": "2.88.2",
|
||||
"resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz",
|
||||
"integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==",
|
||||
"requires": {
|
||||
"aws-sign2": "~0.7.0",
|
||||
"aws4": "^1.8.0",
|
||||
"caseless": "~0.12.0",
|
||||
"combined-stream": "~1.0.6",
|
||||
"extend": "~3.0.2",
|
||||
"forever-agent": "~0.6.1",
|
||||
"form-data": "~2.3.2",
|
||||
"har-validator": "~5.1.3",
|
||||
"http-signature": "~1.2.0",
|
||||
"is-typedarray": "~1.0.0",
|
||||
"isstream": "~0.1.2",
|
||||
"json-stringify-safe": "~5.0.1",
|
||||
"mime-types": "~2.1.19",
|
||||
"oauth-sign": "~0.9.0",
|
||||
"performance-now": "^2.1.0",
|
||||
"qs": "~6.5.2",
|
||||
"safe-buffer": "^5.1.2",
|
||||
"tough-cookie": "~2.5.0",
|
||||
"tunnel-agent": "^0.6.0",
|
||||
"uuid": "^3.3.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"qs": {
|
||||
"version": "6.5.2",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
|
||||
"integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"rimraf": {
|
||||
"version": "2.7.1",
|
||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
|
||||
|
@ -1564,6 +1989,15 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"simple-xmpp": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/simple-xmpp/-/simple-xmpp-1.3.1.tgz",
|
||||
"integrity": "sha512-o0wGVlI8Q4o0qTz6Kylbo1QPOMVn+DA/vyHHZecqcQ+LK4ZWGe3wtRON9QjHAkSyxB36PoagmiUz4pHADau8Mw==",
|
||||
"requires": {
|
||||
"node-xmpp-client": "^3.0.0",
|
||||
"qbox": "0.1.x"
|
||||
}
|
||||
},
|
||||
"snekfetch": {
|
||||
"version": "3.6.4",
|
||||
"resolved": "https://registry.npmjs.org/snekfetch/-/snekfetch-3.6.4.tgz",
|
||||
|
@ -1742,6 +2176,29 @@
|
|||
"resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.1.tgz",
|
||||
"integrity": "sha1-R1OT/56RR5rqYtyvDKPRSYOn+0A="
|
||||
},
|
||||
"sshpk": {
|
||||
"version": "1.16.1",
|
||||
"resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
|
||||
"integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==",
|
||||
"requires": {
|
||||
"asn1": "~0.2.3",
|
||||
"assert-plus": "^1.0.0",
|
||||
"bcrypt-pbkdf": "^1.0.0",
|
||||
"dashdash": "^1.12.0",
|
||||
"ecc-jsbn": "~0.1.1",
|
||||
"getpass": "^0.1.1",
|
||||
"jsbn": "~0.1.0",
|
||||
"safer-buffer": "^2.0.2",
|
||||
"tweetnacl": "~0.14.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"tweetnacl": {
|
||||
"version": "0.14.5",
|
||||
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
|
||||
"integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q="
|
||||
}
|
||||
}
|
||||
},
|
||||
"statuses": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
|
||||
|
@ -1829,6 +2286,15 @@
|
|||
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
|
||||
"integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw=="
|
||||
},
|
||||
"tough-cookie": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
|
||||
"integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
|
||||
"requires": {
|
||||
"psl": "^1.1.28",
|
||||
"punycode": "^2.1.1"
|
||||
}
|
||||
},
|
||||
"ts-node": {
|
||||
"version": "8.5.4",
|
||||
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.5.4.tgz",
|
||||
|
@ -1846,6 +2312,14 @@
|
|||
"resolved": "https://registry.npmjs.org/ts-toolbelt/-/ts-toolbelt-6.9.9.tgz",
|
||||
"integrity": "sha512-5a8k6qfbrL54N4Dw+i7M6kldrbjgDWb5Vit8DnT+gwThhvqMg8KtxLE5Vmnft+geIgaSOfNJyAcnmmlflS+Vdg=="
|
||||
},
|
||||
"tunnel-agent": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
|
||||
"integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
|
||||
"requires": {
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"tweetnacl": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz",
|
||||
|
@ -1865,11 +2339,24 @@
|
|||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.6.3.tgz",
|
||||
"integrity": "sha512-N7bceJL1CtRQ2RiG0AQME13ksR7DiuQh/QehubYcghzv20tnh+MQnQIuJddTmsbqYj+dztchykemz0zFzlvdQw=="
|
||||
},
|
||||
"ultron": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/ultron/-/ultron-1.0.2.tgz",
|
||||
"integrity": "sha1-rOEWq1V80Zc4ak6I9GhTeMiy5Po="
|
||||
},
|
||||
"unpipe": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
|
||||
"integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
|
||||
},
|
||||
"uri-js": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz",
|
||||
"integrity": "sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g==",
|
||||
"requires": {
|
||||
"punycode": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
|
@ -1880,11 +2367,26 @@
|
|||
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
|
||||
"integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
|
||||
},
|
||||
"uuid": {
|
||||
"version": "3.4.0",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
|
||||
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
|
||||
},
|
||||
"vary": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
||||
"integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
|
||||
},
|
||||
"verror": {
|
||||
"version": "1.10.0",
|
||||
"resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
|
||||
"integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
|
||||
"requires": {
|
||||
"assert-plus": "^1.0.0",
|
||||
"core-util-is": "1.0.2",
|
||||
"extsprintf": "^1.2.0"
|
||||
}
|
||||
},
|
||||
"wide-align": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "satyr",
|
||||
"version": "0.10.0",
|
||||
"version": "0.10.1",
|
||||
"description": "A livestreaming server.",
|
||||
"license": "AGPL-3.0",
|
||||
"author": "knotteye",
|
||||
|
@ -33,6 +33,7 @@
|
|||
"nunjucks": "^3.2.1",
|
||||
"parse-yaml": "^0.1.0",
|
||||
"recursive-readdir": "^2.2.2",
|
||||
"simple-xmpp": "^1.3.1",
|
||||
"socket-anti-spam": "^2.0.0",
|
||||
"socket.io": "^2.3.0",
|
||||
"strftime": "^0.10.0",
|
||||
|
|
|
@ -3,12 +3,13 @@
|
|||
<link rel="stylesheet" type="text/css" href="/styles.css">
|
||||
<link rel="stylesheet" type="text/css" href="/local.css">
|
||||
<link rel="icon" type="image/svg" href="/logo.svg">
|
||||
|
||||
<script src="/nunjucks-slim.js"></script>
|
||||
<script src="/templates.js"></script>
|
||||
<script src="/dashjs/dash.all.min.js"></script>
|
||||
|
||||
<script>
|
||||
nunjucks.configure({ autoescape: true });
|
||||
</script>
|
||||
<script>
|
||||
//should check for and refresh login tokens on pageload..
|
||||
if(document.cookie.match(/^(.*;)?\s*X-Auth-As\s*=\s*[^;]+(.*)?$/) !== null) {
|
||||
var xhr = new XMLHttpRequest();
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
async function render(path){
|
||||
async function render(path, s){
|
||||
var context = await getContext();
|
||||
if(!s)
|
||||
history.pushState({}, context.sitename, location.protocol+'//'+location.host+path);
|
||||
switch(path){
|
||||
//nothing but context
|
||||
case (path.match(/^\/about\/?$/) || {}).input:
|
||||
|
@ -80,6 +82,7 @@ async function render(path){
|
|||
if(!config.title){document.body.innerHTML = nunjucks.render('404.njk', context); break;}
|
||||
document.body.innerHTML = nunjucks.render('user.njk', Object.assign({about: config.about, title: config.title, username: config.username}, context));
|
||||
modifyLinks();
|
||||
startVideo();
|
||||
break;
|
||||
case (path.match(/^\/vods\/.+\/manage\/?$/) || {}).input: // /vods/:user/manage
|
||||
var usr = path.substring(6, (path.length - 7));
|
||||
|
@ -103,6 +106,9 @@ async function render(path){
|
|||
case "":
|
||||
render('/users/live');
|
||||
break;
|
||||
case "/index.html":
|
||||
render('/users/live');
|
||||
break;
|
||||
//404
|
||||
default:
|
||||
document.body.innerHTML = nunjucks.render('404.njk', context);
|
||||
|
@ -110,6 +116,10 @@ async function render(path){
|
|||
}
|
||||
}
|
||||
|
||||
window.addEventListener('popstate', (event) => {
|
||||
render(document.location.pathname, true);
|
||||
});
|
||||
|
||||
async function getContext(){
|
||||
var info = JSON.parse(await makeRequest('GET', '/api/instance/info'));
|
||||
info.sitename = info.name;
|
||||
|
@ -167,4 +177,43 @@ function modifyLinks() {
|
|||
function internalLink(path){
|
||||
this.render(path);
|
||||
return false;
|
||||
}
|
||||
|
||||
//start dash.js
|
||||
async function startVideo(){
|
||||
//var url = "/live/{{username}}/index.mpd";
|
||||
//var player = dashjs.MediaPlayer().create();
|
||||
//player.initialize(document.querySelector("#videoPlayer"), url, true);
|
||||
//console.log('called startvideo');
|
||||
while(true){
|
||||
if(!document.querySelector('#videoPlayer'))
|
||||
break;
|
||||
|
||||
if(window.location.pathname.substring(window.location.pathname.length - 1) !== '/'){
|
||||
var url = "/api/"+window.location.pathname.substring(7)+"/config";
|
||||
console.log(url)
|
||||
var xhr = JSON.parse(await makeRequest("GET", url));
|
||||
if(xhr.live){
|
||||
var player = dashjs.MediaPlayer().create();
|
||||
player.initialize(document.querySelector("#videoPlayer"), url, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
else{
|
||||
var url = "/api/"+window.location.pathname.substring(7, window.location.pathname.length - 1)+"/config";
|
||||
console.log(url)
|
||||
var xhr = JSON.parse(await makeRequest("GET", url));
|
||||
if(xhr.live){
|
||||
var player = dashjs.MediaPlayer().create();
|
||||
player.initialize(document.querySelector("#videoPlayer"), url, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
await sleep(60000);
|
||||
}
|
||||
}
|
||||
|
||||
function sleep(ms) {
|
||||
return new Promise(resolve => setTimeout(resolve, ms));
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
/* This file is for themeing Satyr's frontend without worrying about changes
|
||||
being overwritten. Feel free to make whatever local changes you want here. */
|
|
@ -86,7 +86,7 @@ async function getConfig(username: string, all?: boolean): Promise<object>{
|
|||
if(all) {
|
||||
let users = await db.query('SELECT stream_key,record_flag FROM users WHERE username='+db.raw.escape(username));
|
||||
if(users[0]) Object.assign(t, users[0]);
|
||||
let usermeta = await db.query('SELECT title,about FROM user_meta WHERE username='+db.raw.escape(username));
|
||||
let usermeta = await db.query('SELECT title,about,live FROM user_meta WHERE username='+db.raw.escape(username));
|
||||
if(usermeta[0]) Object.assign(t, usermeta[0]);
|
||||
let ci = await db.query('SELECT irc,xmpp,twitch,discord FROM chat_integration WHERE username='+db.raw.escape(username));
|
||||
if(ci[0]) Object.assign(t, ci[0]);
|
||||
|
@ -94,7 +94,7 @@ async function getConfig(username: string, all?: boolean): Promise<object>{
|
|||
if(tw[0]) t['twitch_mirror'] = Object.assign({}, tw[0]);
|
||||
}
|
||||
else {
|
||||
let um = await db.query('SELECT title,about FROM user_meta WHERE username='+db.raw.escape(username));
|
||||
let um = await db.query('SELECT title,about,live FROM user_meta WHERE username='+db.raw.escape(username));
|
||||
if(um[0]) Object.assign(t, um[0]);
|
||||
}
|
||||
return t;
|
||||
|
|
51
src/chat.ts
51
src/chat.ts
|
@ -4,9 +4,12 @@ import {io} from "./http";
|
|||
import * as irc from "irc";
|
||||
import * as discord from "discord.js";
|
||||
import * as twitch from "dank-twitch-irc";
|
||||
import * as xmpp from "simple-xmpp";
|
||||
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
|
||||
|
||||
var ircClient;
|
||||
var xmppClient;
|
||||
var xmppIgnore: Array<string> = [];
|
||||
var xmppJoined: Array<string> = [];
|
||||
var twitchClient;
|
||||
var twitchArr: Array<string> = [];
|
||||
var discordClient;
|
||||
|
@ -51,7 +54,24 @@ async function init() {
|
|||
});
|
||||
}
|
||||
if(config['chat']['xmpp']['enabled']){
|
||||
|
||||
xmpp.on('online', (data) => {
|
||||
console.log("XMPP Client Ready");
|
||||
});
|
||||
xmpp.on('groupchat', function(conference, from, message, stamp) {
|
||||
if(xmppIgnore.findIndex((e) => { return e === conference }) !== -1) return false;
|
||||
if(from === config['chat']['xmpp']['nickname']) return false;
|
||||
console.log(from+'\n'+conference+'\n'+message+'\n'+stamp);
|
||||
var lu = getUsr(conference, "xmpp");
|
||||
for(var i=0;i<lu.length;i++){
|
||||
sendAll(lu[i], [from, message], "xmpp")
|
||||
}
|
||||
});
|
||||
xmpp.connect({
|
||||
jid: config['chat']['xmpp']['jid'],
|
||||
password: config['chat']['xmpp']['password'],
|
||||
host: config['chat']['xmpp']['server'],
|
||||
port: config['chat']['xmpp']['port']
|
||||
});
|
||||
}
|
||||
if(config['chat']['twitch']['enabled']){
|
||||
twitchClient = new twitch.ChatClient({
|
||||
|
@ -96,12 +116,14 @@ async function updateInteg() {
|
|||
chatIntegration = [];
|
||||
if(config['chat']['irc']['enabled']) updateIRCChan();
|
||||
if(config['chat']['twitch']['enabled']) updateTwitchChan();
|
||||
if(config['chat']['xmpp']['enabled']) updateXmppChan();
|
||||
return;
|
||||
}
|
||||
if(liveUsers.length === 1) {
|
||||
chatIntegration = await db.query('SELECT * FROM chat_integration WHERE username='+db.raw.escape(liveUsers[0]['username']));
|
||||
if(config['chat']['irc']['enabled']) updateIRCChan();
|
||||
if(config['chat']['twitch']['enabled']) updateTwitchChan();
|
||||
if(config['chat']['xmpp']['enabled']) updateXmppChan();
|
||||
return;
|
||||
}
|
||||
var qs: string;
|
||||
|
@ -112,6 +134,7 @@ async function updateInteg() {
|
|||
chatIntegration = await db.query('SELECT * FROM chat_integration WHERE username='+qs);
|
||||
if(config['chat']['irc']['enabled']) updateIRCChan();
|
||||
if(config['chat']['twitch']['enabled']) updateTwitchChan();
|
||||
if(config['chat']['xmpp']['enabled']) updateXmppChan();
|
||||
}
|
||||
|
||||
async function sendAll(user: string, msg: Array<string>, src: string) {
|
||||
|
@ -126,7 +149,7 @@ async function sendAll(user: string, msg: Array<string>, src: string) {
|
|||
if(src !== "irc") sendIRC(getCh(user, "irc"), '['+src.toUpperCase()+']'+msg[0]+': '+msg[1]);
|
||||
if(src !== "twitch") sendTwitch(getCh(user, "twitch"), '['+src.toUpperCase()+']'+msg[0]+': '+msg[1]);
|
||||
if(src !== "discord") sendDiscord(getCh(user, "discord"), '['+src.toUpperCase()+']'+msg[0]+': '+msg[1]);
|
||||
//if(src !== "xmpp") sendXMPP();
|
||||
if(src !== "xmpp") sendXMPP(getCh(user, "xmpp"), '['+src.toUpperCase()+']'+msg[0]+': '+msg[1]);
|
||||
if(src !== "web") sendWeb(user, ['['+src.toUpperCase()+']'+msg[0], msg[1]]);
|
||||
}
|
||||
|
||||
|
@ -146,6 +169,7 @@ async function sendDiscord(channel: string, msg: string) {
|
|||
async function sendXMPP(channel: string, msg: string) {
|
||||
if(!config['chat']['xmpp']['enabled']) return;
|
||||
if(channel === null) return;
|
||||
xmpp.send(channel, msg, true);
|
||||
}
|
||||
|
||||
async function sendTwitch(channel: string, msg: string) {
|
||||
|
@ -252,4 +276,25 @@ async function normalizeDiscordMsg(msg): Promise<string>{
|
|||
return nmsg;
|
||||
}
|
||||
|
||||
function xmppJoin(room: string): void{
|
||||
if(xmppJoined.findIndex((e) => { return e === room }) !== -1) return;
|
||||
var stanza = new xmpp.Element('presence', {"to": room+'/'+config['chat']['xmpp']['nickname']}).c('x', { xmlns: 'http://jabber.org/protocol/muc' }).c('history', { maxstanzas: 0, seconds: 0});
|
||||
xmpp.conn.send(stanza);
|
||||
xmppIgnore = xmppIgnore.concat([room]);
|
||||
xmpp.join(room+'/'+config['chat']['xmpp']['nickname']);
|
||||
xmppJoined = xmppJoined.concat([room]);
|
||||
sleep(4000).then(() => {
|
||||
xmppIgnore = xmppIgnore.filter((item) => {
|
||||
return item !== room;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function updateXmppChan(): void{
|
||||
for(var i=0;i<chatIntegration.length;i++){
|
||||
if(chatIntegration[i]['xmpp'].trim() !== "" && chatIntegration[i]['xmpp'] !== null) xmppJoin(chatIntegration[i]['xmpp']);
|
||||
}
|
||||
//we can't really leave channels so I'll come back to that.
|
||||
}
|
||||
|
||||
export { init, sendAll };
|
|
@ -133,14 +133,14 @@ if (cluster.isMaster) {
|
|||
db.query('update user_meta set live=true where username=\''+results[0].username+'\' limit 1');
|
||||
db.query('SELECT twitch_key,enabled from twitch_mirror where username='+db.raw.escape(results[0].username)+' limit 1').then(async (tm) => {
|
||||
if(!tm[0]['enabled'] || !config['twitch_mirror']['enabled'] || !config['twitch_mirror']['ingest']) return;
|
||||
console.log('[NodeMediaServer] Mirroring to twitch for stream:',id)
|
||||
console.log(`[RTMP Cluster WORKER ${process.pid}] Mirroring to twitch for stream: ${id}`)
|
||||
execFile(config['media']['ffmpeg'], ['-loglevel', 'fatal', '-i', 'rtmp://127.0.0.1:'+wPort+'/'+config['media']['privateEndpoint']+'/'+key, '-vcodec', 'copy', '-acodec', 'copy', '-f', 'flv', config['twitch_mirror']['ingest']+tm[0]['twitch_key']], {
|
||||
detached: true,
|
||||
stdio : 'inherit',
|
||||
maxBuffer: Infinity
|
||||
}).unref();
|
||||
});
|
||||
console.log('[NodeMediaServer] Stream key ok for stream:',id);
|
||||
console.log(`[RTMP Cluster WORKER ${process.pid}] Stream key ok for stream: ${id}`);
|
||||
console.log(`[RTMP Cluster WORKER ${process.pid}] Stream key ok for stream: ${id}`);
|
||||
//notify master process that we're handling the stream for this user
|
||||
process.send({type: 'handle-publish', name:results[0].username});
|
||||
|
@ -171,14 +171,14 @@ if (cluster.isMaster) {
|
|||
let key: string = StreamPath.split("/")[2];
|
||||
//correctly formatted urls again
|
||||
if (StreamPath.split("/").length !== 3){
|
||||
console.log("[NodeMediaServer] Malformed URL, closing connection for stream:",id);
|
||||
console.log(`[RTMP Cluster WORKER ${process.pid}] Malformed URL, closing connection for stream: ${id}`);
|
||||
session.reject();
|
||||
return false;
|
||||
}
|
||||
//localhost can play from whatever endpoint
|
||||
//other clients must use private endpoint
|
||||
if(app !== config['media']['publicEndpoint'] && !session.isLocal) {
|
||||
console.log("[NodeMediaServer] Non-local Play from private endpoint, rejecting client:",id);
|
||||
console.log(`[RTMP Cluster WORKER ${process.pid}] Non-local Play from private endpoint, rejecting client: ${id}`);
|
||||
session.reject();
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ const config: Object = {
|
|||
insecureAuth: false,
|
||||
debug: false }, localconfig['database']),
|
||||
rtmp: Object.assign({
|
||||
cluster: false,
|
||||
port: 1935,
|
||||
chunk_size: 6000,
|
||||
gop_cache: true,
|
||||
|
@ -75,8 +76,9 @@ const config: Object = {
|
|||
enabled: false,
|
||||
server: null,
|
||||
port: 5222,
|
||||
nickname: 'SatyrChat',
|
||||
username: 'SatyrChat'
|
||||
jid: null,
|
||||
password: null,
|
||||
nickname: 'SatyrChat'
|
||||
}, localconfig['chat']['xmpp']),
|
||||
|
||||
twitch: Object.assign({
|
||||
|
|
|
@ -168,6 +168,7 @@ async function initAPI() {
|
|||
app.get('/api/instance/config', (req, res) => {
|
||||
res.json({
|
||||
rtmp: {
|
||||
cluster: config['rtmp']['cluster'],
|
||||
port: config['rtmp']['port'],
|
||||
ping_timeout: config['rtmp']['ping_timeout']
|
||||
},
|
||||
|
|
|
@ -10,7 +10,7 @@ async function run() {
|
|||
await initDB();
|
||||
await clean();
|
||||
await initHTTP();
|
||||
config['rtmp']['cluster'] ? execFile(process.cwd()+'/node_modules/.bin/ts-node' [process.cwd()+'src/cluster.ts']) : await initRTMP();
|
||||
config['rtmp']['cluster'] ? execFile(process.cwd()+'/node_modules/.bin/ts-node', [process.cwd()+'/src/cluster.ts']) : await initRTMP();
|
||||
await initChat();
|
||||
console.log(`Satyr v${config['satyr']['version']} ready`);
|
||||
}
|
||||
|
|
|
@ -12,6 +12,29 @@
|
|||
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
|
||||
xhr.send("");
|
||||
}
|
||||
function makeRequest(method, url, payload) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
let xhr = new XMLHttpRequest();
|
||||
xhr.open(method, url);
|
||||
xhr.onload = function () {
|
||||
if (this.status >= 200 && this.status < 300) {
|
||||
resolve(xhr.response);
|
||||
} else {
|
||||
reject({
|
||||
status: this.status,
|
||||
statusText: xhr.statusText
|
||||
});
|
||||
}
|
||||
};
|
||||
xhr.onerror = function () {
|
||||
reject({
|
||||
status: this.status,
|
||||
statusText: xhr.statusText
|
||||
});
|
||||
};
|
||||
!payload ? xhr.send() : xhr.send(payload);
|
||||
});
|
||||
}
|
||||
</script>
|
||||
{% block head %}
|
||||
{% endblock %}
|
||||
|
|
|
@ -4,12 +4,43 @@
|
|||
<link rel="stylesheet" type="text/css" href="/videojs/video-js.min.css">-->
|
||||
<script src="/dashjs/dash.all.min.js"></script>
|
||||
<script>
|
||||
function startVideo(){
|
||||
var url = "/live/{{username}}/index.mpd";
|
||||
var player = dashjs.MediaPlayer().create();
|
||||
player.initialize(document.querySelector("#videoPlayer"), url, true);
|
||||
console.log('called startvideo');
|
||||
}
|
||||
async function startVideo(){
|
||||
//var url = "/live/{{username}}/index.mpd";
|
||||
//var player = dashjs.MediaPlayer().create();
|
||||
//player.initialize(document.querySelector("#videoPlayer"), url, true);
|
||||
//console.log('called startvideo');
|
||||
while(true){
|
||||
if(!document.querySelector('#videoPlayer'))
|
||||
break;
|
||||
|
||||
if(window.location.pathname.substring(window.location.pathname.length - 1) !== '/'){
|
||||
var url = "/api/"+window.location.pathname.substring(7)+"/config";
|
||||
console.log(url)
|
||||
var xhr = JSON.parse(await makeRequest("GET", url));
|
||||
if(xhr.live){
|
||||
var player = dashjs.MediaPlayer().create();
|
||||
player.initialize(document.querySelector("#videoPlayer"), url, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
else{
|
||||
var url = "/api/"+window.location.pathname.substring(7, window.location.pathname.length - 1)+"/config";
|
||||
console.log(url)
|
||||
var xhr = JSON.parse(await makeRequest("GET", url));
|
||||
if(xhr.live){
|
||||
var player = dashjs.MediaPlayer().create();
|
||||
player.initialize(document.querySelector("#videoPlayer"), url, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
await sleep(60000);
|
||||
}
|
||||
}
|
||||
|
||||
function sleep(ms) {
|
||||
return new Promise(resolve => setTimeout(resolve, ms));
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
|
@ -28,7 +59,7 @@ function newPopup(url) {
|
|||
|
||||
<!--this spits errors fucking constantly after it tries to reload a video that's already running.. I dunno if it's bad or causing problems so let's just push it to develop and wait for issues!-->
|
||||
<!--it plays the stream without reloading the page tho lol-->
|
||||
<script>window.setInterval(startVideo, 60000)</script>
|
||||
<script>startVideo()</script>
|
||||
</div>
|
||||
<div id="jschild" class="webchat" style="width: 30%;height: 100%;position: relative;">
|
||||
<iframe src="/chat?room={{ username }}" frameborder="0" style="width: 100%;height: 100%; min-height: 534px;" allowfullscreen></iframe>
|
||||
|
|
Reference in New Issue