diff --git a/config/defaults.js b/config/defaults.js index f053324150..89c211132e 100644 --- a/config/defaults.js +++ b/config/defaults.js @@ -64,6 +64,12 @@ const defaultConfig = { }, savedVolume: undefined //plugin save volume between session here }, + chromecast: { + enabled: false, + syncVolume: true, + syncStartTime: true, + syncSeek: true + }, sponsorblock: { enabled: false, apiURL: "https://sponsor.ajay.app", diff --git a/package.json b/package.json index 12602a1850..64a04b2574 100644 --- a/package.json +++ b/package.json @@ -70,6 +70,7 @@ "async-mutex": "^0.3.1", "browser-id3-writer": "^4.4.0", "chokidar": "^3.5.1", + "chromecast-api": "^0.3.4", "custom-electron-titlebar": "^3.2.6", "discord-rpc": "^3.2.0", "electron-debug": "^3.2.0", @@ -97,7 +98,8 @@ "xo": "^0.38.2" }, "resolutions": { - "yargs-parser": "18.1.3" + "yargs-parser": "18.1.3", + "dns-packet": "5.2.4" }, "xo": { "envs": [ diff --git a/plugins/chromecast/back.js b/plugins/chromecast/back.js new file mode 100644 index 0000000000..3e8cc9ac2e --- /dev/null +++ b/plugins/chromecast/back.js @@ -0,0 +1,105 @@ +const registerCallback = require("../../providers/song-info"); +const getSongControls = require('../../providers/song-controls'); + +const { ipcMain } = require('electron') +const ChromecastAPI = require('chromecast-api'); +const { setOptions } = require("../../config/plugins"); + +let client; +let deviceList = []; + +let controls; + +let options; + +module.exports = (win, initialOptions) => { + const { play, pause } = getSongControls(win); + controls = { play, pause }; + + options = initialOptions; + + client = new ChromecastAPI(); + + client.on('device', (device) => { + if (!deviceList.includes(device.name)) { + registerDevice(device); + } + }); + ipcMain.on('volume-change', (_, v) => setVolume(v)); + ipcMain.on('seeked-to', (_, s) => seekTo(s + 1.5)); +}; + +function setVolume(volume) { + if (options.syncVolume) { + for (const device of client.devices) { + device.setVolume(volume); + } + } +} + +function seekTo(seconds) { + if (options.syncSeek) { + for (const device of client.devices) { + device.seekTo(seconds); + } + } +} + +function registerDevice(device) { + deviceList.push(device.name); + let currentStatus; + device.on('status', async (status) => { + currentStatus = status.playerState; + if (options.syncStartTime) { + currentStatus === "PLAYING" ? controls.play() : controls.pause(); + } + }) + + let currentUrl; + let isPaused; + registerCallback(songInfo => { + if (!songInfo?.title) { + return; + } + if (currentUrl !== songInfo.url) { //new song + currentUrl = songInfo.url; + if (options.syncStartTime) { + isPaused = true; + controls.pause(); + } else { + isPaused = songInfo.isPaused; + } + device.play(transformURL(songInfo.url)); + + } else if (isPaused !== songInfo.isPaused) { //paused status changed + isPaused = songInfo.isPaused; + if (isPaused && currentStatus === "PLAYING") { + device.pause(); + } else { + device.resume(); + } + } + }); +} + +// will not be needed after https://github.com/alxhotel/chromecast-api/pull/69 (chromecastAPI v0.3.5) +function transformURL(url) { + const videoId = url.match(/(?:http(?:s?):\/\/)?(?:www\.)?(?:music\.)?youtu(?:be\.com\/watch\?v=|\.be\/)([\w\-\_]*)/); + // videoId[1] should always be valid since regex should always be valid - rickroll video should never happen :) + return "https://youtube.com/watch?v=" + (videoId.length > 1 ? videoId[1] : "dQw4w9WgXcQ"); +} + +module.exports.setOption = (value, ...keys) => { + for (const key of keys) { + options[key] = value; + } + setOptions("chromecast", options); +}; + +module.exports.menuCheck = (options_) => { + if (!options) options = options_; +} + +module.exports.refreshChromecast = () => { + if (client) client.update(); +} diff --git a/plugins/chromecast/front.js b/plugins/chromecast/front.js new file mode 100644 index 0000000000..e10aef7c01 --- /dev/null +++ b/plugins/chromecast/front.js @@ -0,0 +1,20 @@ +const { ipcRenderer } = require('electron'); + +const sendVolume = (volume) => ipcRenderer.send('volume-change', volume); +const sendTime = (seconds) => ipcRenderer.send('seeked-to', seconds); + +module.exports = function checkVideoLoaded() { + const video = document.querySelector("video"); + video ? setup(video) : setTimeout(checkVideoLoaded, 500); +} + +function setup(video) { + + sendVolume(video.volume); + + video.addEventListener('volumechange', e => + sendVolume(e.target.muted ? 0 : e.target.volume)); + + video.addEventListener('seeking', e => + sendTime(e.target.currentTime)); +} diff --git a/plugins/chromecast/menu.js b/plugins/chromecast/menu.js new file mode 100644 index 0000000000..e15d90bff4 --- /dev/null +++ b/plugins/chromecast/menu.js @@ -0,0 +1,30 @@ +const { menuCheck, setOption, refreshChromecast } = require("./back"); + +module.exports = (_win, options) => { + menuCheck(options); + return [ + { + label: "Sync Volume", + type: "checkbox", + checked: !!options.syncVolume, + click: (item) => setOption(item.checked, "syncVolume") + }, + { + label: "Sync Start Time", + type: "checkbox", + checked: !!options.syncStartTime, + click: (item) => setOption(item.checked, "syncStartTime") + }, + { + label: "Sync Seek", + type: "checkbox", + checked: !!options.syncSeek, + click: (item) => setOption(item.checked, "syncSeek") + }, + { type: "separator" }, + { + label: "Refresh Device List", + click: refreshChromecast + } + ] +}; diff --git a/plugins/taskbar-mediacontrol/back.js b/plugins/taskbar-mediacontrol/back.js index 26a117320b..fabdf0c48b 100644 --- a/plugins/taskbar-mediacontrol/back.js +++ b/plugins/taskbar-mediacontrol/back.js @@ -33,16 +33,16 @@ function setThumbar(win, songInfo) { { tooltip: 'Previous', icon: get('backward.png'), - click() { controls.previous(win.webContents); } + click() { controls.previous(); } }, { tooltip: 'Play/Pause', // Update icon based on play state icon: songInfo.isPaused ? get('play.png') : get('pause.png'), - click() { controls.playPause(win.webContents); } + click() { controls.playPause(); } }, { tooltip: 'Next', icon: get('forward.png'), - click() { controls.next(win.webContents); } + click() { controls.next(); } } ]); } diff --git a/providers/song-controls-front.js b/providers/song-controls-front.js index 1860e7614e..01f6563846 100644 --- a/providers/song-controls-front.js +++ b/providers/song-controls-front.js @@ -1,18 +1,37 @@ const { ipcRenderer } = require("electron"); -let videoStream = document.querySelector(".video-stream"); -module.exports = () => { - ipcRenderer.on("playPause", () => { - if (!videoStream) { - videoStream = document.querySelector(".video-stream"); - } +let video = document.querySelector("video"); - if (videoStream.paused) { - videoStream.play(); - } else { - videoStream.yns_pause ? - videoStream.yns_pause() : - videoStream.pause(); - } - }); +module.exports = () => { + ipcRenderer.on("playPause", (_e, toPlay) => playPause(toPlay)); }; +module.exports.playPause = playPause; + +function playPause(toPlay = undefined) { + if (!checkVideo()) return; + + switch (toPlay) { + case true: + video.play(); + break; + case false: + pause(); + break; + default: //usually undefined + video.paused ? video.play() : pause(); + } + + function pause() { + video.yns_pause ? + video.yns_pause() : + video.pause(); + } +} + +function checkVideo() { + if (!video) { + video = document.querySelector("video"); + } + + return !!video; +} diff --git a/providers/song-controls.js b/providers/song-controls.js index 5d3ad953d2..0f955c05c0 100644 --- a/providers/song-controls.js +++ b/providers/song-controls.js @@ -13,7 +13,8 @@ module.exports = (win) => { previous: () => pressKey(win, "k"), next: () => pressKey(win, "j"), playPause: () => win.webContents.send("playPause"), - like: () => pressKey(win, "_"), + play: () => win.webContents.send("playPause", true), + pause: () => win.webContents.send("playPause", false), dislike: () => pressKey(win, "+"), go10sBack: () => pressKey(win, "h"), go10sForward: () => pressKey(win, "l"), diff --git a/yarn.lock b/yarn.lock index 26ee2ded0f..786a44e2e3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1077,6 +1077,59 @@ "@nodelib/fs.scandir" "2.1.4" fastq "^1.6.0" +"@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" + integrity sha1-m4sMxmPWaafY9vXQiToU00jzD78= + +"@protobufjs/base64@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/base64/-/base64-1.1.2.tgz#4c85730e59b9a1f1f349047dbf24296034bb2735" + integrity sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg== + +"@protobufjs/codegen@^2.0.4": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@protobufjs/codegen/-/codegen-2.0.4.tgz#7ef37f0d010fb028ad1ad59722e506d9262815cb" + integrity sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg== + +"@protobufjs/eventemitter@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70" + integrity sha1-NVy8mLr61ZePntCV85diHx0Ga3A= + +"@protobufjs/fetch@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45" + integrity sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU= + dependencies: + "@protobufjs/aspromise" "^1.1.1" + "@protobufjs/inquire" "^1.1.0" + +"@protobufjs/float@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1" + integrity sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E= + +"@protobufjs/inquire@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089" + integrity sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik= + +"@protobufjs/path@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d" + integrity sha1-bMKyDFya1q0NzP0hynZz2Nf79o0= + +"@protobufjs/pool@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54" + integrity sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q= + +"@protobufjs/utf8@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" + integrity sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA= + "@remusao/guess-url-type@^1.1.2": version "1.2.1" resolved "https://registry.yarnpkg.com/@remusao/guess-url-type/-/guess-url-type-1.2.1.tgz#b3e7c32abdf98d0fb4f93cc67cad580b5fe4ba57" @@ -1291,6 +1344,11 @@ dependencies: "@types/node" "*" +"@types/long@^4.0.1": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.1.tgz#459c65fa1867dafe6a8f322c4c51695663cc55e9" + integrity sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w== + "@types/minimatch@*": version "3.0.3" resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" @@ -1306,6 +1364,11 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.25.tgz#15967a7b577ff81383f9b888aa6705d43fbbae93" integrity sha512-EPpXLOVqDvisVxtlbvzfyqSsFeQxltFbluZNRndIb8tr9KiBnYNLzrc1N3pyKUCww2RNrfHDViqDWWE1LCJQtQ== +"@types/node@>=13.7.0": + version "15.3.0" + resolved "https://registry.yarnpkg.com/@types/node/-/node-15.3.0.tgz#d6fed7d6bc6854306da3dea1af9f874b00783e26" + integrity sha512-8/bnjSZD86ZfpBsDlCIkNXIvm+h6wi9g7IqL+kmFkQ+Wvu3JrasgLElfiPgoo8V8vVfnEi0QVS12gbl94h9YsQ== + "@types/node@^14.6.2": version "14.14.44" resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.44.tgz#df7503e6002847b834371c004b372529f3f85215" @@ -1878,6 +1941,13 @@ async@0.9.x: resolved "https://registry.yarnpkg.com/async/-/async-0.9.2.tgz#aea74d5e61c1f899613bf64bda66d4c78f2fd17d" integrity sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0= +async@^2.6.0: + version "2.6.3" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" + integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg== + dependencies: + lodash "^4.17.14" + async@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/async/-/async-3.2.0.tgz#b3a2685c5ebb641d3de02d161002c60fc9f85720" @@ -2030,7 +2100,7 @@ bluebird-lst@^1.0.9: dependencies: bluebird "^3.5.5" -bluebird@^3.5.5: +bluebird@^3.5.1, bluebird@^3.5.5: version "3.7.2" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== @@ -2219,6 +2289,11 @@ buffer-from@^1.0.0: resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== +buffer-indexof@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-indexof/-/buffer-indexof-1.1.1.tgz#52fabcc6a606d1a00302802648ef68f639da268c" + integrity sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g== + buffer-xor@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" @@ -2384,6 +2459,22 @@ caseless@~0.12.0: resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= +castv2-client@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/castv2-client/-/castv2-client-1.2.0.tgz#a9193b1a5448b8cb9a0415bd021c8811ed7b0544" + integrity sha1-qRk7GlRIuMuaBBW9AhyIEe17BUQ= + dependencies: + castv2 "~0.1.4" + debug "^2.2.0" + +castv2@~0.1.4: + version "0.1.10" + resolved "https://registry.yarnpkg.com/castv2/-/castv2-0.1.10.tgz#d3df00124f1ba8a97691c69dd44221d3b5f93c56" + integrity sha512-3QWevHrjT22KdF08Y2a217IYCDQDP7vEJaY4n0lPBeC5UBYbMFMadDfVTsaQwq7wqsEgYUHElPGm3EO1ey+TNw== + dependencies: + debug "^4.1.1" + protobufjs "^6.8.8" + chalk@1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" @@ -2454,6 +2545,20 @@ chrome-launcher@^0.13.1: mkdirp "^0.5.3" rimraf "^3.0.2" +chromecast-api@^0.3.4: + version "0.3.4" + resolved "https://registry.yarnpkg.com/chromecast-api/-/chromecast-api-0.3.4.tgz#7c4a30f29dc8a76aa725da893c926dcfb616d647" + integrity sha512-b7+qyms+78cRMUiygPW/x8E5SL3gFRycmZDO5JWKYp0NS3wY4S620j0Xo6oQumQFMKUEvnVlEIPqPcDwzlam3A== + dependencies: + castv2-client "1.2.0" + debug "^4.1.1" + dns-txt "^2.0.2" + mime "^2.3.1" + multicast-dns "^7.2.0" + node-ssdp "^4.0.0" + xml2js "^0.4.23" + youtube-remote "^1.0.0" + chromium-pickle-js@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/chromium-pickle-js/-/chromium-pickle-js-0.2.0.tgz#04a106672c18b085ab774d983dfa3ea138f22205" @@ -2924,6 +3029,13 @@ debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: dependencies: ms "2.0.0" +debug@^3.1.0, debug@^3.2.6: + version "3.2.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== + dependencies: + ms "^2.1.1" + debug@^4.3.2: version "4.3.2" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" @@ -3164,6 +3276,20 @@ dmg-license@^1.0.8: smart-buffer "^4.0.2" verror "^1.10.0" +dns-packet@5.2.4, dns-packet@^4.0.0: + version "5.2.4" + resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-5.2.4.tgz#e004f409eadfa8ec861964dcb9eb395884fcf67d" + integrity sha512-vgu5Bx5IV8mXmh/9cn1lzn+J7okFlXe1vBRp+kCBJXg1nBED6Z/Q4e+QaDxQRSozMr14p/VQmdXwsf/I2wGjUA== + dependencies: + ip "^1.1.5" + +dns-txt@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/dns-txt/-/dns-txt-2.0.2.tgz#b91d806f5d27188e4ab3e7d107d881a1cc4642b6" + integrity sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY= + dependencies: + buffer-indexof "^1.0.0" + doctrine@1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" @@ -3981,7 +4107,7 @@ extend-shallow@^3.0.0, extend-shallow@^3.0.2: assign-symbols "^1.0.0" is-extendable "^1.0.1" -extend@~3.0.2: +extend@^3.0.1, extend@~3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== @@ -4804,7 +4930,7 @@ iconv-corefoundation@^1.1.5: cli-truncate "^1.1.0" node-addon-api "^1.6.3" -iconv-lite@0.4.24: +iconv-lite@0.4.24, iconv-lite@^0.4.4: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== @@ -4927,6 +5053,11 @@ ip-regex@^2.1.0: resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9" integrity sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk= +ip@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" + integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= + irregular-plurals@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/irregular-plurals/-/irregular-plurals-3.2.0.tgz#b19c490a0723798db51b235d7e39add44dab0822" @@ -6197,7 +6328,7 @@ lodash@^4.13.1, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20: resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA== -lodash@^4.17.10, lodash@^4.17.21: +lodash@^4.17.10, lodash@^4.17.14, lodash@^4.17.21, lodash@^4.17.4: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -6219,6 +6350,11 @@ loglevel@^1.6.0: resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.7.1.tgz#005fde2f5e6e47068f935ff28573e125ef72f197" integrity sha512-Hesni4s5UkWkwCGJMQGAh71PaLUmKFM60dHvq0zi/vDhhrzuk+4GgNbTXJ12YYQJn6ZKBDNIjYcuQGKudvqrIw== +long@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" + integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA== + lowercase-keys@^1.0.0, lowercase-keys@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" @@ -6400,7 +6536,7 @@ mime@^1.3.4: resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== -mime@^2.5.0: +mime@^2.3.1, mime@^2.5.0: version "2.5.2" resolved "https://registry.yarnpkg.com/mime/-/mime-2.5.2.tgz#6e3dc6cc2b9510643830e5f19d5cb753da5eeabe" integrity sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg== @@ -6508,6 +6644,19 @@ ms@2.1.2: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== +ms@^2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +multicast-dns@^7.2.0: + version "7.2.2" + resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-7.2.2.tgz#5731da04f47d1e435ac457e5ac7b4b39d866a5a1" + integrity sha512-XqSMeO8EWV/nOXOpPV8ztIpNweVfE1dSpz6SQvDPp71HD74lMXjt4m/mWB1YBMG0kHtOodxRWc5WOb/UNN1A5g== + dependencies: + dns-packet "^4.0.0" + thunky "^1.0.2" + multimap@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/multimap/-/multimap-1.1.0.tgz#5263febc085a1791c33b59bb3afc6a76a2a10ca8" @@ -6535,6 +6684,15 @@ natural-compare@^1.4.0: resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= +needle@^2.5.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/needle/-/needle-2.6.0.tgz#24dbb55f2509e2324b4a99d61f413982013ccdbe" + integrity sha512-KKYdza4heMsEfSWD7VPUIz3zX2XDwOyX2d+geb4vrERZMT5RMU6ujjaD+I5Yr54uZxQ2w6XRTAhHBbSCyovZBg== + dependencies: + debug "^3.2.6" + iconv-lite "^0.4.4" + sax "^1.2.4" + nice-try@^1.0.4: version "1.0.5" resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" @@ -6618,6 +6776,17 @@ node-releases@^1.1.71: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.72.tgz#14802ab6b1039a79a0c7d662b610a5bbd76eacbe" integrity sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw== +node-ssdp@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/node-ssdp/-/node-ssdp-4.0.1.tgz#ea5b2e9a287823b58b3ede348b22a08159cf718f" + integrity sha512-uJXkLZVuyaMg1qNbMbGQ6YzNzyOD+NLxYyxIJocPTKTVECPDokOiCZA686jTLXHMUnV34uY/lcUSJ+/5fhY43A== + dependencies: + async "^2.6.0" + bluebird "^3.5.1" + debug "^3.1.0" + extend "^3.0.1" + ip "^1.1.5" + normalize-package-data@^2.3.2, normalize-package-data@^2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" @@ -7314,6 +7483,25 @@ proto-props@^2.0.0: resolved "https://registry.yarnpkg.com/proto-props/-/proto-props-2.0.0.tgz#8ac6e6dec658545815c623a3bc81580deda9a181" integrity sha512-2yma2tog9VaRZY2mn3Wq51uiSW4NcPYT1cQdBagwyrznrilKSZwIZ0UG3ZPL/mx+axEns0hE35T5ufOYZXEnBQ== +protobufjs@^6.8.8: + version "6.11.2" + resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.11.2.tgz#de39fabd4ed32beaa08e9bb1e30d08544c1edf8b" + integrity sha512-4BQJoPooKJl2G9j3XftkIXjoC9C0Av2NOrWmbLWT1vH32GcSUHjM0Arra6UfTsVyfMAuFzaLucXn1sadxJydAw== + dependencies: + "@protobufjs/aspromise" "^1.1.2" + "@protobufjs/base64" "^1.1.2" + "@protobufjs/codegen" "^2.0.4" + "@protobufjs/eventemitter" "^1.1.0" + "@protobufjs/fetch" "^1.1.0" + "@protobufjs/float" "^1.0.2" + "@protobufjs/inquire" "^1.1.0" + "@protobufjs/path" "^1.1.2" + "@protobufjs/pool" "^1.1.0" + "@protobufjs/utf8" "^1.1.0" + "@types/long" "^4.0.1" + "@types/node" ">=13.7.0" + long "^4.0.0" + proxy-from-env@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" @@ -8488,6 +8676,11 @@ through@2, through@^2.3.8: resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= +thunky@^1.0.2: + version "1.1.0" + resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d" + integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA== + timers-browserify@^2.0.4: version "2.0.12" resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.12.tgz#44a45c11fbf407f34f97bccd1577c652361b00ee" @@ -9143,7 +9336,7 @@ xml-parse-from-string@^1.0.0: resolved "https://registry.yarnpkg.com/xml-parse-from-string/-/xml-parse-from-string-1.0.1.tgz#a9029e929d3dbcded169f3c6e28238d95a5d5a28" integrity sha1-qQKekp09vN7RafPG4oI42VpdWig= -xml2js@^0.4.5: +xml2js@^0.4.23, xml2js@^0.4.5: version "0.4.23" resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.23.tgz#a0c69516752421eb2ac758ee4d4ccf58843eac66" integrity sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug== @@ -9330,6 +9523,14 @@ yocto-queue@^0.1.0: resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== +youtube-remote@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/youtube-remote/-/youtube-remote-1.0.2.tgz#873acdd3b206762da011ebdb6a61284454418bc8" + integrity sha512-IR7OtIuk7NA4wcrRDBbWtLQtM/hcZdtrxgelAwzajvrzzbwGFTf1O+yDzhUWcqOdw2QAp8fKXxS4QQR3e3k24A== + dependencies: + lodash "^4.17.4" + needle "^2.5.0" + ytdl-core@^4.7.0: version "4.8.0" resolved "https://registry.yarnpkg.com/ytdl-core/-/ytdl-core-4.8.0.tgz#d9f037a370a4b984f1f937e7a11b4531e8959443"