From 8cc80833619761e8ce12f7d9f7c0142e2c06bab7 Mon Sep 17 00:00:00 2001 From: knotteye Date: Tue, 22 Oct 2019 17:54:57 -0500 Subject: [PATCH 01/10] Fix typo in usage instructions. --- docs/USAGE.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/USAGE.md b/docs/USAGE.md index 469ca57..38014d9 100644 --- a/docs/USAGE.md +++ b/docs/USAGE.md @@ -3,9 +3,9 @@ ### 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. ``` -[http] +[server.http] port = 8000 -[rtmp] +[server.rtmp] port = 1935 ``` Changing the rtmp port is not recommended. From 61bf54de95ea36ae977dea5a180b02b2de54a10e Mon Sep 17 00:00:00 2001 From: knotteye Date: Tue, 22 Oct 2019 18:24:10 -0500 Subject: [PATCH 02/10] Add cleanup script to fix any problems arising from restarting the server mid-stream. This may cause further problems if the user manages to reconnect before the cleanup script has finished, but the server *shouldn't* start listening until after the script is done. Increment version I guess, I don't really know how versioning works. --- package-lock.json | 10 +++++++++- package.json | 3 ++- src/cleanup.ts | 23 +++++++++++++++++++++++ src/controller.ts | 6 ++++-- 4 files changed, 38 insertions(+), 4 deletions(-) create mode 100644 src/cleanup.ts diff --git a/package-lock.json b/package-lock.json index a6ac8a9..cd52619 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "satyr", - "version": "0.2.0", + "version": "0.3.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -2370,6 +2370,14 @@ "readable-stream": "^2.0.2" } }, + "recursive-readdir": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.2.tgz", + "integrity": "sha512-nRCcW9Sj7NuZwa2XvH9co8NPeXUBhZP7CRKJtU+cS6PW9FpCIFoI5ib0NT1ZrbNuPoRy0ylyCaUL8Gih4LSyFg==", + "requires": { + "minimatch": "3.0.4" + } + }, "regex-not": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", diff --git a/package.json b/package.json index b4a9377..c1fb672 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "satyr", - "version": "0.3.0", + "version": "0.3.1", "description": "A livestreaming server.", "license": "AGPL-3.0", "author": "knotteye", @@ -24,6 +24,7 @@ "mysql": "^2.17.1", "node-media-server": ">=2.1.3 <3.0.0", "nunjucks": "^3.2.0", + "recursive-readdir": "^2.2.2", "socket.io": "^2.3.0", "toml": "^3.0.0" }, diff --git a/src/cleanup.ts b/src/cleanup.ts new file mode 100644 index 0000000..7fe1fa4 --- /dev/null +++ b/src/cleanup.ts @@ -0,0 +1,23 @@ +import * as db from "./database"; +import * as read from "recursive-readdir"; +import * as fs from "fs"; + +async function init(siteDir: string) { + //If satyr is restarted in the middle of a stream + //it causes problems + //Live flags in the database stay live + await db.query('update user_meta set live=false'); + //and stray m3u8 files will play the last + //few seconds of a stream back + try { + var files = await read(siteDir+'/live', ['!*.m3u8']); + } + catch (error) {} + if(files === undefined || files.length == 0) return; + for(let i=0;i Date: Tue, 5 Nov 2019 16:30:15 -0600 Subject: [PATCH 03/10] Add help page, change base links. Turn off watch in nunjucks config. I do not know if that made it master, hopefully not. --- package-lock.json | 2 +- src/controller.ts | 2 +- src/http.ts | 5 ++++- templates/base.njk | 2 +- templates/help.njk | 16 ++++++++++++++++ 5 files changed, 23 insertions(+), 4 deletions(-) create mode 100644 templates/help.njk diff --git a/package-lock.json b/package-lock.json index cd52619..fefe80b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "satyr", - "version": "0.3.0", + "version": "0.3.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/src/controller.ts b/src/controller.ts index 461eb8a..593679e 100644 --- a/src/controller.ts +++ b/src/controller.ts @@ -2,7 +2,7 @@ import * as mediaserver from "./server"; import * as db from "./database"; import * as api from "./api"; import * as http from "./http"; -import * as cleanup from "./cleanup" +import * as cleanup from "./cleanup"; import * as config from "config"; async function run() { diff --git a/src/http.ts b/src/http.ts index f0ee4ff..02e7e17 100644 --- a/src/http.ts +++ b/src/http.ts @@ -18,7 +18,7 @@ function init(satyr: any, port: number){ njk.configure('templates', { autoescape: true, express : app, - watch: true + watch: false }); njkconf ={ sitename: satyr.name, @@ -89,6 +89,9 @@ function init(satyr: any, port: number){ app.get('/chat', (req, res) => { res.render('chat.html', njkconf); }); + app.get('/help', (req, res) => { + res.render('help.njk', njkconf); + }); //api handlers app.post('/api/register', (req, res) => { api.register(req.body.username, req.body.password, req.body.confirm).then( (result) => { diff --git a/templates/base.njk b/templates/base.njk index 6fc4453..a7aa9e7 100644 --- a/templates/base.njk +++ b/templates/base.njk @@ -8,7 +8,7 @@
{% block content %} diff --git a/templates/help.njk b/templates/help.njk new file mode 100644 index 0000000..432eb09 --- /dev/null +++ b/templates/help.njk @@ -0,0 +1,16 @@ +{% extends "base.njk" %} +{% block content %} +

+

Chatting

+The webclient for chat can be accessed on the streamer's page, or at https://{{ domain }}/chat

+The following commands are available:
+`/nick kawen (password)` Password is only required if kawen is a registered user.
+`/join kawen` Join the chatroom for kawen's stream and leave the previous room.
+`/kick cvcvcv` Available only in your own room if you are a streamer. Forcefully disconnect the user.
+ +

Streaming

+Users should stream to rtmp://{{ domain }}/stream/Stream-Key

