diff --git a/README.md b/README.md index 7e05cfe..2eb8f62 100644 --- a/README.md +++ b/README.md @@ -14,8 +14,11 @@ Configure the apiurl variable in static/js/custom.js to point to your yt-dlp-web Install node/npm -`npm install` +`npm install --omit=dev` That's all! Once this code is hosted, add the host url to allowedorigins in conf.json in yt-dlp-web and reload the server + +# License +This code is distributed under [GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html) \ No newline at end of file diff --git a/index.html b/index.html index a8d86d5..111369e 100644 --- a/index.html +++ b/index.html @@ -8,6 +8,10 @@ + + + + @@ -41,6 +45,8 @@
+

See here for a list of sites supported by the yt-dlp backend (note that playlists only work on Youtube at the moment, also ymmv for which services will work): https://github.com/yt-dlp/yt-dlp/blob/master/supportedsites.md/p> +

User Guides:

➕ Show

@@ -254,7 +260,6 @@ - \ No newline at end of file diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index c98fa25..0000000 --- a/package-lock.json +++ /dev/null @@ -1,569 +0,0 @@ -{ - "name": "yt-dlp-web-ui", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "dependencies": { - "@ffmpeg/ffmpeg": "^0.12.5", - "@ffmpeg/util": "^0.12.0", - "pristinejs": "^0.1.1", - "pyodide": "^0.23.4", - "socket.io-client": "^4.7.2", - "turretcss": "^5.2.2", - "video.js": "^8.5.2", - "videojs-youtube": "^3.0.1" - } - }, - "node_modules/@babel/runtime": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.15.tgz", - "integrity": "sha512-T0O+aa+4w0u06iNmapipJXMV4HoUir03hpx3/YqXXhu9xim3w+dVphjFWl1OH8NbZHw5Lbm9k45drDkgq2VNNA==", - "dependencies": { - "regenerator-runtime": "^0.14.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@ffmpeg/ffmpeg": { - "version": "0.12.5", - "resolved": "https://registry.npmjs.org/@ffmpeg/ffmpeg/-/ffmpeg-0.12.5.tgz", - "integrity": "sha512-grDWTaYSm0g/LEtpwkJtw0Kp1Iix/WF3KmtUo0Fm0V5GqKMUVzj1yzyaILg83o96wHSc8Y2d9Q3C37pYAF2wxQ==", - "dependencies": { - "@ffmpeg/types": "^0.12.0" - }, - "engines": { - "node": ">=18.17.0" - } - }, - "node_modules/@ffmpeg/types": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/@ffmpeg/types/-/types-0.12.0.tgz", - "integrity": "sha512-AuR4K+L6v1/9hVOsikU4rGGT5nKulQa8HrtYhpgBEq0HojoWB1c9bq3TTkNBpEvS/gC17WDMVJrqIGgXOj1DXA==", - "engines": { - "node": ">=16.6.0" - } - }, - "node_modules/@ffmpeg/util": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/@ffmpeg/util/-/util-0.12.0.tgz", - "integrity": "sha512-8sHCW8H/ngqVhbRvCCX4e4uDNgZVoz8uNRry1zphIyzdX6flfBa2TmVwJ4g9/Qw//eAubEnuHaSxDGWWxcOTjg==", - "engines": { - "node": ">=18.17.0" - } - }, - "node_modules/@socket.io/component-emitter": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz", - "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==" - }, - "node_modules/@videojs/http-streaming": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/@videojs/http-streaming/-/http-streaming-3.5.3.tgz", - "integrity": "sha512-dty8lsZk9QPc0i4It79tjWsmPiaC3FpgARFM0vJGko4k3yKNZIYkAk8kjiDRfkAQH/HZ3rYi5dDTriFNzwSsIg==", - "dependencies": { - "@babel/runtime": "^7.12.5", - "@videojs/vhs-utils": "4.0.0", - "aes-decrypter": "4.0.1", - "global": "^4.4.0", - "m3u8-parser": "^7.1.0", - "mpd-parser": "^1.1.1", - "mux.js": "7.0.0", - "video.js": "^7 || ^8" - }, - "engines": { - "node": ">=8", - "npm": ">=5" - }, - "peerDependencies": { - "video.js": "^7 || ^8" - } - }, - "node_modules/@videojs/http-streaming/node_modules/m3u8-parser": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/m3u8-parser/-/m3u8-parser-7.1.0.tgz", - "integrity": "sha512-7N+pk79EH4oLKPEYdgRXgAsKDyA/VCo0qCHlUwacttQA0WqsjZQYmNfywMvjlY9MpEBVZEt0jKFd73Kv15EBYQ==", - "dependencies": { - "@babel/runtime": "^7.12.5", - "@videojs/vhs-utils": "^3.0.5", - "global": "^4.4.0" - } - }, - "node_modules/@videojs/http-streaming/node_modules/m3u8-parser/node_modules/@videojs/vhs-utils": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@videojs/vhs-utils/-/vhs-utils-3.0.5.tgz", - "integrity": "sha512-PKVgdo8/GReqdx512F+ombhS+Bzogiofy1LgAj4tN8PfdBx3HSS7V5WfJotKTqtOWGwVfSWsrYN/t09/DSryrw==", - "dependencies": { - "@babel/runtime": "^7.12.5", - "global": "^4.4.0", - "url-toolkit": "^2.2.1" - }, - "engines": { - "node": ">=8", - "npm": ">=5" - } - }, - "node_modules/@videojs/http-streaming/node_modules/mux.js": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/mux.js/-/mux.js-7.0.0.tgz", - "integrity": "sha512-DeZmr+3NDrO02k4SREtl4VB5GyGPCz2fzMjDxBIlamkxffSTLge97rtNMoonnmFHTp96QggDucUtKv3fmyObrA==", - "dependencies": { - "@babel/runtime": "^7.11.2", - "global": "^4.4.0" - }, - "bin": { - "muxjs-transmux": "bin/transmux.js" - }, - "engines": { - "node": ">=8", - "npm": ">=5" - } - }, - "node_modules/@videojs/vhs-utils": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@videojs/vhs-utils/-/vhs-utils-4.0.0.tgz", - "integrity": "sha512-xJp7Yd4jMLwje2vHCUmi8MOUU76nxiwII3z4Eg3Ucb+6rrkFVGosrXlMgGnaLjq724j3wzNElRZ71D/CKrTtxg==", - "dependencies": { - "@babel/runtime": "^7.12.5", - "global": "^4.4.0", - "url-toolkit": "^2.2.1" - }, - "engines": { - "node": ">=8", - "npm": ">=5" - } - }, - "node_modules/@videojs/xhr": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/@videojs/xhr/-/xhr-2.6.0.tgz", - "integrity": "sha512-7J361GiN1tXpm+gd0xz2QWr3xNWBE+rytvo8J3KuggFaLg+U37gZQ2BuPLcnkfGffy2e+ozY70RHC8jt7zjA6Q==", - "dependencies": { - "@babel/runtime": "^7.5.5", - "global": "~4.4.0", - "is-function": "^1.0.1" - } - }, - "node_modules/@xmldom/xmldom": { - "version": "0.8.10", - "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz", - "integrity": "sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==", - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/aes-decrypter": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/aes-decrypter/-/aes-decrypter-4.0.1.tgz", - "integrity": "sha512-H1nh/P9VZXUf17AA5NQfJML88CFjVBDuGkp5zDHa7oEhYN9TTpNLJknRY1ie0iSKWlDf6JRnJKaZVDSQdPy6Cg==", - "dependencies": { - "@babel/runtime": "^7.12.5", - "@videojs/vhs-utils": "^3.0.5", - "global": "^4.4.0", - "pkcs7": "^1.0.4" - } - }, - "node_modules/aes-decrypter/node_modules/@videojs/vhs-utils": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@videojs/vhs-utils/-/vhs-utils-3.0.5.tgz", - "integrity": "sha512-PKVgdo8/GReqdx512F+ombhS+Bzogiofy1LgAj4tN8PfdBx3HSS7V5WfJotKTqtOWGwVfSWsrYN/t09/DSryrw==", - "dependencies": { - "@babel/runtime": "^7.12.5", - "global": "^4.4.0", - "url-toolkit": "^2.2.1" - }, - "engines": { - "node": ">=8", - "npm": ">=5" - } - }, - "node_modules/base-64": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/base-64/-/base-64-1.0.0.tgz", - "integrity": "sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg==" - }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/dom-walk": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", - "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==" - }, - "node_modules/engine.io-client": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.5.2.tgz", - "integrity": "sha512-CQZqbrpEYnrpGqC07a9dJDz4gePZUgTPMU3NKJPSeQOyw27Tst4Pl3FemKoFGAlHzgZmKjoRmiJvbWfhCXUlIg==", - "dependencies": { - "@socket.io/component-emitter": "~3.1.0", - "debug": "~4.3.1", - "engine.io-parser": "~5.2.1", - "ws": "~8.11.0", - "xmlhttprequest-ssl": "~2.0.0" - } - }, - "node_modules/engine.io-client/node_modules/ws": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", - "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/engine.io-parser": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.1.tgz", - "integrity": "sha512-9JktcM3u18nU9N2Lz3bWeBgxVgOKpw7yhRaoxQA3FUDZzzw+9WlA6p4G4u0RixNkg14fH7EfEc/RhpurtiROTQ==", - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/global": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", - "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", - "dependencies": { - "min-document": "^2.19.0", - "process": "^0.11.10" - } - }, - "node_modules/individual": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/individual/-/individual-2.0.0.tgz", - "integrity": "sha512-pWt8hBCqJsUWI/HtcfWod7+N9SgAqyPEaF7JQjwzjn5vGrpg6aQ5qeAFQ7dx//UH4J1O+7xqew+gCeeFt6xN/g==" - }, - "node_modules/is-function": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz", - "integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==" - }, - "node_modules/keycode": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/keycode/-/keycode-2.2.0.tgz", - "integrity": "sha512-ps3I9jAdNtRpJrbBvQjpzyFbss/skHqzS+eu4RxKLaEAtFqkjZaB6TZMSivPbLxf4K7VI4SjR0P5mRCX5+Q25A==" - }, - "node_modules/m3u8-parser": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/m3u8-parser/-/m3u8-parser-6.2.0.tgz", - "integrity": "sha512-qlC00JTxYOxawcqg+RB8jbyNwL3foY/nCY61kyWP+RCuJE9APLeqB/nSlTjb4Mg0yRmyERgjswpdQxMvkeoDrg==", - "dependencies": { - "@babel/runtime": "^7.12.5", - "@videojs/vhs-utils": "^3.0.5", - "global": "^4.4.0" - } - }, - "node_modules/m3u8-parser/node_modules/@videojs/vhs-utils": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@videojs/vhs-utils/-/vhs-utils-3.0.5.tgz", - "integrity": "sha512-PKVgdo8/GReqdx512F+ombhS+Bzogiofy1LgAj4tN8PfdBx3HSS7V5WfJotKTqtOWGwVfSWsrYN/t09/DSryrw==", - "dependencies": { - "@babel/runtime": "^7.12.5", - "global": "^4.4.0", - "url-toolkit": "^2.2.1" - }, - "engines": { - "node": ">=8", - "npm": ">=5" - } - }, - "node_modules/min-document": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", - "integrity": "sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ==", - "dependencies": { - "dom-walk": "^0.1.0" - } - }, - "node_modules/mpd-parser": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/mpd-parser/-/mpd-parser-1.2.2.tgz", - "integrity": "sha512-QCfB1koOoZw6E5La1cx+W/Yd0EZlRhHMqMr4TAJez0eRTuPDzPM5FWoiOqjyo37W+ISPLzmfJACSbJFEBjbL4Q==", - "dependencies": { - "@babel/runtime": "^7.12.5", - "@videojs/vhs-utils": "^3.0.5", - "@xmldom/xmldom": "^0.8.3", - "global": "^4.4.0" - }, - "bin": { - "mpd-to-m3u8-json": "bin/parse.js" - } - }, - "node_modules/mpd-parser/node_modules/@videojs/vhs-utils": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@videojs/vhs-utils/-/vhs-utils-3.0.5.tgz", - "integrity": "sha512-PKVgdo8/GReqdx512F+ombhS+Bzogiofy1LgAj4tN8PfdBx3HSS7V5WfJotKTqtOWGwVfSWsrYN/t09/DSryrw==", - "dependencies": { - "@babel/runtime": "^7.12.5", - "global": "^4.4.0", - "url-toolkit": "^2.2.1" - }, - "engines": { - "node": ">=8", - "npm": ">=5" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/mux.js": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/mux.js/-/mux.js-6.3.0.tgz", - "integrity": "sha512-/QTkbSAP2+w1nxV+qTcumSDN5PA98P0tjrADijIzQHe85oBK3Akhy9AHlH0ne/GombLMz1rLyvVsmrgRxoPDrQ==", - "dependencies": { - "@babel/runtime": "^7.11.2", - "global": "^4.4.0" - }, - "bin": { - "muxjs-transmux": "bin/transmux.js" - }, - "engines": { - "node": ">=8", - "npm": ">=5" - } - }, - "node_modules/node-fetch": { - "version": "2.6.13", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.13.tgz", - "integrity": "sha512-StxNAxh15zr77QvvkmveSQ8uCQ4+v5FkvNTj0OESmiHu+VRi/gXArXtkWMElOsOUNLtUEvI4yS+rdtOHZTwlQA==", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/pkcs7": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/pkcs7/-/pkcs7-1.0.4.tgz", - "integrity": "sha512-afRERtHn54AlwaF2/+LFszyAANTCggGilmcmILUzEjvs3XgFZT+xE6+QWQcAGmu4xajy+Xtj7acLOPdx5/eXWQ==", - "dependencies": { - "@babel/runtime": "^7.5.5" - }, - "bin": { - "pkcs7": "bin/cli.js" - } - }, - "node_modules/pristinejs": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pristinejs/-/pristinejs-0.1.1.tgz", - "integrity": "sha512-dhIBdMDCVSTIwmkIDBA+sPMN5OPTKaJO/d8nlnmnjghjFyTFN6KDnHX35CZ8OjzpmVjujSGvIgwDxpQtNKJ1rA==" - }, - "node_modules/process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", - "engines": { - "node": ">= 0.6.0" - } - }, - "node_modules/pyodide": { - "version": "0.23.4", - "resolved": "https://registry.npmjs.org/pyodide/-/pyodide-0.23.4.tgz", - "integrity": "sha512-WpQUHaIXQ1xede5BMqPAjBcmopxN22s5hEsYOR8T7/UW/fkNLFUn07SaemUgthbtvedD5JGymMMj4VpD9sGMTg==", - "dependencies": { - "base-64": "^1.0.0", - "node-fetch": "^2.6.1", - "ws": "^8.5.0" - } - }, - "node_modules/regenerator-runtime": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", - "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==" - }, - "node_modules/rust-result": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/rust-result/-/rust-result-1.0.0.tgz", - "integrity": "sha512-6cJzSBU+J/RJCF063onnQf0cDUOHs9uZI1oroSGnHOph+CQTIJ5Pp2hK5kEQq1+7yE/EEWfulSNXAQ2jikPthA==", - "dependencies": { - "individual": "^2.0.0" - } - }, - "node_modules/safe-json-parse": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/safe-json-parse/-/safe-json-parse-4.0.0.tgz", - "integrity": "sha512-RjZPPHugjK0TOzFrLZ8inw44s9bKox99/0AZW9o/BEQVrJfhI+fIHMErnPyRa89/yRXUUr93q+tiN6zhoVV4wQ==", - "dependencies": { - "rust-result": "^1.0.0" - } - }, - "node_modules/socket.io-client": { - "version": "4.7.2", - "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.7.2.tgz", - "integrity": "sha512-vtA0uD4ibrYD793SOIAwlo8cj6haOeMHrGvwPxJsxH7CeIksqJ+3Zc06RvWTIFgiSqx4A3sOnTXpfAEE2Zyz6w==", - "dependencies": { - "@socket.io/component-emitter": "~3.1.0", - "debug": "~4.3.2", - "engine.io-client": "~6.5.2", - "socket.io-parser": "~4.2.4" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/socket.io-parser": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", - "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==", - "dependencies": { - "@socket.io/component-emitter": "~3.1.0", - "debug": "~4.3.1" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" - }, - "node_modules/turretcss": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/turretcss/-/turretcss-5.2.2.tgz", - "integrity": "sha512-N9rnnRrwEWCz5+P+cHW+HUmHWco0XuvcriXa6aFcMnJazDDTGixVI2hOB0Uu8wk7SvwNKi6qiEiaqweeiRst9g==" - }, - "node_modules/url-toolkit": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/url-toolkit/-/url-toolkit-2.2.5.tgz", - "integrity": "sha512-mtN6xk+Nac+oyJ/PrI7tzfmomRVNFIWKUbG8jdYFt52hxbiReFAXIjYskvu64/dvuW71IcB7lV8l0HvZMac6Jg==" - }, - "node_modules/video.js": { - "version": "8.5.2", - "resolved": "https://registry.npmjs.org/video.js/-/video.js-8.5.2.tgz", - "integrity": "sha512-6/uNXQV3xSaKLpaPf/bVvr7omd+82sKUp0RMBgIt4PxHIe28GtX+O+GcNfI2fuwBvcDRDqk5Ei5AG9bJJOpulA==", - "dependencies": { - "@babel/runtime": "^7.12.5", - "@videojs/http-streaming": "3.5.3", - "@videojs/vhs-utils": "^4.0.0", - "@videojs/xhr": "2.6.0", - "aes-decrypter": "^4.0.1", - "global": "4.4.0", - "keycode": "2.2.0", - "m3u8-parser": "^6.0.0", - "mpd-parser": "^1.0.1", - "mux.js": "^6.2.0", - "safe-json-parse": "4.0.0", - "videojs-contrib-quality-levels": "4.0.0", - "videojs-font": "4.1.0", - "videojs-vtt.js": "0.15.5" - } - }, - "node_modules/videojs-contrib-quality-levels": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/videojs-contrib-quality-levels/-/videojs-contrib-quality-levels-4.0.0.tgz", - "integrity": "sha512-u5rmd8BjLwANp7XwuQ0Q/me34bMe6zg9PQdHfTS7aXgiVRbNTb4djcmfG7aeSrkpZjg+XCLezFNenlJaCjBHKw==", - "dependencies": { - "global": "^4.4.0" - }, - "engines": { - "node": ">=14", - "npm": ">=6" - }, - "peerDependencies": { - "video.js": "^8" - } - }, - "node_modules/videojs-font": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/videojs-font/-/videojs-font-4.1.0.tgz", - "integrity": "sha512-X1LuPfLZPisPLrANIAKCknZbZu5obVM/ylfd1CN+SsCmPZQ3UMDPcvLTpPBJxcBuTpHQq2MO1QCFt7p8spnZ/w==" - }, - "node_modules/videojs-vtt.js": { - "version": "0.15.5", - "resolved": "https://registry.npmjs.org/videojs-vtt.js/-/videojs-vtt.js-0.15.5.tgz", - "integrity": "sha512-yZbBxvA7QMYn15Lr/ZfhhLPrNpI/RmCSCqgIff57GC2gIrV5YfyzLfLyZMj0NnZSAz8syB4N0nHXpZg9MyrMOQ==", - "dependencies": { - "global": "^4.3.1" - } - }, - "node_modules/videojs-youtube": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/videojs-youtube/-/videojs-youtube-3.0.1.tgz", - "integrity": "sha512-0gKgag7Zno/dDwIdk+h48ODKDulR4IW62RxGE81PrMwi0OX/wUcKO6m1j+DFYI+7qjtWMZTKnbtQoHGxvUrFQg==", - "dependencies": { - "video.js": "5.x || 6.x || 7.x || 8.x" - }, - "peerDependencies": { - "video.js": "5.x || 6.x || 7.x || 8.x" - } - }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" - }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "node_modules/ws": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", - "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/xmlhttprequest-ssl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz", - "integrity": "sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==", - "engines": { - "node": ">=0.4.0" - } - } - } -} diff --git a/package.json b/package.json index 3429307..ab775ac 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,10 @@ { "dependencies": { + "@ffmpeg/core": "^0.12.4", + "@ffmpeg/core-mt": "^0.12.4", + "@ffmpeg/ffmpeg": "^0.12.7", + "@ffmpeg/util": "^0.12.1", + "coi-serviceworker": "^0.1.7", "socket.io-client": "^4.7.2", "turretcss": "^5.2.2", "video.js": "^8.5.2" diff --git a/static/js/custom.js b/static/js/custom.js index 6354d53..6693c6a 100644 --- a/static/js/custom.js +++ b/static/js/custom.js @@ -16,6 +16,7 @@ var eid3fields = ["album", "bpm", "compilation", "composer", "encodedby", "lyric var ginfo = []; // Limits of the server var glimits = []; +var streamPick = ""; // Predefined themes var themes = { "white": { @@ -43,6 +44,31 @@ var themes = { "textcolor": "#ffffff" } }; +const DO_NOT_RETRY = "coi-dnr"; +window.coi = { + shouldRegister: () => { + if (!window["sessionStorage"]) return false; + let register = !window.sessionStorage.getItem(DO_NOT_RETRY); + window.sessionStorage.removeItem(DO_NOT_RETRY); + return register; + }, + coepCredentialless: () => { + if (window["chrome"] !== undefined || window["netscape"] !== undefined) return true; + const test = /firefox(\/(\d+))?/i; + try { + const match = test.exec(window.navigator.userAgent); + if (match && match[2]) { + const n = parseInt(match[2]); + if (!isNaN(n) && n >= 119) return true; + } + } catch (e) { } + return false; + }, + doReload: () => { + window.sessionStorage.setItem(DO_NOT_RETRY, "true"); + window.location.reload() + } +}; // Do when the document has loaded document.addEventListener("DOMContentLoaded", function () { // Check url for youtube link and if there's a youtube link prefill the Video/Playlist URL field with it @@ -52,8 +78,8 @@ document.addEventListener("DOMContentLoaded", function () { } // Load theme from last theme settings // If a gradient is set up load the gradient - if (document.querySelector("#gradienttop").value != "none"){ - if (document.querySelector("#gradientbottom").value != "none"){ + if (document.querySelector("#gradienttop").value != "none") { + if (document.querySelector("#gradientbottom").value != "none") { setTheme(true); } else { setTheme(); @@ -94,7 +120,14 @@ document.addEventListener("DOMContentLoaded", function () { glimits = limits; // Populate the limits table for (it in limits) { - document.querySelector("#" + limits[it]["limitid"]).innerHTML = limits[it]["limitvalue"]; + var lv = Number(limits[it]["limitvalue"]); + var curl = ""; + if (limits[it]["limitid"].includes("Length")) { + curl = "" + (Math.floor(lv / 60)).toString().padStart(2, "0") + ":" + (lv % 60).toString().padStart(2, "0"); + } else { + curl = lv.toString(); + } + document.querySelector("#" + limits[it]["limitid"]).innerHTML = curl; } } else { // Get method @@ -152,9 +185,71 @@ document.addEventListener("DOMContentLoaded", function () { }); // When downloading a stream from the select the Get all download links for video method provides just open the link in a new tab -function dlStream(selectID) { - var index = document.getElementById(selectID).value; - window.open(ginfo["formats"][Number(index)]["url"], "_blank"); +function dlStream(sid) { + if (document.getElementById("combineCheck").checked == true) { + //var aurl = ginfo["formats"][document.querySelector("#a_" + sid).value]["url"]; + //var vurl = ginfo["formats"][document.querySelector("#v_" + sid).value]["url"]; + //combineStreams(aurl, vurl); + var vid = ginfo["formats"][document.querySelector("#v_" + sid).value]["format_id"]; + var aid = ginfo["formats"][document.querySelector("#a_" + sid).value]["format_id"]; + combineStreamsHard(vid, aid); + } else { + window.open(ginfo["formats"][streamPick]["url"], "_blank"); + } +} + +const { fetchFile } = FFmpegUtil; +const { FFmpeg } = FFmpegWASM; +let ffmpeg = null; + +// On hold, ffmpeg-wasm needs more testing +// import { FFmpeg } from '@ffmpeg/ffmpeg'; +// import { fetchFile, toBlobURL } from '@ffmpeg/util'; +async function combineStreams(aurl, vurl, sid) { + console.log("loading ffmpeg"); + try { + if (ffmpeg === null) { + ffmpeg = new FFmpeg(); + ffmpeg.on("log", ({ message }) => { + console.log(message); + }) + ffmpeg.on("progress", ({ progress, time }) => { + console.log(`${progress * 100} %, time: ${time / 1000000} s`); + }); + // TODO: Providing necessary headers + // TODO: Figure out what needs to be done to get this working live + await ffmpeg.load({ + coreURL: '/node_modules/@ffmpeg/core/dist/umd/ffmpeg-core.js', + //wasmURL: '/node_modules/@ffmpeg/core-mt/dist/umd/ffmpeg-core.wasm', + //workerURL: '/node_modules/@ffmpeg/core-mt/dist/umd/ffmpeg-core.worker.js', + }); + } + console.log("loaded ffmpeg"); + console.log("fetching audio"); + await ffmpeg.writeFile('inputaudio.mp3', await fetchFile(aurl)); + console.log("fetching video"); + console.log(vurl); + await ffmpeg.writeFile('inputvideo.mp4', await fetchFile(vurl)); + // Todo: codec matching for more efficient mixing + console.log("mixing"); + await ffmpeg.exec(['-i', 'inputvideo.mp4', '-i', 'inputaudio.mp3', '-c:v', 'mp4', '-c:a', 'aac', 'output.mp4']); + console.log("done"); + const data = await ffmpeg.readFile('output.mp4'); + window.open(URL.createObjectURL(new Blob([data.buffer], { type: 'video/mp4' })), "_blank"); +} catch (e){ + console.trace(); +} +} + +function combineStreamsHard(format_id, format_id_audio){ + var spinnerid = genSpinner(); + var data = { + "url": ginfo["original_url"], + "format_id": format_id, + "format_id_audio": format_id_audio, + "spinnerid": spinnerid + } + socket.emit("combine", data); } // Method for showing notifications in title @@ -197,12 +292,32 @@ function makeRow(data) { if (data["method"] == "streams") { // Used to differentiate selects when there are multiple var iid = crypto.randomUUID(); - lhtml += "
"; + vhtml = "Video"; + ohtml = "Misc"; - lhtml += "
" + lhtml += ahtml + "" + vhtml + "" + chtml + "" + ohtml + ""; + // TODO: Split dropdown into audio/video/both dropdowns Done + // TODO: Combine and download button for audio/video edit: checkbox + lhtml += "
" + ``; + lhtml += "
"; } else { var iid = crypto.randomUUID(); lhtml += "