diff --git a/.gitmodules b/.gitmodules index b83bc39..3f92968 100644 --- a/.gitmodules +++ b/.gitmodules @@ -2,9 +2,6 @@ [submodule "packages/dasha"] path = packages/dasha url = https://github.com/vitalygashkov/dasha.git -[submodule "packages/crunchyroll"] - path = packages/crunchyroll - url = https://github.com/vitalygashkov/streamyx-crunchyroll.git [submodule "packages/esor"] path = packages/molnia url = https://github.com/vitalygashkov/esor.git @@ -14,3 +11,6 @@ [submodule "apps/desktop"] path = apps/desktop url = https://github.com/vitalygashkov/streamyx-desktop.git +[submodule "packages/extensions"] + path = packages/extensions + url = https://github.com/vitalygashkov/streamyx-extensions.git diff --git a/apps/cli b/apps/cli index 378e263..d616390 160000 --- a/apps/cli +++ b/apps/cli @@ -1 +1 @@ -Subproject commit 378e263c8ee8e262184ad72a5762ba19c73bffef +Subproject commit d61639044fc6654d76eb88a91a5fdf5328f6887f diff --git a/package-lock.json b/package-lock.json index c3577b8..b4cc061 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "license": "AGPL-3.0", "workspaces": [ "packages/*", + "packages/extensions/extensions/*", "apps/*" ], "devDependencies": { @@ -19,7 +20,7 @@ }, "apps/cli": { "name": "@streamyx/cli", - "version": "4.1.6", + "version": "4.1.7", "hasInstallScript": true, "dependencies": { "azot": "^0.6.1", @@ -4649,8 +4650,32 @@ "resolved": "packages/core", "link": true }, - "node_modules/@streamyx/crunchyroll": { - "resolved": "packages/crunchyroll", + "node_modules/@streamyx/extension-crunchyroll": { + "resolved": "packages/extensions/extensions/crunchyroll", + "link": true + }, + "node_modules/@streamyx/extension-ntv": { + "resolved": "packages/extensions/extensions/ntv", + "link": true + }, + "node_modules/@streamyx/extension-rutube": { + "resolved": "packages/extensions/extensions/rutube", + "link": true + }, + "node_modules/@streamyx/extension-soundcloud": { + "resolved": "packages/extensions/extensions/soundcloud", + "link": true + }, + "node_modules/@streamyx/extension-virtualroom": { + "resolved": "packages/extensions/extensions/virtualroom", + "link": true + }, + "node_modules/@streamyx/extension-vk": { + "resolved": "packages/extensions/extensions/vk", + "link": true + }, + "node_modules/@streamyx/extension-weibo": { + "resolved": "packages/extensions/extensions/weibo", "link": true }, "node_modules/@streamyx/loader": { @@ -4661,10 +4686,6 @@ "resolved": "packages/logger", "link": true }, - "node_modules/@streamyx/services": { - "resolved": "packages/services", - "link": true - }, "node_modules/@swc/helpers": { "version": "0.5.15", "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz", @@ -6851,16 +6872,6 @@ "node": ">=8" } }, - "node_modules/browserify-zlib": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.1.4.tgz", - "integrity": "sha512-19OEpq7vWgsH6WkvkBJQDFvJS1uPcbFOQ4v9CU839dO+ZZXUZO6XpE6hNCqvlIIj+4fZvRiJ6DsAQ382GwiyTQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "pako": "~0.2.0" - } - }, "node_modules/browserslist": { "version": "4.24.2", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz", @@ -8298,19 +8309,6 @@ "readable-stream": "^2.0.2" } }, - "node_modules/duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "dev": true, - "license": "MIT", - "dependencies": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - } - }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", @@ -9418,6 +9416,7 @@ "dev": true, "hasInstallScript": true, "license": "MIT", + "peer": true, "bin": { "esbuild": "bin/esbuild" }, @@ -11203,24 +11202,6 @@ "dev": true, "license": "MIT" }, - "node_modules/gunzip-maybe": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/gunzip-maybe/-/gunzip-maybe-1.4.2.tgz", - "integrity": "sha512-4haO1M4mLO91PW57BMsDFf75UmwoRX0GkdD+Faw+Lr+r/OZrOCS0pIBwOL1xCKQqnQzbNFGgK2V2CpBUPeFNTw==", - "dev": true, - "license": "MIT", - "dependencies": { - "browserify-zlib": "^0.1.4", - "is-deflate": "^1.0.0", - "is-gzip": "^1.0.0", - "peek-stream": "^1.1.0", - "pumpify": "^1.3.3", - "through2": "^2.0.3" - }, - "bin": { - "gunzip-maybe": "bin.js" - } - }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -11713,13 +11694,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-deflate": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-deflate/-/is-deflate-1.0.0.tgz", - "integrity": "sha512-YDoFpuZWu1VRXlsnlYMzKyVRITXj7Ej/V9gXQ2/pAe7X1J7M/RNOqaIYi6qUn+B7nGyB9pDXrv02dsB58d2ZAQ==", - "dev": true, - "license": "MIT" - }, "node_modules/is-extendable": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", @@ -11759,16 +11733,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-gzip": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-gzip/-/is-gzip-1.0.0.tgz", - "integrity": "sha512-rcfALRIb1YewtnksfRIHGcIY93QnK8BIQ/2c9yDYcG/Y6+vRoJuTWBmmSEbyLLYtXm7q35pHOHbZFQBaLrhlWQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-interactive": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", @@ -11940,13 +11904,6 @@ "node": ">=0.10.0" } }, - "node_modules/itchy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/itchy/-/itchy-1.0.0.tgz", - "integrity": "sha512-oet14BEPPCAVUPlrZWylyJdJpXqZ5D6cbLY6U2EFf8KN8z2xEd6HIDDnGXO7CDuK+k6z5VyzaLKxzpanhl89Vw==", - "dev": true, - "license": "MIT" - }, "node_modules/jackspeak": { "version": "3.4.3", "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", @@ -14011,13 +13968,6 @@ "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==", "license": "BlueOak-1.0.0" }, - "node_modules/pako": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", - "integrity": "sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==", - "dev": true, - "license": "MIT" - }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -14210,18 +14160,6 @@ "url": "https://github.com/sponsors/jet2jet" } }, - "node_modules/peek-stream": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/peek-stream/-/peek-stream-1.1.3.tgz", - "integrity": "sha512-FhJ+YbOSBb9/rIl2ZeE/QHEsWn7PqNYt8ARAY3kIgNGOk13g9FGyIY6JIl/xB/3TFRVoTv5as0l11weORrTekA==", - "dev": true, - "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "duplexify": "^3.5.0", - "through2": "^2.0.3" - } - }, "node_modules/pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", @@ -14350,16 +14288,6 @@ "integrity": "sha512-e906FRY0+tV27iq4juKzSYPbUj2do2X2JX4EzSca1631EB2QJQUqGbDuERal7LCtOpxl6x3+nvo9NPZcmjkiFA==", "license": "MIT" }, - "node_modules/pipe-io": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pipe-io/-/pipe-io-4.0.1.tgz", - "integrity": "sha512-Wj9G85wJCpIgHq7xd0g4/IDjrA51pxmd+m9AbTiC6zRmWzVC6jOJIUyf92r7/B2+NE6zwqZIz0BZr85xkc3/Sg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/pirates": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", @@ -14867,29 +14795,6 @@ "once": "^1.3.1" } }, - "node_modules/pumpify": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - } - }, - "node_modules/pumpify/node_modules/pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "dev": true, - "license": "MIT", - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -16491,13 +16396,6 @@ "readable-stream": "^2.1.4" } }, - "node_modules/stream-shift": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.3.tgz", - "integrity": "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==", - "dev": true, - "license": "MIT" - }, "node_modules/streamx": { "version": "2.20.2", "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.20.2.tgz", @@ -16924,28 +16822,6 @@ "node": ">= 6" } }, - "node_modules/tar-to-zip": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/tar-to-zip/-/tar-to-zip-3.0.0.tgz", - "integrity": "sha512-ZoEuSzcL8TETGahHr3E3txBs895uSRPywNeFybFkiqgdXSnimwDZJ6uxxGnVwqBX1OEr3mq0kwtY8HGZls9cmA==", - "dev": true, - "license": "MIT", - "dependencies": { - "gunzip-maybe": "^1.3.1", - "itchy": "^1.0.0", - "pipe-io": "^4.0.1", - "tar-stream": "^2.1.4", - "try-to-catch": "^3.0.0", - "yazl": "^2.4.2" - }, - "bin": { - "tar-to-zip": "bin/tar-to-zip.js", - "tar2zip": "bin/tar-to-zip.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/tar/node_modules/chownr": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", @@ -17070,17 +16946,6 @@ "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", "license": "MIT" }, - "node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, "node_modules/tiny-each-async": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/tiny-each-async/-/tiny-each-async-2.0.3.tgz", @@ -17295,16 +17160,6 @@ "utf8-byte-length": "^1.0.1" } }, - "node_modules/try-to-catch": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/try-to-catch/-/try-to-catch-3.0.1.tgz", - "integrity": "sha512-hOY83V84Hx/1sCzDSaJA+Xz2IIQOHRvjxzt+F0OjbQGPZ6yLPLArMA0gw/484MlfUkQbCpKYMLX3VDCAjWKfzQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/ts-api-utils": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", @@ -17918,6 +17773,8 @@ "integrity": "sha512-0flMz1lh74BR4wOvBjuh9olbnwqCPc35OOlfyzHba0Dc+QNUeWX/Gq2YTbnwcWPO3BMd8fkzRVrHcsR+a7z7rA==", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "esbuild": "~0.23.0", "get-tsconfig": "^4.7.5" @@ -19412,6 +19269,7 @@ "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", "dev": true, "license": "MIT", + "optional": true, "engines": { "node": ">=0.4" } @@ -19622,16 +19480,6 @@ "fd-slicer": "~1.1.0" } }, - "node_modules/yazl": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/yazl/-/yazl-2.5.1.tgz", - "integrity": "sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==", - "dev": true, - "license": "MIT", - "dependencies": { - "buffer-crc32": "~0.2.3" - } - }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", @@ -20287,6 +20135,7 @@ "packages/crunchyroll": { "name": "@streamyx/crunchyroll", "version": "0.0.21", + "extraneous": true, "hasInstallScript": true, "license": "AGPL-3.0", "dependencies": { @@ -20580,6 +20429,164 @@ "node": "*" } }, + "packages/extensions/extensions/crunchyroll": { + "name": "@streamyx/extension-crunchyroll", + "version": "0.1.1", + "hasInstallScript": true, + "license": "AGPL-3.0", + "devDependencies": { + "@streamyx/api": "^0.0.6", + "@streamyx/core": "^2.3.2", + "@types/node": "^22.7.5", + "tsup": "^8.3.0", + "typescript": "^5.6.3", + "vitest": "^2.1.3" + } + }, + "packages/extensions/extensions/ntv": { + "name": "@streamyx/extension-ntv", + "version": "0.0.1", + "funding": [ + { + "type": "individual", + "url": "https://boosty.to/vitalygashkov" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/vitalygashkov" + } + ], + "license": "MIT", + "devDependencies": { + "@streamyx/api": "^0.0.6", + "@streamyx/core": "^2.3.2", + "@types/node": "^22.10.1", + "typescript": "^5.7.2" + }, + "engines": { + "node": "20 || 21 || 22 || 23" + } + }, + "packages/extensions/extensions/rutube": { + "name": "@streamyx/extension-rutube", + "version": "0.0.1", + "funding": [ + { + "type": "individual", + "url": "https://boosty.to/vitalygashkov" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/vitalygashkov" + } + ], + "license": "MIT", + "devDependencies": { + "@streamyx/api": "^0.0.6", + "@streamyx/core": "^2.3.2", + "@types/node": "^22.10.1", + "typescript": "^5.7.2" + }, + "engines": { + "node": "20 || 21 || 22 || 23" + } + }, + "packages/extensions/extensions/soundcloud": { + "name": "@streamyx/extension-soundcloud", + "version": "0.0.1", + "funding": [ + { + "type": "individual", + "url": "https://boosty.to/vitalygashkov" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/vitalygashkov" + } + ], + "license": "MIT", + "devDependencies": { + "@streamyx/api": "^0.0.6", + "@streamyx/core": "^2.3.2", + "@types/node": "^22.10.1", + "typescript": "^5.7.2" + }, + "engines": { + "node": "20 || 21 || 22 || 23" + } + }, + "packages/extensions/extensions/virtualroom": { + "name": "@streamyx/extension-virtualroom", + "version": "0.0.1", + "funding": [ + { + "type": "individual", + "url": "https://boosty.to/vitalygashkov" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/vitalygashkov" + } + ], + "license": "MIT", + "devDependencies": { + "@streamyx/api": "^0.0.6", + "@streamyx/core": "^2.3.2", + "@types/node": "^22.10.1", + "typescript": "^5.7.2" + }, + "engines": { + "node": "20 || 21 || 22 || 23" + } + }, + "packages/extensions/extensions/vk": { + "name": "@streamyx/extension-vk", + "version": "0.0.1", + "funding": [ + { + "type": "individual", + "url": "https://boosty.to/vitalygashkov" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/vitalygashkov" + } + ], + "license": "MIT", + "devDependencies": { + "@streamyx/api": "^0.0.6", + "@streamyx/core": "^2.3.2", + "@types/node": "^22.10.1", + "typescript": "^5.7.2" + }, + "engines": { + "node": "20 || 21 || 22 || 23" + } + }, + "packages/extensions/extensions/weibo": { + "name": "@streamyx/extension-weibo", + "version": "0.0.1", + "funding": [ + { + "type": "individual", + "url": "https://boosty.to/vitalygashkov" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/vitalygashkov" + } + ], + "license": "MIT", + "devDependencies": { + "@streamyx/api": "^0.0.6", + "@streamyx/core": "^2.3.2", + "@types/node": "^22.10.1", + "typescript": "^5.7.2" + }, + "engines": { + "node": "20 || 21 || 22 || 23" + } + }, "packages/loader": { "name": "@streamyx/loader", "version": "0.0.3", @@ -21445,6 +21452,7 @@ "packages/services": { "name": "@streamyx/services", "version": "0.0.1", + "extraneous": true, "devDependencies": { "@streamyx/core": "^2.1.1" } diff --git a/package.json b/package.json index 4298378..ba18704 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "scripts": {}, "workspaces": [ "packages/*", + "packages/extensions/extensions/*", "apps/*" ], "devDependencies": { diff --git a/packages/crunchyroll b/packages/crunchyroll deleted file mode 160000 index 06a3ce1..0000000 --- a/packages/crunchyroll +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 06a3ce1372b99baa792f4ea23f9eb0b6a006dea9 diff --git a/packages/extensions b/packages/extensions new file mode 160000 index 0000000..8d070ab --- /dev/null +++ b/packages/extensions @@ -0,0 +1 @@ +Subproject commit 8d070abeeffa4d73f44382dc2473532e17b799d1 diff --git a/packages/services/index.d.ts b/packages/services/index.d.ts deleted file mode 100644 index 3a3dfa8..0000000 --- a/packages/services/index.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { Service } from '@streamyx/core'; - -export const services: Record; diff --git a/packages/services/index.js b/packages/services/index.js deleted file mode 100644 index 6c0c421..0000000 --- a/packages/services/index.js +++ /dev/null @@ -1,12 +0,0 @@ -'use strict'; - -const services = { - rutube: require('./src/rutube'), - soundcloud: require('./src/soundcloud'), - weibo: require('./src/weibo'), - vk: require('./src/vk'), - virtualroom: require('./src/virtualroom'), - ntv: require('./src/ntv'), -}; - -module.exports = { services }; diff --git a/packages/services/package.json b/packages/services/package.json deleted file mode 100644 index 7dc9978..0000000 --- a/packages/services/package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "@streamyx/services", - "version": "0.0.1", - "private": true, - "description": "Built-in services for Streamyx", - "main": "index.js", - "types": "index.d.ts", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "devDependencies": { - "@streamyx/core": "^2.1.1" - } -} diff --git a/packages/services/src/ntv.js b/packages/services/src/ntv.js deleted file mode 100644 index 08bb224..0000000 --- a/packages/services/src/ntv.js +++ /dev/null @@ -1,26 +0,0 @@ -'use strict'; - -/** @type {import("@streamyx/core").Service} */ -module.exports = () => (core) => ({ - name: 'ntv', - tag: 'NTV', - fetchContentMetadata: async (url) => { - const pageResponse = await core.http.fetch(url); - const pageBody = await pageResponse.text(); - const videoFrameLink = pageBody - .split(``)[0] - ?.split(`" />`)[0]; - const videoId = videoFrameLink.split(`embed/`)[1]?.split(`/`)[0]; - const xmlResponse = await core.http.fetch(`https://www.ntv.ru/vi${videoId}/`); - const xmlBody = await xmlResponse.text(); - const fileLink = xmlBody.split(``)[1]?.split(``)[0]?.split(`DATA[`)[1]?.split(`]`)[0]; - const title = xmlBody.split(``)[1]?.split(``)[0]; - const subtitlesRoute = xmlBody.split(``)[1]?.split(``)[0]; - const subtitlesUrl = `https://www.ntv.ru${subtitlesRoute}`; - const hqFileLink = fileLink.replace(`vod/`, `vod/hd/`).replace(`_lo.mp4`, `.mp4`); - core.log.info(`Video: ${hqFileLink}`); - if (subtitlesRoute) core.log.info(`Subtitles: ${subtitlesUrl}`); - return [{ title, source: { url: hqFileLink } }]; - }, -}); diff --git a/packages/services/src/rutube.js b/packages/services/src/rutube.js deleted file mode 100644 index 90d9606..0000000 --- a/packages/services/src/rutube.js +++ /dev/null @@ -1,75 +0,0 @@ -'use strict'; - -/** @type {import("@streamyx/core").Service} */ -module.exports = () => (core) => { - return { - name: 'rutube', - tag: 'RUTUBE', - fetchContentMetadata: async (url) => { - const patterns = [ - '/video/:id{/}?', - '/play/embed/:id{/}?', - '/shorts/:id{/}?', - '/yappy/:yappyId{/}?', - '/video/private/:id{/}??p=:key{/}?', - '/video/private/:id{/}?', - ]; - - const params = { yappyId: '', id: '', key: '' }; - for (const path of patterns) { - const pattern = new URLPattern(path, 'https://rutube.ru'); - const patternResult = pattern.exec(url); - if (patternResult) { - Object.assign(params, patternResult.pathname.groups); - Object.assign(params, patternResult.search.groups); - } - } - - const results = []; - if (params.yappyId) { - const yappy = await fetch( - `https://rutube.ru/pangolin/api/web/yappy/yappypage/?client=wdp&videoId=${params.yappyId}&page=1&page_size=15` - ) - .then((r) => r.json()) - .catch(() => null); - const yappyURL = yappy?.results?.find((r) => r.id === params.yappyId)?.link; - if (!yappyURL) { - core.log.error('ErrorEmptyDownload'); - return results; - } - results.push({ - title: `rutube_yappy_${params.yappyId}`, - source: { url: yappyURL }, - }); - return results; - } - - const requestURL = new URL(`https://rutube.ru/api/play/options/${params.id}/?no_404=true&referer&pver=v2`); - if (params.key) requestURL.searchParams.set('p', params.key); - - const play = await fetch(requestURL) - .then((r) => r.json()) - .catch(() => null); - if (!play) { - core.log.error('Cannot fetch play info'); - return results; - } - if (play.detail || !play.video_balancer) { - core.log.error('Play info is empty'); - return results; - } - if (play.live_streams?.hls) { - core.log.error('Live videos are not supported'); - return results; - } - - const playlistUrl = play.video_balancer.m3u8; - const title = play.title.trim(); - const artist = play.author.name.trim(); - - results.push({ title: `${title} ${artist}`, source: { url: playlistUrl } }); - - return results; - }, - }; -}; diff --git a/packages/services/src/soundcloud.js b/packages/services/src/soundcloud.js deleted file mode 100644 index 3a9b840..0000000 --- a/packages/services/src/soundcloud.js +++ /dev/null @@ -1,114 +0,0 @@ -'use strict'; - -const cachedID = { version: '', id: '' }; - -/** @type {import("@streamyx/core").Service} */ -module.exports = () => (core) => { - async function findClientID() { - try { - const sc = await fetch('https://soundcloud.com/') - .then((r) => r.text()) - .catch((e) => { - const isBlocked = e.cause?.toString().includes('ECONNRESET'); - if (isBlocked) - core.log.warn('Soundcloud may be blocked in your region. Use proxy or VPN to bypass restrictions.'); - return ''; - }); - - const scVersion = String(sc.match(/