+The stream will be available at rtmp://{{ domain }}/live/username
or at your page on https://{{ domain }}/users/username
+
+Most software, such as OBS, will have a separate field for the URL and stream key, in which case you can enter rtmp://{{ domain }}/stream/ and the stream key in the appropriate field. +{% endblock %} \ No newline at end of file From 9076b1817ba37a28a36d286eccf2fe7da6f59b86 Mon Sep 17 00:00:00 2001 From: knotteye Date: Tue, 5 Nov 2019 17:22:52 -0600 Subject: [PATCH 04/10] Add contributors file Add irc.js for peering with IRC Change default to reflect that Add basic peering. Implemented: register/unregister a user messages join/part Not implemented/TODO: Kill, kick, change nick It is likely that the web chat will not have full feature parity with clients connecting directly to IRC. --- CONTRIBUTORS | 2 + config/default.toml | 6 +- src/controller.ts | 2 +- src/http.ts | 22 ++++- src/irc.js | 213 ++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 241 insertions(+), 4 deletions(-) create mode 100644 CONTRIBUTORS create mode 100644 src/irc.js diff --git a/CONTRIBUTORS b/CONTRIBUTORS new file mode 100644 index 0000000..dac1314 --- /dev/null +++ b/CONTRIBUTORS @@ -0,0 +1,2 @@ +knotteye +crushv \ No newline at end of file diff --git a/config/default.toml b/config/default.toml index cda1845..c7ff14d 100644 --- a/config/default.toml +++ b/config/default.toml @@ -12,9 +12,11 @@ rootredirect = '/users/live' [ircd] enable = false -port = 7000 -user = '' +port = 6667 +sid = '' +server = '' pass = '' +vhost = 'web.satyr.net' [database] host = 'localhost' diff --git a/src/controller.ts b/src/controller.ts index 593679e..8ed3e1d 100644 --- a/src/controller.ts +++ b/src/controller.ts @@ -56,7 +56,7 @@ async function run() { db.init(dbcfg, bcryptcfg); await cleanup.init(config.server.http.directory); api.init(satyr); - http.init(satyr, config.server.http.port); + http.init(satyr, config.server.http.port, config.ircd); mediaserver.init(nms, satyr); } run(); diff --git a/src/http.ts b/src/http.ts index 02e7e17..4593f4d 100644 --- a/src/http.ts +++ b/src/http.ts @@ -7,6 +7,7 @@ import * as http from "http"; import * as dirty from "dirty"; import * as api from "./api"; import * as db from "./database"; +import * as irc from "./irc"; const app = express(); const server = http.createServer(app); @@ -14,7 +15,7 @@ const io = socketio(server); const store = dirty(); var njkconf; -function init(satyr: any, port: number){ +async function init(satyr: any, port: number, ircconf: any){ njk.configure('templates', { autoescape: true, express : app, @@ -119,26 +120,44 @@ function init(satyr: any, port: number){ app.use(function (req, res, next) { res.status(404).render('404.njk', njkconf); }); + //irc peering + if(ircconf.enable){ + await irc.connect({ + port: ircconf.port, + sid: ircconf.sid, + pass: ircconf.pass, + server: ircconf.server, + vhost: ircconf.vhost + }); + irc.events.on('message', (nick, channel, msg) => { + io.to(channel).emit('MSG', {nick: nick, msg: msg}); + }); + } //socket.io chat logic io.on('connection', async (socket) => { socket.nick = await newNick(socket); + if(ircconf.enable) irc.registerUser(socket.nick); socket.on('JOINROOM', async (data) => { let t: any = await db.query('select username from users where username='+db.raw.escape(data)); if(t[0]){ socket.join(data); io.to(data).emit('JOINED', {nick: socket.nick}); + if(ircconf.enable) irc.join(socket.nick, data); } else socket.emit('ALERT', 'Room does not exist'); }); socket.on('LEAVEROOM', (data) => { socket.leave(data); + if(ircconf.enable) irc.part(socket.nick, data); io.to(data).emit('LEFT', {nick: socket.nick}); }); socket.on('disconnecting', (reason) => { let rooms = Object.keys(socket.rooms); for(let i=1;i { @@ -164,6 +183,7 @@ function init(satyr: any, port: number){ }); socket.on('MSG', (data) => { io.to(data.room).emit('MSG', {nick: socket.nick, msg: data.msg}); + if(ircconf.enable) irc.send(socket.nick, data.room, data.msg); }); socket.on('KICK', (data) => { if(socket.nick === data.room){ diff --git a/src/irc.js b/src/irc.js new file mode 100644 index 0000000..4427303 --- /dev/null +++ b/src/irc.js @@ -0,0 +1,213 @@ +// written by crushv +// thanks nikki + +const net = require('net') +const EventEmitter = require('events') + +const socket = new net.Socket() +const emitter = new EventEmitter() + +socket.setEncoding('utf8') + +socket.on('error', console.error) + +function m (text) { + console.log('> ' + text) + socket.write(text + '\r\n') +} + +var config + +socket.once('connect', async () => { + console.log('Connected') + m(`PASS ${config.pass} TS 6 :${config.sid}`) + m('CAPAB QS ENCAP EX IE SAVE EUID') + m(`SERVER ${config.server} 1 satyr`) +}) + +function parseLine (l) { + const colIndex = l.lastIndexOf(':') + if (colIndex > -1) { + return { + params: l.substring(0, colIndex - 1).split(' '), + query: l.substring(colIndex + 1) + } + } else return { params: l.split(' ') } +} + +const servers = [] +const users = {} +const channels = {} + +const globalCommands = { + // PING :42X + // params: SID + PING: l => { + const { query } = parseLine(l) + m(`PONG :${query}`) + emitter.emit('ping') + }, + // PASS hunter2 TS 6 :42X + // params: password, 'TS', TS version, SID + PASS: l => { + const { query } = parseLine(l) + // adds a server + servers.push(query) + } +} + +const serverCommands = { + // EUID nik 1 1569146316 +i ~nik localhost6.attlocal.net 0::1 42XAAAAAB * * :nik + // params: nickname, hopcount, nickTS, umodes, username, visible hostname, IP address, UID, real hostname, account name, gecos + EUID: l => { + const { params } = parseLine(l) + const user = { + nick: params[0], + nickTS: params[2], + modes: params[3], + username: params[4], + vhost: params[5], + ip: params[6], + uid: params[7] + } + users[user.uid] = user + }, + // SJOIN 1569142987 #test +nt :42XAAAAAB + // params: channelTS, channel, simple modes, opt. mode parameters..., nicklist + SJOIN: l => { + const { params, query } = parseLine(l) + const channel = { + timestamp: params[0], + name: params[1], + modes: params.slice(2).join(' '), + nicklist: query.split(' ').map(uid => { + if (/[^0-9a-zA-Z]/.test(uid[0])) return { uid: uid.slice(1), mode: uid[0] } + else return { uid: uid, mode: '' } + }) + } + channels[channel.name] = channel + } +} + +const userCommands = { + // :42XAAAAAC PRIVMSG #test :asd + // params: target, msg + PRIVMSG: (l, source) => { + const { params, query } = parseLine(l) + emitter.emit('message', users[source].nick, params[0], query) + }, + // :42XAAAAAC JOIN 1569149395 #test + + JOIN: (l, source) => { + const { params } = parseLine(l) + channels[params[1]].nicklist.push({ + uid: source + }) + }, + // :42XAAAAAC PART #test :WeeChat 2.6 + PART: (l, source) => { + const { params } = parseLine(l) + for (let i = 0; i < channels[params[0]].nicklist.length; i++) { + if (channels[params[0]].nicklist[i].uid === source) { + channels[params[0]].nicklist.splice(i, 1) + return + } + } + }, + QUIT: (_l, source) => { + delete users[source] + } +} + +function parser (l) { + const split = l.split(' ') + const cmd = split[0] + const args = split.slice(1).join(' ') + if (globalCommands[cmd]) return globalCommands[cmd](args) + if (cmd[0] === ':') { + const source = cmd.slice(1) + const subcmd = split[1] + const subargs = split.slice(2).join(' ') + if (servers.indexOf(source) > -1 && serverCommands[subcmd]) serverCommands[subcmd](subargs) + if (users[source] && userCommands[subcmd]) userCommands[subcmd](subargs, source) + } +} + +socket.on('data', data => { + data.split('\r\n') + .filter(l => l !== '') + .forEach(l => { + console.log('< ' + l) + parser(l) + }) +}) + +process.on('SIGINT', () => { + socket.write('QUIT\r\n') + process.exit() +}) + +module.exports.connect = conf => new Promise((resolve, reject) => { + emitter.once('ping', resolve) + config = conf + socket.connect(config.port) +}) +module.exports.events = emitter + +const genTS = () => Math.trunc((new Date()).getTime() / 1000) +const genUID = () => { + const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + var uid = '' + for (let i = 0; i < 6; i++) uid += chars.charAt(Math.floor(Math.random() * chars.length)) + if (users[uid]) return genUID() + return config.sid + uid +} +const getUID = nick => { + for (const key in users) if (users[key].nick === nick) return key +} + +module.exports.registerUser = nick => { + const user = { + nick: nick, + nickTS: genTS(), + modes: '+i', + username: '~' + nick, + vhost: config.vhost, + ip: '0::1', + uid: genUID() + } + users[user.uid] = user + m(`EUID ${user.nick} 1 ${user.nickTS} ${user.modes} ~${user.nick} ${user.vhost} 0::1 ${user.uid} * * :${user.nick}`) +} +module.exports.unregisterUser = nick => { + const uid = getUID(nick) + m(`:${uid} QUIT :Quit: satyr`) + delete users[uid] +} +module.exports.join = (nick, channelName) => { + const uid = getUID(nick) + if (!channels[channelName]) { + const channel = { + timestamp: genTS(), + name: channelName, + modes: '+nt', + nicklist: [{ uid: uid, mode: '' }] + } + channels[channel.name] = channel + } + m(`:${uid} JOIN ${channels[channelName].timestamp} ${channelName} +`) +} +module.exports.part = (nick, channelName) => { + const uid = getUID(nick) + m(`:${uid} PART ${channelName} :satyr`) + for (let i = 0; i < channels[channelName].nicklist.length; i++) { + if (channels[channelName].nicklist[i].uid === uid) { + channels[channelName].nicklist.splice(i, 1) + return + } + } +} +module.exports.send = (nick, channelName, message) => { + const uid = getUID(nick) + m(`:${uid} PRIVMSG ${channelName} :${message}`) + emitter.emit('message', nick, channelName, message) +} From 297aeb3d4a075a4987bb25c15d3a3c77e9c9dae8 Mon Sep 17 00:00:00 2001 From: knotteye Date: Tue, 5 Nov 2019 17:48:12 -0600 Subject: [PATCH 05/10] Move SIGINT listener to connect function to avoid socket does not exist errors Add conditional to disconnect peering --- src/http.ts | 2 +- src/irc.js | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/http.ts b/src/http.ts index 4593f4d..2e1c7b2 100644 --- a/src/http.ts +++ b/src/http.ts @@ -157,7 +157,7 @@ async function init(satyr: any, port: number, ircconf: any){ if(ircconf.enable) irc.part(socket.nick, rooms[i]); io.to(rooms[i]).emit('ALERT', socket.nick+' disconnected'); } - irc.unregisterUser(socket.nick); + if(ircconf.enable) irc.unregisterUser(socket.nick); store.rm(socket.nick); }); socket.on('NICK', async (data) => { diff --git a/src/irc.js b/src/irc.js index 4427303..86359e7 100644 --- a/src/irc.js +++ b/src/irc.js @@ -141,15 +141,14 @@ socket.on('data', data => { }) }) -process.on('SIGINT', () => { - socket.write('QUIT\r\n') - process.exit() -}) - module.exports.connect = conf => new Promise((resolve, reject) => { emitter.once('ping', resolve) config = conf socket.connect(config.port) + process.on('SIGINT', () => { + socket.write('QUIT\r\n') + process.exit() + }) }) module.exports.events = emitter From 97b1132ef019124ddaf9e4d6b32f55bf4f3ab1d5 Mon Sep 17 00:00:00 2001 From: knotteye Date: Sat, 9 Nov 2019 17:22:32 -0600 Subject: [PATCH 06/10] Fix typo on new stream key page --- templates/changesk.njk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/changesk.njk b/templates/changesk.njk index d5e6dbc..30802a6 100644 --- a/templates/changesk.njk +++ b/templates/changesk.njk @@ -1,6 +1,6 @@ {% extends "base.njk" %} {% block content %} -

