From 65f1631fbad3a9817d160462ca317ba2092b0403 Mon Sep 17 00:00:00 2001 From: Vitaly Gashkov Date: Sun, 1 Dec 2024 21:58:59 +0500 Subject: [PATCH 1/5] add extensions submodule with all public extensions --- .gitmodules | 3 +++ package-lock.json | 19 +++++++++++++++++++ package.json | 1 + packages/extensions | 1 + 4 files changed, 24 insertions(+) create mode 160000 packages/extensions diff --git a/.gitmodules b/.gitmodules index b83bc39..c759632 100644 --- a/.gitmodules +++ b/.gitmodules @@ -14,3 +14,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/package-lock.json b/package-lock.json index c3577b8..3d88a28 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "license": "AGPL-3.0", "workspaces": [ "packages/*", + "packages/extensions/extensions/*", "apps/*" ], "devDependencies": { @@ -4653,6 +4654,10 @@ "resolved": "packages/crunchyroll", "link": true }, + "node_modules/@streamyx/extension-crunchyroll": { + "resolved": "packages/extensions/extensions/crunchyroll", + "link": true + }, "node_modules/@streamyx/loader": { "resolved": "packages/loader", "link": true @@ -20580,6 +20585,20 @@ "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/loader": { "name": "@streamyx/loader", "version": "0.0.3", 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/extensions b/packages/extensions new file mode 160000 index 0000000..4d0cec3 --- /dev/null +++ b/packages/extensions @@ -0,0 +1 @@ +Subproject commit 4d0cec3250814bd4e03b91de2bbc56f28a52dabc From 55012c8d21fc5d880d1f6de35363980923a5c008 Mon Sep 17 00:00:00 2001 From: Vitaly Gashkov Date: Sun, 1 Dec 2024 23:22:32 +0500 Subject: [PATCH 2/5] refactor: move virtualroom to extensions repo --- apps/cli | 2 +- packages/services/index.js | 1 - packages/services/src/virtualroom.js | 24 ------------------------ 3 files changed, 1 insertion(+), 26 deletions(-) delete mode 100644 packages/services/src/virtualroom.js diff --git a/apps/cli b/apps/cli index 378e263..81a92d1 160000 --- a/apps/cli +++ b/apps/cli @@ -1 +1 @@ -Subproject commit 378e263c8ee8e262184ad72a5762ba19c73bffef +Subproject commit 81a92d1d15bb4f343a9e7567c2c4afd1687f05c0 diff --git a/packages/services/index.js b/packages/services/index.js index 6c0c421..8a675c1 100644 --- a/packages/services/index.js +++ b/packages/services/index.js @@ -5,7 +5,6 @@ const services = { soundcloud: require('./src/soundcloud'), weibo: require('./src/weibo'), vk: require('./src/vk'), - virtualroom: require('./src/virtualroom'), ntv: require('./src/ntv'), }; diff --git a/packages/services/src/virtualroom.js b/packages/services/src/virtualroom.js deleted file mode 100644 index 5b587cf..0000000 --- a/packages/services/src/virtualroom.js +++ /dev/null @@ -1,24 +0,0 @@ -'use strict'; - -/** @type {import("@streamyx/core").Service} */ -module.exports = () => (core) => ({ - name: 'virtualroom', - fetchContentMetadata: async (url) => { - const recordId = new URL(url).searchParams.get('recordId'); - - const infoUrl = `https://mv1.virtualroom.ru/vr/player/records/${recordId}/info`; - const infoResponse = await core.http.fetch(infoUrl); - const info = await infoResponse.json(); - - const eventsUrl = `https://mv1.virtualroom.ru/vr/player/records/${recordId}/events`; - const eventsResponse = await core.http.fetch(eventsUrl); - const events = await eventsResponse.json(); - - const results = []; - for (const translation of events.data.translations) { - const title = `${info.data.roomParameters.name} ${translation.type} ${translation.source} ${translation.start}`; - results.push({ title, source: { url: translation.url } }); - } - return results; - }, -}); From e25fe23b28196586755ee7110d3bdf1881abe2a3 Mon Sep 17 00:00:00 2001 From: Vitaly Gashkov Date: Sun, 1 Dec 2024 23:35:16 +0500 Subject: [PATCH 3/5] refactor: move services to extensions repo --- apps/cli | 2 +- packages/extensions | 2 +- packages/services/index.d.ts | 3 - packages/services/index.js | 11 --- packages/services/package.json | 14 ---- packages/services/src/ntv.js | 26 ------- packages/services/src/rutube.js | 75 ------------------ packages/services/src/soundcloud.js | 114 ---------------------------- packages/services/src/vk.js | 56 -------------- packages/services/src/weibo.js | 40 ---------- 10 files changed, 2 insertions(+), 341 deletions(-) delete mode 100644 packages/services/index.d.ts delete mode 100644 packages/services/index.js delete mode 100644 packages/services/package.json delete mode 100644 packages/services/src/ntv.js delete mode 100644 packages/services/src/rutube.js delete mode 100644 packages/services/src/soundcloud.js delete mode 100644 packages/services/src/vk.js delete mode 100644 packages/services/src/weibo.js diff --git a/apps/cli b/apps/cli index 81a92d1..d616390 160000 --- a/apps/cli +++ b/apps/cli @@ -1 +1 @@ -Subproject commit 81a92d1d15bb4f343a9e7567c2c4afd1687f05c0 +Subproject commit d61639044fc6654d76eb88a91a5fdf5328f6887f diff --git a/packages/extensions b/packages/extensions index 4d0cec3..8d070ab 160000 --- a/packages/extensions +++ b/packages/extensions @@ -1 +1 @@ -Subproject commit 4d0cec3250814bd4e03b91de2bbc56f28a52dabc +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 8a675c1..0000000 --- a/packages/services/index.js +++ /dev/null @@ -1,11 +0,0 @@ -'use strict'; - -const services = { - rutube: require('./src/rutube'), - soundcloud: require('./src/soundcloud'), - weibo: require('./src/weibo'), - vk: require('./src/vk'), - 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(/