Change your password on {{ sitename }}

Not registered yet? Sign up here.
Update your profile or password.
+

Get a new stream key on {{ sitename }}

Not registered yet? Sign up here.
Update your profile or password.

Username:

@@ -8,4 +8,4 @@
-{% endblock %} \ No newline at end of file +{% endblock %} From 73e91783e37ef2fc97109a2f044386ca1c2b3481 Mon Sep 17 00:00:00 2001 From: knotteye Date: Sun, 10 Nov 2019 08:27:00 -0600 Subject: [PATCH 07/10] Fix handling of usernames with capital letters in the web page. Add updating and backup/restore instructions. --- docs/INSTALLATION.md | 16 +++++++++++++++- src/http.ts | 4 ++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/docs/INSTALLATION.md b/docs/INSTALLATION.md index 37792db..abcf2eb 100644 --- a/docs/INSTALLATION.md +++ b/docs/INSTALLATION.md @@ -32,4 +32,18 @@ npm start ``` It is reccomended that you run Satyr behind a TLS terminating reverse proxy, like nginx. -An example systemd service is provided at install/satyr.service. It assumes you've installed satyr into /opt/satyr, and created a satyr user with the home directory /var/lib/satyr for the purpose of running the service. \ No newline at end of file +An example systemd service is provided at install/satyr.service. It assumes you've installed satyr into /opt/satyr, and created a satyr user with the home directory /var/lib/satyr for the purpose of running the service. + +## Updating Satyr +Updating should be as simple as pulling the latest code and dependencies, then building and restarting the server. + +```bash +git pull +npm i +npm run build +``` + +Then restart the server. + +## Migrating Satyr +To backup and restore, you will need to export the mysqlDB. Restore the new database from the backup, then copy the config/local.toml file and the site directory to the new install. \ No newline at end of file diff --git a/src/http.ts b/src/http.ts index 2e1c7b2..49f4a42 100644 --- a/src/http.ts +++ b/src/http.ts @@ -52,9 +52,9 @@ async function init(satyr: any, port: number, ircconf: any){ }); }); app.get('/users/*', (req, res) => { - njkconf.user = req.url.split('/')[2].toLowerCase(); - db.query('select title,about from user_meta where username='+db.raw.escape(njkconf.user)).then((result) => { + db.query('select username,title,about from user_meta where username='+db.raw.escape(req.url.split('/')[2].toLowerCase())).then((result) => { if(result[0]){ + njkconf.user = result[0].username; njkconf.streamtitle = result[0].title; njkconf.about = result[0].about; res.render('user.njk', njkconf); From 4e19bdc2f59622b535efe75d5c635e48339b0214 Mon Sep 17 00:00:00 2001 From: knotteye Date: Sun, 10 Nov 2019 09:07:23 -0600 Subject: [PATCH 08/10] Ignore empty messages in socket.io --- src/http.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/http.ts b/src/http.ts index 49f4a42..65e9f52 100644 --- a/src/http.ts +++ b/src/http.ts @@ -182,6 +182,7 @@ async function init(satyr: any, port: number, ircconf: any){ } }); socket.on('MSG', (data) => { + if(data.msg === "") return; io.to(data.room).emit('MSG', {nick: socket.nick, msg: data.msg}); if(ircconf.enable) irc.send(socket.nick, data.room, data.msg); }); From f5f9d1f8e68b828d971ef71d27e8e3c8e3c06dc6 Mon Sep 17 00:00:00 2001 From: knotteye Date: Sun, 10 Nov 2019 10:29:15 -0600 Subject: [PATCH 09/10] Play MPEG-DASH by default. Add dash.js and videojs-dash files --- config/default.toml | 4 +-- site/dashjs/AUTHORS.md | 49 ++++++++++++++++++++++++++++++++ site/dashjs/LICENSE.md | 14 +++++++++ site/dashjs/dash.all.min.js | 3 ++ site/videojs/videojs-dash.min.js | 2 ++ templates/user.njk | 6 ++-- 6 files changed, 74 insertions(+), 4 deletions(-) create mode 100644 site/dashjs/AUTHORS.md create mode 100644 site/dashjs/LICENSE.md create mode 100644 site/dashjs/dash.all.min.js create mode 100644 site/videojs/videojs-dash.min.js diff --git a/config/default.toml b/config/default.toml index c7ff14d..63074e6 100644 --- a/config/default.toml +++ b/config/default.toml @@ -53,7 +53,7 @@ privateEndpoint = 'stream' ffmpeg = '' [transcode] -hls = true +hls = false hlsFlags = '[hls_time=2:hls_list_size=3:hls_flags=delete_segments]' -dash = false +dash = true dashFlags = '[f=dash:window_size=3:extra_window_size=5]' \ No newline at end of file diff --git a/site/dashjs/AUTHORS.md b/site/dashjs/AUTHORS.md new file mode 100644 index 0000000..9488135 --- /dev/null +++ b/site/dashjs/AUTHORS.md @@ -0,0 +1,49 @@ +# Dash.js Authors List +#####Please add entries to the bottom of the list in the following format +* @GitHub UserName (Required) [Name and/or Organization] (Optional) + +#Authors +* @nweber [Digital Primates] +* @jefftapper [Jeff Tapper, Digital Primates] +* @KozhinM [Mikail Kozhin, Microsoft Open Technologies] +* @kirkshoop [Kirk Shoop, Microsoft Open Technologies] +* @wilaw [Will Law, Akamai Technologies] +* @AkamaiDASH [Dan Sparacio, Akamai Technologies] +* @dsilhavy [Daniel Silhavy, Fraunhofer Fokus] +* @greg80303 [Greg Rutz, CableLabs] +* @heff [Steve Hefferman, Brightcove] +* @Tomjohnson916 [Tom Johnson, Brightcove] +* @jeroenwiljering [Jeroen Wijering, JWPlayer] +* @bbcrddave [David Evans, BBC R&D] +* @bbert [Bertrand Berthelot, Orange] +* @vigneshvg [Vignesh Venkatasubramanian, Google] +* @nicosang [Nicolas Angot, Orange] +* @PriyadarshiniV +* @senthil-codr [Senthil] +* @dweremeichik [Dylan Weremeichik] +* @aleal-envivio +* @mconlin +* @umavinoth +* @lbonn +* @mdale [Michael Dale, Kaltura] +* @sgrebnov [Sergey Grebnov, Microsoft Open Technologies] +* @wesleytodd [Wes Todd, Vubeology] +* @colde [Loke Dupont, Xstream] +* @rgardler [Ross Gardler, Microsoft Open Technologies] +* @squapp +* @xiaomings +* @rcollins112 [Rich Collins, Wowza] +* @timothy003 [Timothy Liang] +* @JaapHaitsma +* @72lions [Thodoris Tsiridis, 72lions] +* @TobbeMobiTV [Torbjörn Einarsson, MobiTV] +* @TobbeEdgeware [Torbjörn Einarsson, Edgeware] +* @mstorsjo [Martin Storsjö] +* @Hyddan [Daniel Hedenius] +* @qjia7 +* @waqarz +* @WMSPanel [WMSPanel Team] +* @matt-hammond-bbc [Matt Hammond, BBC R&D] +* @siropeich [Siro Blanco, Epic Labs] +* @epiclabsDASH [Jesus Oliva, Epic Labs] +* @adripanico [Adrian Caballero, Epic Labs] diff --git a/site/dashjs/LICENSE.md b/site/dashjs/LICENSE.md new file mode 100644 index 0000000..f7517a4 --- /dev/null +++ b/site/dashjs/LICENSE.md @@ -0,0 +1,14 @@ +# dash.js BSD License Agreement + +The copyright in this software is being made available under the BSD License, included below. This software may be subject to other third party and contributor rights, including patent rights, and no such rights are granted under this license. + +**Copyright (c) 2015, Dash Industry Forum. +**All rights reserved.** + +* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: +* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. +* Neither the name of the Dash Industry Forum nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +**THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.** + \ No newline at end of file diff --git a/site/dashjs/dash.all.min.js b/site/dashjs/dash.all.min.js new file mode 100644 index 0000000..6b18d5e --- /dev/null +++ b/site/dashjs/dash.all.min.js @@ -0,0 +1,3 @@ +/*! v3.0.0-b0f46e83, 2019-06-29T00:07:30Z */ +!function a(o,s,u){function l(t,e){if(!s[t]){if(!o[t]){var n="function"==typeof require&&require;if(!e&&n)return n(t,!0);if(f)return f(t,!0);var r=new Error("Cannot find module '"+t+"'");throw r.code="MODULE_NOT_FOUND",r}var i=s[t]={exports:{}};o[t][0].call(i.exports,function(e){return l(o[t][1][e]||e)},i,i.exports,a,o,s,u)}return s[t].exports}for(var f="function"==typeof require&&require,e=0;e>6):(r<65536?t.push(224|r>>12):(t.push(240|r>>18),t.push(128|63&r>>12)),t.push(128|63&r>>6)),t.push(128|63&r))}return t},decode:function(e){for(var t=[],n=0;n>18)),n.push(o.charAt(63&i>>12)),n.push(o.charAt(63&i>>6)),n.push(o.charAt(63&i))}if(2==e.length-t){i=(e[t]<<16)+(e[t+1]<<8);n.push(o.charAt(63&i>>18)),n.push(o.charAt(63&i>>12)),n.push(o.charAt(63&i>>6)),n.push("=")}else if(1==e.length-t){i=e[t]<<16;n.push(o.charAt(63&i>>18)),n.push(o.charAt(63&i>>12)),n.push("==")}return n.join("")}function d(e){for(var t=0,n=[],r=0|e.length/4;0>16),n.push(255&i>>8),n.push(255&i),t+=4}return n&&("="==e.charAt(t-2)?(n.pop(),n.pop()):"="==e.charAt(t-1)&&n.pop()),n}o="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",u=function(){for(var e=[],t=0;t=n&&console.log(this.time+" ["+e+"] "+t)}};o.prototype={reset:function(){this.foreground="white",this.underline=!1,this.italics=!1,this.background="black",this.flash=!1},setStyles:function(e){for(var t=["foreground","underline","italics","background","flash"],n=0;n ("+u([r,i])+")"),!(n=(n=(n=(n=this.parseCmd(r,i))||this.parseMidrow(r,i))||this.parsePAC(r,i))||this.parseBackgroundAttributes(r,i)))if(a=this.parseChars(r,i))if(this.currChNr&&0<=this.currChNr)this.channels[this.currChNr-1].insertChars(a);else h.log("WARNING","No channel found yet. TEXT-MODE?");n?this.dataCounters.cmd+=2:a?this.dataCounters.char+=2:(this.dataCounters.other+=2,h.log("WARNING","Couldn't parse cleaned data "+u([r,i])+" orig: "+u([t[o],t[o+1]])))}else this.dataCounters.padding+=2},parseCmd:function(e,t){var n=null;if(!((20===e||21===e||28===e||29===e)&&32<=t&&t<=47)&&!((23===e||31===e)&&33<=t&&t<=35))return!1;n=20===e||21===e||23===e?1:2;var r=this.channels[n-1];return 20===e||21===e||28===e||29===e?32===t?r.cc_RCL():33===t?r.cc_BS():34===t?r.cc_AOF():35===t?r.cc_AON():36===t?r.cc_DER():37===t?r.cc_RU(2):38===t?r.cc_RU(3):39===t?r.cc_RU(4):40===t?r.cc_FON():41===t?r.cc_RDC():42===t?r.cc_TR():43===t?r.cc_RTD():44===t?r.cc_EDM():45===t?r.cc_CR():46===t?r.cc_ENM():47===t&&r.cc_EOC():r.cc_TO(t-32),this.lastCmdA=e,this.lastCmdB=t,this.currChNr=n,!0},parseMidrow:function(e,t){var n=null;if((17===e||25===e)&&32<=t&&t<=47){if((n=17===e?1:2)!==this.currChNr)return h.log("ERROR","Mismatch channel in midrow parsing"),!1;var r=this.channels[n-1];return r.insertChars([32]),r.cc_MIDROW(t),h.log("DEBUG","MIDROW ("+u([e,t])+")"),this.lastCmdA=e,this.lastCmdB=t,!0}return!1},parsePAC:function(e,t){var n,r=null;if(!((17<=e&&e<=23||25<=e&&e<=31)&&64<=t&&t<=127)&&!((16===e||24===e)&&64<=t&&t<=95))return!1;n=e<=23?1:2,r=64<=t&&t<=95?1==n?a[e]:f[e]:1==n?l[e]:d[e];var i=this.interpretPAC(r,t);return this.channels[n-1].setPAC(i),this.lastCmdA=e,this.lastCmdB=t,this.currChNr=n,!0},interpretPAC:function(e,t){var n=t,r={color:null,italics:!1,indent:null,underline:!1,row:e};return n=95/g,">").replace(/"/g,""").replace(/'/g,"'"):e}function R(e,t,n,r){for(var i=0;i":">"}function f(e,t){return""}function d(e,t){return!!("property"==A.arrayAccessForm&&function(e,t){return-1!==e.indexOf(t,e.length-t.length)}(t.toString(),"_asArray")||0==t.toString().indexOf(A.attributePrefix)||0==t.toString().indexOf("__")||e[t]instanceof Function)}function c(e){var t=0;if(e instanceof Object)for(var n in e)d(e,n)||t++;return t}function h(e){var t=[];if(e instanceof Object)for(var n in e)-1==n.toString().indexOf("__")&&0==n.toString().indexOf(A.attributePrefix)&&t.push(n);return t}function p(e){var t="";return e instanceof Object?t+=function(e){var t="";return null!=e.__cdata&&(t+=""),null!=e.__text&&(A.escapeMode?t+=u(e.__text):t+=e.__text),t}(e):null!=e&&(A.escapeMode?t+=u(e):t+=e),t}function g(e,t){return""===e?t:e+"."+t}function _(e,t,n,r){var i="";if(0==e.length)i+=l(e,t,n,!0);else for(var a=0;a")+2)),(t=new ActiveXObject("Microsoft.XMLDOM")).async="false",t.loadXML(e);return t},this.asArray=function(e){return void 0===e||null==e?[]:e instanceof Array?e:[e]},this.toXmlDateTime=function(e){return e instanceof Date?e.toISOString():"number"==typeof e?new Date(e).toISOString():null},this.asDateTime=function(e){return"string"==typeof e?M(e):e},this.xml2json=function(e){return C(e)},this.xml_str2json=function(e){var t=this.parseXmlString(e);return null!=t?this.xml2json(t):null},this.json2xml_str=function(e){return m(e,"")},this.json2xml=function(e){var t=this.json2xml_str(e);return this.parseXmlString(t)},this.getVersion=function(){return"1.2.0"}},t.exports=n.default},{}],4:[function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(n,"__esModule",{value:!0});var i=e(5),a=r(e(125)),o=r(e(159)),s=r(e(103)),u=r(e(47));dashjs.Protection=o.default,dashjs.MetricsReporting=a.default,dashjs.MediaPlayerFactory=s.default,dashjs.Debug=u.default,n.default=dashjs,n.MediaPlayer=i.MediaPlayer,n.Protection=o.default,n.MetricsReporting=a.default,n.MediaPlayerFactory=s.default,n.Debug=u.default},{103:103,125:125,159:159,47:47,5:5}],5:[function(u,e,l){(function(e){"use strict";function t(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(l,"__esModule",{value:!0});var n=t(u(101)),r=t(u(49)),i=t(u(47)),a=u(52),o="undefined"!=typeof window&&window||e,s=o.dashjs;(s=s||(o.dashjs={})).MediaPlayer=n.default,s.FactoryMaker=r.default,s.Debug=i.default,s.Version=(0,a.getVersionString)(),l.default=s,l.MediaPlayer=n.default,l.FactoryMaker=r.default,l.Debug=i.default}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{101:101,47:47,49:49,52:52}],6:[function(e,t,n){"use strict";n.byteLength=function(e){var t=d(e),n=t[0],r=t[1];return 3*(n+r)/4-r},n.toByteArray=function(e){for(var t,n=d(e),r=n[0],i=n[1],a=new f(function(e,t,n){return 3*(t+n)/4-n}(0,r,i)),o=0,s=0>16&255,a[o++]=t>>8&255,a[o++]=255&t;2===i&&(t=l[e.charCodeAt(u)]<<2|l[e.charCodeAt(u+1)]>>4,a[o++]=255&t);1===i&&(t=l[e.charCodeAt(u)]<<10|l[e.charCodeAt(u+1)]<<4|l[e.charCodeAt(u+2)]>>2,a[o++]=t>>8&255,a[o++]=255&t);return a},n.fromByteArray=function(e){for(var t,n=e.length,r=n%3,i=[],a=0,o=n-r;a>2]+s[t<<4&63]+"==")):2==r&&(t=(e[n-2]<<8)+e[n-1],i.push(s[t>>10]+s[t>>4&63]+s[t<<2&63]+"="));return i.join("")};for(var s=[],l=[],f="undefined"!=typeof Uint8Array?Uint8Array:Array,r="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",i=0,a=r.length;i>18&63]+s[i>>12&63]+s[i>>6&63]+s[63&i]);return a.join("")}l["-".charCodeAt(0)]=62,l["_".charCodeAt(0)]=63},{}],7:[function(e,t,n){},{}],8:[function(e,t,n){"use strict";var r=e(6),a=e(12);n.Buffer=d,n.SlowBuffer=function(e){+e!=e&&(e=0);return d.alloc(+e)},n.INSPECT_MAX_BYTES=50;var i=2147483647;function o(e){if(i>>1;case"base64":return L(e).length;default:if(i)return r?-1:P(e).length;t=(""+t).toLowerCase(),i=!0}}function p(e,t,n){var r=e[t];e[t]=e[n],e[n]=r}function g(e,t,n,r,i){if(0===e.length)return-1;if("string"==typeof n?(r=n,n=0):2147483647=e.length){if(i)return-1;n=e.length-1}else if(n<0){if(!i)return-1;n=0}if("string"==typeof t&&(t=d.from(t,r)),d.isBuffer(t))return 0===t.length?-1:_(e,t,n,r,i);if("number"==typeof t)return t&=255,"function"==typeof Uint8Array.prototype.indexOf?i?Uint8Array.prototype.indexOf.call(e,t,n):Uint8Array.prototype.lastIndexOf.call(e,t,n):_(e,[t],n,r,i);throw new TypeError("val must be string, number or Buffer")}function _(e,t,n,r,i){var a,o=1,s=e.length,u=t.length;if(void 0!==r&&("ucs2"===(r=String(r).toLowerCase())||"ucs-2"===r||"utf16le"===r||"utf-16le"===r)){if(e.length<2||t.length<2)return-1;s/=o=2,u/=2,n/=2}function l(e,t){return 1===o?e[t]:e.readUInt16BE(t*o)}if(i){var f=-1;for(a=n;a>>10&1023|55296),f=56320|1023&f),r.push(f),i+=d}return function(e){var t=e.length;if(t<=T)return String.fromCharCode.apply(String,e);var n="",r=0;for(;rthis.length)return"";if((void 0===n||n>this.length)&&(n=this.length),n<=0)return"";if((n>>>=0)<=(t>>>=0))return"";for(e=e||"utf8";;)switch(e){case"hex":return I(this,t,n);case"utf8":case"utf-8":return y(this,t,n);case"ascii":return S(this,t,n);case"latin1":case"binary":return A(this,t,n);case"base64":return v(this,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return b(this,t,n);default:if(r)throw new TypeError("Unknown encoding: "+e);e=(e+"").toLowerCase(),r=!0}}.apply(this,arguments)},d.prototype.equals=function(e){if(!d.isBuffer(e))throw new TypeError("Argument must be a Buffer");return this===e||0===d.compare(this,e)},d.prototype.inspect=function(){var e="",t=n.INSPECT_MAX_BYTES;return e=this.toString("hex",0,t).replace(/(.{2})/g,"$1 ").trim(),this.length>t&&(e+=" ... "),""},d.prototype.compare=function(e,t,n,r,i){if(F(e,Uint8Array)&&(e=d.from(e,e.offset,e.byteLength)),!d.isBuffer(e))throw new TypeError('The "target" argument must be one of type Buffer or Uint8Array. Received type '+typeof e);if(void 0===t&&(t=0),void 0===n&&(n=e?e.length:0),void 0===r&&(r=0),void 0===i&&(i=this.length),t<0||n>e.length||r<0||i>this.length)throw new RangeError("out of range index");if(i<=r&&n<=t)return 0;if(i<=r)return-1;if(n<=t)return 1;if(this===e)return 0;for(var a=(i>>>=0)-(r>>>=0),o=(n>>>=0)-(t>>>=0),s=Math.min(a,o),u=this.slice(r,i),l=e.slice(t,n),f=0;f>>=0,isFinite(n)?(n>>>=0,void 0===r&&(r="utf8")):(r=n,n=void 0)}var i=this.length-t;if((void 0===n||ithis.length)throw new RangeError("Attempt to write outside buffer bounds");r=r||"utf8";for(var a,o,s,u,l,f,d,c,h,p=!1;;)switch(r){case"hex":return m(this,e,t,n);case"utf8":case"utf-8":return c=t,h=n,x(P(e,(d=this).length-c),d,c,h);case"ascii":return E(this,e,t,n);case"latin1":case"binary":return E(this,e,t,n);case"base64":return u=this,l=t,f=n,x(L(e),u,l,f);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return o=t,s=n,x(function(e,t){for(var n,r,i,a=[],o=0;o>8,i=n%256,a.push(i),a.push(r);return a}(e,(a=this).length-o),a,o,s);default:if(p)throw new TypeError("Unknown encoding: "+r);r=(""+r).toLowerCase(),p=!0}},d.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};var T=4096;function S(e,t,n){var r="";n=Math.min(e.length,n);for(var i=t;ie.length)throw new RangeError("Index out of range")}function M(e,t,n,r){if(n+r>e.length)throw new RangeError("Index out of range");if(n<0)throw new RangeError("Index out of range")}function C(e,t,n,r,i){return t=+t,n>>>=0,i||M(e,0,n,4),a.write(e,t,n,r,23,4),n+4}function w(e,t,n,r,i){return t=+t,n>>>=0,i||M(e,0,n,8),a.write(e,t,n,r,52,8),n+8}d.prototype.slice=function(e,t){var n=this.length;(e=~~e)<0?(e+=n)<0&&(e=0):n>>=0,t>>>=0,n||R(e,t,this.length);for(var r=this[e],i=1,a=0;++a>>=0,t>>>=0,n||R(e,t,this.length);for(var r=this[e+--t],i=1;0>>=0,t||R(e,1,this.length),this[e]},d.prototype.readUInt16LE=function(e,t){return e>>>=0,t||R(e,2,this.length),this[e]|this[e+1]<<8},d.prototype.readUInt16BE=function(e,t){return e>>>=0,t||R(e,2,this.length),this[e]<<8|this[e+1]},d.prototype.readUInt32LE=function(e,t){return e>>>=0,t||R(e,4,this.length),(this[e]|this[e+1]<<8|this[e+2]<<16)+16777216*this[e+3]},d.prototype.readUInt32BE=function(e,t){return e>>>=0,t||R(e,4,this.length),16777216*this[e]+(this[e+1]<<16|this[e+2]<<8|this[e+3])},d.prototype.readIntLE=function(e,t,n){e>>>=0,t>>>=0,n||R(e,t,this.length);for(var r=this[e],i=1,a=0;++a>>=0,t>>>=0,n||R(e,t,this.length);for(var r=t,i=1,a=this[e+--r];0>>=0,t||R(e,1,this.length),128&this[e]?-1*(255-this[e]+1):this[e]},d.prototype.readInt16LE=function(e,t){e>>>=0,t||R(e,2,this.length);var n=this[e]|this[e+1]<<8;return 32768&n?4294901760|n:n},d.prototype.readInt16BE=function(e,t){e>>>=0,t||R(e,2,this.length);var n=this[e+1]|this[e]<<8;return 32768&n?4294901760|n:n},d.prototype.readInt32LE=function(e,t){return e>>>=0,t||R(e,4,this.length),this[e]|this[e+1]<<8|this[e+2]<<16|this[e+3]<<24},d.prototype.readInt32BE=function(e,t){return e>>>=0,t||R(e,4,this.length),this[e]<<24|this[e+1]<<16|this[e+2]<<8|this[e+3]},d.prototype.readFloatLE=function(e,t){return e>>>=0,t||R(e,4,this.length),a.read(this,e,!0,23,4)},d.prototype.readFloatBE=function(e,t){return e>>>=0,t||R(e,4,this.length),a.read(this,e,!1,23,4)},d.prototype.readDoubleLE=function(e,t){return e>>>=0,t||R(e,8,this.length),a.read(this,e,!0,52,8)},d.prototype.readDoubleBE=function(e,t){return e>>>=0,t||R(e,8,this.length),a.read(this,e,!1,52,8)},d.prototype.writeUIntLE=function(e,t,n,r){e=+e,t>>>=0,n>>>=0,r||D(this,e,t,n,Math.pow(2,8*n)-1,0);var i=1,a=0;for(this[t]=255&e;++a>>=0,n>>>=0,r||D(this,e,t,n,Math.pow(2,8*n)-1,0);var i=n-1,a=1;for(this[t+i]=255&e;0<=--i&&(a*=256);)this[t+i]=e/a&255;return t+n},d.prototype.writeUInt8=function(e,t,n){return e=+e,t>>>=0,n||D(this,e,t,1,255,0),this[t]=255&e,t+1},d.prototype.writeUInt16LE=function(e,t,n){return e=+e,t>>>=0,n||D(this,e,t,2,65535,0),this[t]=255&e,this[t+1]=e>>>8,t+2},d.prototype.writeUInt16BE=function(e,t,n){return e=+e,t>>>=0,n||D(this,e,t,2,65535,0),this[t]=e>>>8,this[t+1]=255&e,t+2},d.prototype.writeUInt32LE=function(e,t,n){return e=+e,t>>>=0,n||D(this,e,t,4,4294967295,0),this[t+3]=e>>>24,this[t+2]=e>>>16,this[t+1]=e>>>8,this[t]=255&e,t+4},d.prototype.writeUInt32BE=function(e,t,n){return e=+e,t>>>=0,n||D(this,e,t,4,4294967295,0),this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e,t+4},d.prototype.writeIntLE=function(e,t,n,r){if(e=+e,t>>>=0,!r){var i=Math.pow(2,8*n-1);D(this,e,t,n,i-1,-i)}var a=0,o=1,s=0;for(this[t]=255&e;++a>0)-s&255;return t+n},d.prototype.writeIntBE=function(e,t,n,r){if(e=+e,t>>>=0,!r){var i=Math.pow(2,8*n-1);D(this,e,t,n,i-1,-i)}var a=n-1,o=1,s=0;for(this[t+a]=255&e;0<=--a&&(o*=256);)e<0&&0===s&&0!==this[t+a+1]&&(s=1),this[t+a]=(e/o>>0)-s&255;return t+n},d.prototype.writeInt8=function(e,t,n){return e=+e,t>>>=0,n||D(this,e,t,1,127,-128),e<0&&(e=255+e+1),this[t]=255&e,t+1},d.prototype.writeInt16LE=function(e,t,n){return e=+e,t>>>=0,n||D(this,e,t,2,32767,-32768),this[t]=255&e,this[t+1]=e>>>8,t+2},d.prototype.writeInt16BE=function(e,t,n){return e=+e,t>>>=0,n||D(this,e,t,2,32767,-32768),this[t]=e>>>8,this[t+1]=255&e,t+2},d.prototype.writeInt32LE=function(e,t,n){return e=+e,t>>>=0,n||D(this,e,t,4,2147483647,-2147483648),this[t]=255&e,this[t+1]=e>>>8,this[t+2]=e>>>16,this[t+3]=e>>>24,t+4},d.prototype.writeInt32BE=function(e,t,n){return e=+e,t>>>=0,n||D(this,e,t,4,2147483647,-2147483648),e<0&&(e=4294967295+e+1),this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e,t+4},d.prototype.writeFloatLE=function(e,t,n){return C(this,e,t,!0,n)},d.prototype.writeFloatBE=function(e,t,n){return C(this,e,t,!1,n)},d.prototype.writeDoubleLE=function(e,t,n){return w(this,e,t,!0,n)},d.prototype.writeDoubleBE=function(e,t,n){return w(this,e,t,!1,n)},d.prototype.copy=function(e,t,n,r){if(!d.isBuffer(e))throw new TypeError("argument should be a Buffer");if(n=n||0,r||0===r||(r=this.length),t>=e.length&&(t=e.length),t=t||0,0=this.length)throw new RangeError("Index out of range");if(r<0)throw new RangeError("sourceEnd out of bounds");r>this.length&&(r=this.length),e.length-t>>=0,n=void 0===n?this.length:n>>>0,"number"==typeof(e=e||0))for(a=t;a>6|192,63&n|128)}else if(n<65536){if((t-=3)<0)break;a.push(n>>12|224,n>>6&63|128,63&n|128)}else{if(!(n<1114112))throw new Error("Invalid code point");if((t-=4)<0)break;a.push(n>>18|240,n>>12&63|128,n>>6&63|128,63&n|128)}}return a}function L(e){return r.toByteArray(function(e){if((e=(e=e.split("=")[0]).trim().replace(O,"")).length<2)return"";for(;e.length%4!=0;)e+="=";return e}(e))}function x(e,t,n,r){for(var i=0;i=t.length||i>=e.length);++i)t[i+n]=e[i];return i}function F(e,t){return e instanceof t||null!=e&&null!=e.constructor&&null!=e.constructor.name&&e.constructor.name===t.name}function U(e){return e!=e}},{12:12,6:6}],9:[function(e,t,n){var i={parseBuffer:function(e){return new a(e).parse()},addBoxProcessor:function(e,t){"string"==typeof e&&"function"==typeof t&&(o.prototype._boxProcessors[e]=t)},createFile:function(){return new a},createBox:function(e,t,n){var r=o.create(e);return t&&t.append(r,n),r},createFullBox:function(e,t,n){var r=i.createBox(e,t,n);return r.version=0,r.flags=0,r},Utils:{}};i.Utils.dataViewToString=function(e,t){var n=t||"utf-8";if("undefined"!=typeof TextDecoder)return new TextDecoder(n).decode(e);var r=[],i=0;if("utf-8"===n)for(;i>6):(r<65536?t.push(224|r>>12):(t.push(240|r>>18),t.push(128|63&r>>12)),t.push(128|63&r>>6)),t.push(128|63&r))}return t},i.Utils.appendBox=function(e,t,n){if(t._offset=e._cursor.offset,t._root=e._root?e._root:e,t._raw=e._raw,t._parent=e,-1!==n)if(null!=n){var r,i=-1;if("number"==typeof n)i=n;else{if("string"==typeof n)r=n;else{if("object"!=typeof n||!n.type)return void e.boxes.push(t);r=n.type}for(var a=0;a>3,t},o.prototype._readUint=function(e){var t,n,r=null,i=this._cursor.offset-this._raw.byteOffset;switch(e){case 8:r=this._raw.getUint8(i);break;case 16:r=this._raw.getUint16(i);break;case 24:r=((t=this._raw.getUint16(i))<<8)+(n=this._raw.getUint8(2+i));break;case 32:r=this._raw.getUint32(i);break;case 64:t=this._raw.getUint32(i),n=this._raw.getUint32(4+i),r=t*Math.pow(2,32)+n}return this._cursor.offset+=e>>3,r},o.prototype._readString=function(e){for(var t="",n=0;nthis._raw.buffer.byteLength)this._root._incomplete=!0;else{switch(this._procField("size","uint",32),this._procField("type","string",4),1===this.size&&this._procField("largesize","uint",64),"uuid"===this.type&&this._procFieldArray("usertype",16,"uint",8),this.size){case 0:this._raw=new DataView(this._raw.buffer,this._offset,this._raw.byteLength-this._cursor.offset+8);break;case 1:this._offset+this.size>this._raw.buffer.byteLength?(this._incomplete=!0,this._root._incomplete=!0):this._raw=new DataView(this._raw.buffer,this._offset,this.largesize);break;default:this._offset+this.size>this._raw.buffer.byteLength?(this._incomplete=!0,this._root._incomplete=!0):this._raw=new DataView(this._raw.buffer,this._offset,this.size)}this._incomplete||(this._boxProcessors[this.type]&&this._boxProcessors[this.type].call(this),-1!==this._boxContainers.indexOf(this.type)?this._parseContainerBox():this._data=this._readData())}},o.prototype._parseFullBox=function(){this.version=this._readUint(8),this.flags=this._readUint(24)},o.prototype._parseContainerBox=function(){for(this.boxes=[];this._cursor.offset-this._raw.byteOffset>3}else this.size+=e>>3},o.prototype._writeUint=function(e,t){if(this._rawo){var n,r,i=this._cursor.offset-this._rawo.byteOffset;switch(e){case 8:this._rawo.setUint8(i,t);break;case 16:this._rawo.setUint16(i,t);break;case 24:n=(16776960&t)>>8,r=255&t,this._rawo.setUint16(i,n),this._rawo.setUint8(2+i,r);break;case 32:this._rawo.setUint32(i,t);break;case 64:r=t-(n=Math.floor(t/Math.pow(2,32)))*Math.pow(2,32),this._rawo.setUint32(i,n),this._rawo.setUint32(4+i,r)}this._cursor.offset+=e>>3}else this.size+=e>>3},o.prototype._writeString=function(e,t){for(var n=0;n>10&31),96+(this.language>>5&31),96+(31&this.language))),this._procField("pre_defined","uint",16)},o.prototype._boxProcessors.mehd=function(){this._procFullBox(),this._procField("fragment_duration","uint",1==this.version?64:32)},o.prototype._boxProcessors.mfhd=function(){this._procFullBox(),this._procField("sequence_number","uint",32)},o.prototype._boxProcessors.mfro=function(){this._procFullBox(),this._procField("mfra_size","uint",32)},o.prototype._boxProcessors.mp4a=o.prototype._boxProcessors.enca=function(){this._procFieldArray("reserved1",6,"uint",8),this._procField("data_reference_index","uint",16),this._procFieldArray("reserved2",2,"uint",32),this._procField("channelcount","uint",16),this._procField("samplesize","uint",16),this._procField("pre_defined","uint",16),this._procField("reserved3","uint",16),this._procField("samplerate","template",32),this._procField("esds","data",-1)},o.prototype._boxProcessors.mvhd=function(){this._procFullBox(),this._procField("creation_time","uint",1==this.version?64:32),this._procField("modification_time","uint",1==this.version?64:32),this._procField("timescale","uint",32),this._procField("duration","uint",1==this.version?64:32),this._procField("rate","template",32),this._procField("volume","template",16),this._procField("reserved1","uint",16),this._procFieldArray("reserved2",2,"uint",32),this._procFieldArray("matrix",9,"template",32),this._procFieldArray("pre_defined",6,"uint",32),this._procField("next_track_ID","uint",32)},o.prototype._boxProcessors.payl=function(){this._procField("cue_text","utf8")},o.prototype._boxProcessors.pssh=function(){this._procFullBox(),this._procFieldArray("SystemID",16,"uint",8),this._procField("DataSize","uint",32),this._procFieldArray("Data",this.DataSize,"uint",8)},o.prototype._boxProcessors.schm=function(){this._procFullBox(),this._procField("scheme_type","uint",32),this._procField("scheme_version","uint",32),1&this.flags&&this._procField("scheme_uri","string",-1)},o.prototype._boxProcessors.sdtp=function(){this._procFullBox();var e=-1;this._parsing&&(e=this._raw.byteLength-(this._cursor.offset-this._raw.byteOffset)),this._procFieldArray("sample_dependency_table",e,"uint",8)},o.prototype._boxProcessors.sidx=function(){this._procFullBox(),this._procField("reference_ID","uint",32),this._procField("timescale","uint",32),this._procField("earliest_presentation_time","uint",1==this.version?64:32),this._procField("first_offset","uint",1==this.version?64:32),this._procField("reserved","uint",16),this._procField("reference_count","uint",16),this._procEntries("references",this.reference_count,function(e){this._parsing||(e.reference=(1&e.reference_type)<<31,e.reference|=2147483647&e.referenced_size,e.sap=(1&e.starts_with_SAP)<<31,e.sap|=(3&e.SAP_type)<<28,e.sap|=268435455&e.SAP_delta_time),this._procEntryField(e,"reference","uint",32),this._procEntryField(e,"subsegment_duration","uint",32),this._procEntryField(e,"sap","uint",32),this._parsing&&(e.reference_type=e.reference>>31&1,e.referenced_size=2147483647&e.reference,e.starts_with_SAP=e.sap>>31&1,e.SAP_type=e.sap>>28&7,e.SAP_delta_time=268435455&e.sap)})},o.prototype._boxProcessors.smhd=function(){this._procFullBox(),this._procField("balance","uint",16),this._procField("reserved","uint",16)},o.prototype._boxProcessors.ssix=function(){this._procFullBox(),this._procField("subsegment_count","uint",32),this._procEntries("subsegments",this.subsegment_count,function(e){this._procEntryField(e,"ranges_count","uint",32),this._procSubEntries(e,"ranges",e.ranges_count,function(e){this._procEntryField(e,"level","uint",8),this._procEntryField(e,"range_size","uint",24)})})},o.prototype._boxProcessors.stsd=function(){this._procFullBox(),this._procField("entry_count","uint",32),this._procSubBoxes("entries",this.entry_count)},o.prototype._boxProcessors.subs=function(){this._procFullBox(),this._procField("entry_count","uint",32),this._procEntries("entries",this.entry_count,function(e){this._procEntryField(e,"sample_delta","uint",32),this._procEntryField(e,"subsample_count","uint",16),this._procSubEntries(e,"subsamples",e.subsample_count,function(e){this._procEntryField(e,"subsample_size","uint",1===this.version?32:16),this._procEntryField(e,"subsample_priority","uint",8),this._procEntryField(e,"discardable","uint",8),this._procEntryField(e,"codec_specific_parameters","uint",32)})})},o.prototype._boxProcessors.tenc=function(){this._procFullBox(),this._procField("default_IsEncrypted","uint",24),this._procField("default_IV_size","uint",8),this._procFieldArray("default_KID",16,"uint",8)},o.prototype._boxProcessors.tfdt=function(){this._procFullBox(),this._procField("baseMediaDecodeTime","uint",1==this.version?64:32)},o.prototype._boxProcessors.tfhd=function(){this._procFullBox(),this._procField("track_ID","uint",32),1&this.flags&&this._procField("base_data_offset","uint",64),2&this.flags&&this._procField("sample_description_offset","uint",32),8&this.flags&&this._procField("default_sample_duration","uint",32),16&this.flags&&this._procField("default_sample_size","uint",32),32&this.flags&&this._procField("default_sample_flags","uint",32)},o.prototype._boxProcessors.tfra=function(){this._procFullBox(),this._procField("track_ID","uint",32),this._parsing||(this.reserved=0,this.reserved|=(48&this.length_size_of_traf_num)<<4,this.reserved|=(12&this.length_size_of_trun_num)<<2,this.reserved|=3&this.length_size_of_sample_num),this._procField("reserved","uint",32),this._parsing&&(this.length_size_of_traf_num=(48&this.reserved)>>4,this.length_size_of_trun_num=(12&this.reserved)>>2,this.length_size_of_sample_num=3&this.reserved),this._procField("number_of_entry","uint",32),this._procEntries("entries",this.number_of_entry,function(e){this._procEntryField(e,"time","uint",1===this.version?64:32),this._procEntryField(e,"moof_offset","uint",1===this.version?64:32),this._procEntryField(e,"traf_number","uint",8*(this.length_size_of_traf_num+1)),this._procEntryField(e,"trun_number","uint",8*(this.length_size_of_trun_num+1)),this._procEntryField(e,"sample_number","uint",8*(this.length_size_of_sample_num+1))})},o.prototype._boxProcessors.tkhd=function(){this._procFullBox(),this._procField("creation_time","uint",1==this.version?64:32),this._procField("modification_time","uint",1==this.version?64:32),this._procField("track_ID","uint",32),this._procField("reserved1","uint",32),this._procField("duration","uint",1==this.version?64:32),this._procFieldArray("reserved2",2,"uint",32),this._procField("layer","uint",16),this._procField("alternate_group","uint",16),this._procField("volume","template",16),this._procField("reserved3","uint",16),this._procFieldArray("matrix",9,"template",32),this._procField("width","template",32),this._procField("height","template",32)},o.prototype._boxProcessors.trex=function(){this._procFullBox(),this._procField("track_ID","uint",32),this._procField("default_sample_description_index","uint",32),this._procField("default_sample_duration","uint",32),this._procField("default_sample_size","uint",32),this._procField("default_sample_flags","uint",32)},o.prototype._boxProcessors.trun=function(){this._procFullBox(),this._procField("sample_count","uint",32),1&this.flags&&this._procField("data_offset","int",32),4&this.flags&&this._procField("first_sample_flags","uint",32),this._procEntries("samples",this.sample_count,function(e){256&this.flags&&this._procEntryField(e,"sample_duration","uint",32),512&this.flags&&this._procEntryField(e,"sample_size","uint",32),1024&this.flags&&this._procEntryField(e,"sample_flags","uint",32),2048&this.flags&&this._procEntryField(e,"sample_composition_time_offset",1===this.version?"int":"uint",32)})},o.prototype._boxProcessors["url "]=o.prototype._boxProcessors["urn "]=function(){this._procFullBox(),"urn "===this.type&&this._procField("name","string",-1),this._procField("location","string",-1)},o.prototype._boxProcessors.vlab=function(){this._procField("source_label","utf8")},o.prototype._boxProcessors.vmhd=function(){this._procFullBox(),this._procField("graphicsmode","uint",16),this._procFieldArray("opcolor",3,"uint",16)},o.prototype._boxProcessors.vttC=function(){this._procField("config","utf8")},o.prototype._boxProcessors.vtte=function(){}},{}],10:[function(e,t,n){var u=Object.create||function(e){function t(){}return t.prototype=e,new t},o=Object.keys||function(e){var t=[];for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&t.push(n);return n},a=Function.prototype.bind||function(e){var t=this;return function(){return t.apply(e,arguments)}};function r(){this._events&&Object.prototype.hasOwnProperty.call(this,"_events")||(this._events=u(null),this._eventsCount=0),this._maxListeners=this._maxListeners||void 0}((t.exports=r).EventEmitter=r).prototype._events=void 0,r.prototype._maxListeners=void 0;var i,s=10;try{var l={};Object.defineProperty&&Object.defineProperty(l,"x",{value:0}),i=0===l.x}catch(e){i=!1}function f(e){return void 0===e._maxListeners?r.defaultMaxListeners:e._maxListeners}function d(e,t,n,r){var i,a,o;if("function"!=typeof n)throw new TypeError('"listener" argument must be a function');if((a=e._events)?(a.newListener&&(e.emit("newListener",t,n.listener?n.listener:n),a=e._events),o=a[t]):(a=e._events=u(null),e._eventsCount=0),o){if("function"==typeof o?o=a[t]=r?[n,o]:[o,n]:r?o.unshift(n):o.push(n),!o.warned&&(i=f(e))&&0i){o.warned=!0;var s=new Error("Possible EventEmitter memory leak detected. "+o.length+' "'+String(t)+'" listeners added. Use emitter.setMaxListeners() to increase limit.');s.name="MaxListenersExceededWarning",s.emitter=e,s.type=t,s.count=o.length,"object"==typeof console&&console.warn&&console.warn("%s: %s",s.name,s.message)}}else o=a[t]=n,++e._eventsCount;return e}function c(){if(!this.fired)switch(this.target.removeListener(this.type,this.wrapFn),this.fired=!0,arguments.length){case 0:return this.listener.call(this.target);case 1:return this.listener.call(this.target,arguments[0]);case 2:return this.listener.call(this.target,arguments[0],arguments[1]);case 3:return this.listener.call(this.target,arguments[0],arguments[1],arguments[2]);default:for(var e=new Array(arguments.length),t=0;t>1,f=-7,d=n?i-1:0,c=n?-1:1,h=e[t+d];for(d+=c,a=h&(1<<-f)-1,h>>=-f,f+=s;0>=-f,f+=r;0>1,c=23===i?Math.pow(2,-24)-Math.pow(2,-77):0,h=r?0:a-1,p=r?1:-1,g=t<0||0===t&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(s=isNaN(t)?1:0,o=f):(o=Math.floor(Math.log(t)/Math.LN2),t*(u=Math.pow(2,-o))<1&&(o--,u*=2),2<=(t+=1<=o+d?c/u:c*Math.pow(2,1-d))*u&&(o++,u/=2),f<=o+d?(s=0,o=f):1<=o+d?(s=(t*u-1)*Math.pow(2,i),o+=d):(s=t*Math.pow(2,d-1)*Math.pow(2,i),o=0));8<=i;e[n+h]=255&s,h+=p,s/=256,i-=8);for(o=o< elements at ("+this.line+","+this.column+")"),(v=new T).initFromNode(e,h),g.unshift(v);else if("head"===e.local)g[0]instanceof T||F(h,"Parent of element is not at ("+this.line+","+this.column+")"),null!==v.head&&F("Second element at ("+this.line+","+this.column+")"),v.head=new S,g.unshift(v.head);else if("styling"===e.local)g[0]instanceof S||F(h,"Parent of element is not at ("+this.line+","+this.column+")"),null!==v.head.styling&&F("Second element at ("+this.line+","+this.column+")"),v.head.styling=new A,g.unshift(v.head.styling);else if("style"===e.local){var r;g[0]instanceof A?((r=new I).initFromNode(e,h),r.id?v.head.styling.styles[r.id]=r:x(h,"