From 2f930a6dfe086a729671e386958134d529dbe395 Mon Sep 17 00:00:00 2001 From: 4gray Date: Thu, 23 Oct 2025 22:54:22 +0200 Subject: [PATCH 1/2] chore(deps): upgrade video.js to 8 Add nested @videojs/http-streaming and related module entries (v2.16.3, video.js 7.21.7, mpd-parser, @videojs/xhr, videojs-font, etc.) required by the upgraded video.js ecosystem. These changes ensure the lockfile reflects the new major video.js version and pulls in compatible HTTP streaming and parsing libraries so consumers get consistent, resolved dependency trees and avoid runtime mismatches when using the newer player. --- package-lock.json | 460 +++++++++++++++++++++++++++++++++++++++++----- package.json | 6 +- 2 files changed, 416 insertions(+), 50 deletions(-) diff --git a/package-lock.json b/package-lock.json index 23cdbc3e9..c36eb71b6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -55,7 +55,7 @@ "rxjs": "7.8.2", "semver": "7.7.3", "uuid": "9.0.0", - "video.js": "7.20.3", + "video.js": "8.23.4", "videojs-contrib-quality-levels": "2.2.0", "videojs-hls-quality-selector": "1.1.4", "zone.js": "~0.15.1" @@ -11964,6 +11964,97 @@ "video.js": "^6 || ^7" } }, + "node_modules/@videojs/http-streaming/node_modules/@videojs/http-streaming": { + "version": "2.16.3", + "resolved": "https://registry.npmjs.org/@videojs/http-streaming/-/http-streaming-2.16.3.tgz", + "integrity": "sha512-91CJv5PnFBzNBvyEjt+9cPzTK/xoVixARj2g7ZAvItA+5bx8VKdk5RxCz/PP2kdzz9W+NiDUMPkdmTsosmy69Q==", + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime": "^7.12.5", + "@videojs/vhs-utils": "3.0.5", + "aes-decrypter": "3.1.3", + "global": "^4.4.0", + "m3u8-parser": "4.8.0", + "mpd-parser": "^0.22.1", + "mux.js": "6.0.1", + "video.js": "^6 || ^7" + }, + "engines": { + "node": ">=8", + "npm": ">=5" + }, + "peerDependencies": { + "video.js": "^6 || ^7" + } + }, + "node_modules/@videojs/http-streaming/node_modules/@videojs/http-streaming/node_modules/mpd-parser": { + "version": "0.22.1", + "resolved": "https://registry.npmjs.org/mpd-parser/-/mpd-parser-0.22.1.tgz", + "integrity": "sha512-fwBebvpyPUU8bOzvhX0VQZgSohncbgYwUyJJoTSNpmy7ccD2ryiCvM7oRkn/xQH5cv73/xU7rJSNCLjdGFor0Q==", + "license": "Apache-2.0", + "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/@videojs/http-streaming/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==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.5.5", + "global": "~4.4.0", + "is-function": "^1.0.1" + } + }, + "node_modules/@videojs/http-streaming/node_modules/video.js": { + "version": "7.21.7", + "resolved": "https://registry.npmjs.org/video.js/-/video.js-7.21.7.tgz", + "integrity": "sha512-T2s3WFAht7Zjr2OSJamND9x9Dn2O+Z5WuHGdh8jI5SYh5mkMdVTQ7vSRmA5PYpjXJ2ycch6jpMjkJEIEU2xxqw==", + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime": "^7.12.5", + "@videojs/http-streaming": "2.16.3", + "@videojs/vhs-utils": "^3.0.4", + "@videojs/xhr": "2.6.0", + "aes-decrypter": "3.1.3", + "global": "^4.4.0", + "keycode": "^2.2.0", + "m3u8-parser": "4.8.0", + "mpd-parser": "0.22.1", + "mux.js": "6.0.1", + "safe-json-parse": "4.0.0", + "videojs-font": "3.2.0", + "videojs-vtt.js": "^0.15.5" + } + }, + "node_modules/@videojs/http-streaming/node_modules/video.js/node_modules/mpd-parser": { + "version": "0.22.1", + "resolved": "https://registry.npmjs.org/mpd-parser/-/mpd-parser-0.22.1.tgz", + "integrity": "sha512-fwBebvpyPUU8bOzvhX0VQZgSohncbgYwUyJJoTSNpmy7ccD2ryiCvM7oRkn/xQH5cv73/xU7rJSNCLjdGFor0Q==", + "license": "Apache-2.0", + "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/@videojs/http-streaming/node_modules/videojs-font": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/videojs-font/-/videojs-font-3.2.0.tgz", + "integrity": "sha512-g8vHMKK2/JGorSfqAZQUmYYNnXmfec4MLhwtEFS+mMs2IDY398GLysy6BH6K+aS1KMNu/xWZ8Sue/X/mdQPliA==", + "license": "Apache-2.0" + }, "node_modules/@videojs/vhs-utils": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/@videojs/vhs-utils/-/vhs-utils-3.0.5.tgz", @@ -11980,9 +12071,9 @@ } }, "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==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@videojs/xhr/-/xhr-2.7.0.tgz", + "integrity": "sha512-giab+EVRanChIupZK7gXjHy90y3nncA2phIOyG3Ne5fvpiMJzvqYwiTOnEVW2S4CoYcuKJkomat7bMXA/UoUZQ==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.5.5", @@ -12168,7 +12259,6 @@ "version": "0.8.11", "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.11.tgz", "integrity": "sha512-cQzWCtO6C8TQiYl1ruKNn2U6Ao4o4WBBcbL61yJl84x+j5sOWWFU9X7DpND8XZG3daDppSsigMdfAIl2upQBRw==", - "dev": true, "license": "MIT", "engines": { "node": ">=10.0.0" @@ -12202,6 +12292,82 @@ "npm": ">=5" } }, + "node_modules/@yangkghjh/videojs-aspect-ratio-panel/node_modules/@videojs/http-streaming": { + "version": "2.16.3", + "resolved": "https://registry.npmjs.org/@videojs/http-streaming/-/http-streaming-2.16.3.tgz", + "integrity": "sha512-91CJv5PnFBzNBvyEjt+9cPzTK/xoVixARj2g7ZAvItA+5bx8VKdk5RxCz/PP2kdzz9W+NiDUMPkdmTsosmy69Q==", + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime": "^7.12.5", + "@videojs/vhs-utils": "3.0.5", + "aes-decrypter": "3.1.3", + "global": "^4.4.0", + "m3u8-parser": "4.8.0", + "mpd-parser": "^0.22.1", + "mux.js": "6.0.1", + "video.js": "^6 || ^7" + }, + "engines": { + "node": ">=8", + "npm": ">=5" + }, + "peerDependencies": { + "video.js": "^6 || ^7" + } + }, + "node_modules/@yangkghjh/videojs-aspect-ratio-panel/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==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.5.5", + "global": "~4.4.0", + "is-function": "^1.0.1" + } + }, + "node_modules/@yangkghjh/videojs-aspect-ratio-panel/node_modules/mpd-parser": { + "version": "0.22.1", + "resolved": "https://registry.npmjs.org/mpd-parser/-/mpd-parser-0.22.1.tgz", + "integrity": "sha512-fwBebvpyPUU8bOzvhX0VQZgSohncbgYwUyJJoTSNpmy7ccD2ryiCvM7oRkn/xQH5cv73/xU7rJSNCLjdGFor0Q==", + "license": "Apache-2.0", + "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/@yangkghjh/videojs-aspect-ratio-panel/node_modules/video.js": { + "version": "7.21.7", + "resolved": "https://registry.npmjs.org/video.js/-/video.js-7.21.7.tgz", + "integrity": "sha512-T2s3WFAht7Zjr2OSJamND9x9Dn2O+Z5WuHGdh8jI5SYh5mkMdVTQ7vSRmA5PYpjXJ2ycch6jpMjkJEIEU2xxqw==", + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime": "^7.12.5", + "@videojs/http-streaming": "2.16.3", + "@videojs/vhs-utils": "^3.0.4", + "@videojs/xhr": "2.6.0", + "aes-decrypter": "3.1.3", + "global": "^4.4.0", + "keycode": "^2.2.0", + "m3u8-parser": "4.8.0", + "mpd-parser": "0.22.1", + "mux.js": "6.0.1", + "safe-json-parse": "4.0.0", + "videojs-font": "3.2.0", + "videojs-vtt.js": "^0.15.5" + } + }, + "node_modules/@yangkghjh/videojs-aspect-ratio-panel/node_modules/videojs-font": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/videojs-font/-/videojs-font-3.2.0.tgz", + "integrity": "sha512-g8vHMKK2/JGorSfqAZQUmYYNnXmfec4MLhwtEFS+mMs2IDY398GLysy6BH6K+aS1KMNu/xWZ8Sue/X/mdQPliA==", + "license": "Apache-2.0" + }, "node_modules/@yarnpkg/lockfile": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", @@ -36762,85 +36928,133 @@ "optional": true }, "node_modules/video.js": { - "version": "7.20.3", - "resolved": "https://registry.npmjs.org/video.js/-/video.js-7.20.3.tgz", - "integrity": "sha512-JMspxaK74LdfWcv69XWhX4rILywz/eInOVPdKefpQiZJSMD5O8xXYueqACP2Q5yqKstycgmmEKlJzZ+kVmDciw==", + "version": "8.23.4", + "resolved": "https://registry.npmjs.org/video.js/-/video.js-8.23.4.tgz", + "integrity": "sha512-qI0VTlYmKzEqRsz1Nppdfcaww4RSxZAq77z2oNSl3cNg2h6do5C8Ffl0KqWQ1OpD8desWXsCrde7tKJ9gGTEyQ==", "license": "Apache-2.0", "dependencies": { "@babel/runtime": "^7.12.5", - "@videojs/http-streaming": "2.14.3", - "@videojs/vhs-utils": "^3.0.4", - "@videojs/xhr": "2.6.0", - "aes-decrypter": "3.1.3", - "global": "^4.4.0", - "keycode": "^2.2.0", - "m3u8-parser": "4.7.1", - "mpd-parser": "0.21.1", - "mux.js": "6.0.1", - "safe-json-parse": "4.0.0", - "videojs-font": "3.2.0", - "videojs-vtt.js": "^0.15.4" + "@videojs/http-streaming": "^3.17.2", + "@videojs/vhs-utils": "^4.1.1", + "@videojs/xhr": "2.7.0", + "aes-decrypter": "^4.0.2", + "global": "4.4.0", + "m3u8-parser": "^7.2.0", + "mpd-parser": "^1.3.1", + "mux.js": "^7.0.1", + "videojs-contrib-quality-levels": "4.1.0", + "videojs-font": "4.2.0", + "videojs-vtt.js": "0.15.5" } }, "node_modules/video.js/node_modules/@videojs/http-streaming": { - "version": "2.14.3", - "resolved": "https://registry.npmjs.org/@videojs/http-streaming/-/http-streaming-2.14.3.tgz", - "integrity": "sha512-2tFwxCaNbcEZzQugWf8EERwNMyNtspfHnvxRGRABQs09W/5SqmkWFuGWfUAm4wQKlXGfdPyAJ1338ASl459xAA==", + "version": "3.17.2", + "resolved": "https://registry.npmjs.org/@videojs/http-streaming/-/http-streaming-3.17.2.tgz", + "integrity": "sha512-VBQ3W4wnKnVKb/limLdtSD2rAd5cmHN70xoMf4OmuDd0t2kfJX04G+sfw6u2j8oOm2BXYM9E1f4acHruqKnM1g==", "license": "Apache-2.0", "dependencies": { "@babel/runtime": "^7.12.5", - "@videojs/vhs-utils": "3.0.5", - "aes-decrypter": "3.1.3", + "@videojs/vhs-utils": "^4.1.1", + "aes-decrypter": "^4.0.2", "global": "^4.4.0", - "m3u8-parser": "4.7.1", - "mpd-parser": "0.21.1", - "mux.js": "6.0.1", - "video.js": "^6 || ^7" + "m3u8-parser": "^7.2.0", + "mpd-parser": "^1.3.1", + "mux.js": "7.1.0", + "video.js": "^7 || ^8" }, "engines": { "node": ">=8", "npm": ">=5" }, "peerDependencies": { - "video.js": "^6 || ^7" + "video.js": "^8.19.0" } }, - "node_modules/video.js/node_modules/@xmldom/xmldom": { - "version": "0.7.13", - "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.7.13.tgz", - "integrity": "sha512-lm2GW5PkosIzccsaZIz7tp8cPADSIlIHWDFTR1N0SzfinhhYgeIQjFMz4rYzanCScr3DqQLeomUDArp6MWKm+g==", - "deprecated": "this version is no longer supported, please update to at least 0.8.*", + "node_modules/video.js/node_modules/@videojs/vhs-utils": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@videojs/vhs-utils/-/vhs-utils-4.1.1.tgz", + "integrity": "sha512-5iLX6sR2ownbv4Mtejw6Ax+naosGvoT9kY+gcuHzANyUZZ+4NpeNdKMUhb6ag0acYej1Y7cmr/F2+4PrggMiVA==", "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5", + "global": "^4.4.0" + }, "engines": { - "node": ">=10.0.0" + "node": ">=8", + "npm": ">=5" } }, - "node_modules/video.js/node_modules/m3u8-parser": { - "version": "4.7.1", - "resolved": "https://registry.npmjs.org/m3u8-parser/-/m3u8-parser-4.7.1.tgz", - "integrity": "sha512-pbrQwiMiq+MmI9bl7UjtPT3AK603PV9bogNlr83uC+X9IoxqL5E4k7kU7fMQ0dpRgxgeSMygqUa0IMLQNXLBNA==", + "node_modules/video.js/node_modules/aes-decrypter": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/aes-decrypter/-/aes-decrypter-4.0.2.tgz", + "integrity": "sha512-lc+/9s6iJvuaRe5qDlMTpCFjnwpkeOXp8qP3oiZ5jsj1MRg+SBVUmmICrhxHvc8OELSmc+fEyyxAuppY6hrWzw==", "license": "Apache-2.0", "dependencies": { "@babel/runtime": "^7.12.5", - "@videojs/vhs-utils": "^3.0.5", + "@videojs/vhs-utils": "^4.1.1", + "global": "^4.4.0", + "pkcs7": "^1.0.4" + } + }, + "node_modules/video.js/node_modules/m3u8-parser": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/m3u8-parser/-/m3u8-parser-7.2.0.tgz", + "integrity": "sha512-CRatFqpjVtMiMaKXxNvuI3I++vUumIXVVT/JpCpdU/FynV/ceVw1qpPyyBNindL+JlPMSesx+WX1QJaZEJSaMQ==", + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime": "^7.12.5", + "@videojs/vhs-utils": "^4.1.1", "global": "^4.4.0" } }, "node_modules/video.js/node_modules/mpd-parser": { - "version": "0.21.1", - "resolved": "https://registry.npmjs.org/mpd-parser/-/mpd-parser-0.21.1.tgz", - "integrity": "sha512-BxlSXWbKE1n7eyEPBnTEkrzhS3PdmkkKdM1pgKbPnPOH0WFZIc0sPOWi7m0Uo3Wd2a4Or8Qf4ZbS7+ASqQ49fw==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/mpd-parser/-/mpd-parser-1.3.1.tgz", + "integrity": "sha512-1FuyEWI5k2HcmhS1HkKnUAQV7yFPfXPht2DnRRGtoiiAAW+ESTbtEXIDpRkwdU+XyrQuwrIym7UkoPKsZ0SyFw==", "license": "Apache-2.0", "dependencies": { "@babel/runtime": "^7.12.5", - "@videojs/vhs-utils": "^3.0.5", - "@xmldom/xmldom": "^0.7.2", + "@videojs/vhs-utils": "^4.0.0", + "@xmldom/xmldom": "^0.8.3", "global": "^4.4.0" }, "bin": { "mpd-to-m3u8-json": "bin/parse.js" } }, + "node_modules/video.js/node_modules/mux.js": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/mux.js/-/mux.js-7.1.0.tgz", + "integrity": "sha512-NTxawK/BBELJrYsZThEulyUMDVlLizKdxyAsMuzoCD1eFj97BVaA8D/CvKsKu6FOLYkFojN5CbM9h++ZTZtknA==", + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime": "^7.11.2", + "global": "^4.4.0" + }, + "bin": { + "muxjs-transmux": "bin/transmux.js" + }, + "engines": { + "node": ">=8", + "npm": ">=5" + } + }, + "node_modules/video.js/node_modules/videojs-contrib-quality-levels": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/videojs-contrib-quality-levels/-/videojs-contrib-quality-levels-4.1.0.tgz", + "integrity": "sha512-TfrXJJg1Bv4t6TOCMEVMwF/CoS8iENYsWNKip8zfhB5kTcegiFYezEA0eHAJPU64ZC8NQbxQgOwAsYU8VXbOWA==", + "license": "Apache-2.0", + "dependencies": { + "global": "^4.4.0" + }, + "engines": { + "node": ">=16", + "npm": ">=8" + }, + "peerDependencies": { + "video.js": "^8" + } + }, "node_modules/videojs-contrib-quality-levels": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/videojs-contrib-quality-levels/-/videojs-contrib-quality-levels-2.2.0.tgz", @@ -36854,12 +37068,88 @@ "video.js": "^6 || ^7" } }, - "node_modules/videojs-font": { + "node_modules/videojs-contrib-quality-levels/node_modules/@videojs/http-streaming": { + "version": "2.16.3", + "resolved": "https://registry.npmjs.org/@videojs/http-streaming/-/http-streaming-2.16.3.tgz", + "integrity": "sha512-91CJv5PnFBzNBvyEjt+9cPzTK/xoVixARj2g7ZAvItA+5bx8VKdk5RxCz/PP2kdzz9W+NiDUMPkdmTsosmy69Q==", + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime": "^7.12.5", + "@videojs/vhs-utils": "3.0.5", + "aes-decrypter": "3.1.3", + "global": "^4.4.0", + "m3u8-parser": "4.8.0", + "mpd-parser": "^0.22.1", + "mux.js": "6.0.1", + "video.js": "^6 || ^7" + }, + "engines": { + "node": ">=8", + "npm": ">=5" + }, + "peerDependencies": { + "video.js": "^6 || ^7" + } + }, + "node_modules/videojs-contrib-quality-levels/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==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.5.5", + "global": "~4.4.0", + "is-function": "^1.0.1" + } + }, + "node_modules/videojs-contrib-quality-levels/node_modules/mpd-parser": { + "version": "0.22.1", + "resolved": "https://registry.npmjs.org/mpd-parser/-/mpd-parser-0.22.1.tgz", + "integrity": "sha512-fwBebvpyPUU8bOzvhX0VQZgSohncbgYwUyJJoTSNpmy7ccD2ryiCvM7oRkn/xQH5cv73/xU7rJSNCLjdGFor0Q==", + "license": "Apache-2.0", + "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/videojs-contrib-quality-levels/node_modules/video.js": { + "version": "7.21.7", + "resolved": "https://registry.npmjs.org/video.js/-/video.js-7.21.7.tgz", + "integrity": "sha512-T2s3WFAht7Zjr2OSJamND9x9Dn2O+Z5WuHGdh8jI5SYh5mkMdVTQ7vSRmA5PYpjXJ2ycch6jpMjkJEIEU2xxqw==", + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime": "^7.12.5", + "@videojs/http-streaming": "2.16.3", + "@videojs/vhs-utils": "^3.0.4", + "@videojs/xhr": "2.6.0", + "aes-decrypter": "3.1.3", + "global": "^4.4.0", + "keycode": "^2.2.0", + "m3u8-parser": "4.8.0", + "mpd-parser": "0.22.1", + "mux.js": "6.0.1", + "safe-json-parse": "4.0.0", + "videojs-font": "3.2.0", + "videojs-vtt.js": "^0.15.5" + } + }, + "node_modules/videojs-contrib-quality-levels/node_modules/videojs-font": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/videojs-font/-/videojs-font-3.2.0.tgz", "integrity": "sha512-g8vHMKK2/JGorSfqAZQUmYYNnXmfec4MLhwtEFS+mMs2IDY398GLysy6BH6K+aS1KMNu/xWZ8Sue/X/mdQPliA==", "license": "Apache-2.0" }, + "node_modules/videojs-font": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/videojs-font/-/videojs-font-4.2.0.tgz", + "integrity": "sha512-YPq+wiKoGy2/M7ccjmlvwi58z2xsykkkfNMyIg4xb7EZQQNwB71hcSsB3o75CqQV7/y5lXkXhI/rsGAS7jfEmQ==", + "license": "Apache-2.0" + }, "node_modules/videojs-hls-quality-selector": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/videojs-hls-quality-selector/-/videojs-hls-quality-selector-1.1.4.tgz", @@ -36872,6 +37162,82 @@ "videojs-contrib-quality-levels": "^2.0.9" } }, + "node_modules/videojs-hls-quality-selector/node_modules/@videojs/http-streaming": { + "version": "2.16.3", + "resolved": "https://registry.npmjs.org/@videojs/http-streaming/-/http-streaming-2.16.3.tgz", + "integrity": "sha512-91CJv5PnFBzNBvyEjt+9cPzTK/xoVixARj2g7ZAvItA+5bx8VKdk5RxCz/PP2kdzz9W+NiDUMPkdmTsosmy69Q==", + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime": "^7.12.5", + "@videojs/vhs-utils": "3.0.5", + "aes-decrypter": "3.1.3", + "global": "^4.4.0", + "m3u8-parser": "4.8.0", + "mpd-parser": "^0.22.1", + "mux.js": "6.0.1", + "video.js": "^6 || ^7" + }, + "engines": { + "node": ">=8", + "npm": ">=5" + }, + "peerDependencies": { + "video.js": "^6 || ^7" + } + }, + "node_modules/videojs-hls-quality-selector/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==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.5.5", + "global": "~4.4.0", + "is-function": "^1.0.1" + } + }, + "node_modules/videojs-hls-quality-selector/node_modules/mpd-parser": { + "version": "0.22.1", + "resolved": "https://registry.npmjs.org/mpd-parser/-/mpd-parser-0.22.1.tgz", + "integrity": "sha512-fwBebvpyPUU8bOzvhX0VQZgSohncbgYwUyJJoTSNpmy7ccD2ryiCvM7oRkn/xQH5cv73/xU7rJSNCLjdGFor0Q==", + "license": "Apache-2.0", + "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/videojs-hls-quality-selector/node_modules/video.js": { + "version": "7.21.7", + "resolved": "https://registry.npmjs.org/video.js/-/video.js-7.21.7.tgz", + "integrity": "sha512-T2s3WFAht7Zjr2OSJamND9x9Dn2O+Z5WuHGdh8jI5SYh5mkMdVTQ7vSRmA5PYpjXJ2ycch6jpMjkJEIEU2xxqw==", + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime": "^7.12.5", + "@videojs/http-streaming": "2.16.3", + "@videojs/vhs-utils": "^3.0.4", + "@videojs/xhr": "2.6.0", + "aes-decrypter": "3.1.3", + "global": "^4.4.0", + "keycode": "^2.2.0", + "m3u8-parser": "4.8.0", + "mpd-parser": "0.22.1", + "mux.js": "6.0.1", + "safe-json-parse": "4.0.0", + "videojs-font": "3.2.0", + "videojs-vtt.js": "^0.15.5" + } + }, + "node_modules/videojs-hls-quality-selector/node_modules/videojs-font": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/videojs-font/-/videojs-font-3.2.0.tgz", + "integrity": "sha512-g8vHMKK2/JGorSfqAZQUmYYNnXmfec4MLhwtEFS+mMs2IDY398GLysy6BH6K+aS1KMNu/xWZ8Sue/X/mdQPliA==", + "license": "Apache-2.0" + }, "node_modules/videojs-vtt.js": { "version": "0.15.5", "resolved": "https://registry.npmjs.org/videojs-vtt.js/-/videojs-vtt.js-0.15.5.tgz", diff --git a/package.json b/package.json index 15cd59169..28096e391 100644 --- a/package.json +++ b/package.json @@ -81,9 +81,9 @@ "rxjs": "7.8.2", "semver": "7.7.3", "uuid": "9.0.0", - "video.js": "7.20.3", - "videojs-contrib-quality-levels": "2.2.0", - "videojs-hls-quality-selector": "1.1.4", + "video.js": "8.23.4", + "videojs-contrib-quality-levels": "4.1.0", + "videojs-hls-quality-selector": "2.0.0", "zone.js": "~0.15.1" }, "devDependencies": { From 51e04ab0698f4b0123738ff7c64edf11db4b74c1 Mon Sep 17 00:00:00 2001 From: 4gray Date: Thu, 23 Oct 2025 22:55:17 +0200 Subject: [PATCH 2/2] fix(settings): fix settings issues, fix ipc commands Update channel.model to import Channel from the local interface file instead of the package namespace. This fixes an incorrect module resolution and keeps the codebase consistent with local typings. Add a new SidebarView union type ('CHANNELS' | 'PLAYLISTS') to expose possible sidebar view options for consumers of the shared interfaces. --- apps/web/src/app/app.component.ts | 16 ++-- .../video-player/video-player.component.ts | 21 ++--- apps/web/src/app/services/electron.service.ts | 6 -- .../app/services/settings-store.service.ts | 32 ++++--- .../src/app/settings/settings.component.ts | 33 ++++--- libs/m3u-state/src/lib/effects.ts | 25 +++--- .../interfaces/src/lib/channel.model.ts | 5 +- .../shared/interfaces/src/lib/ipc-commands.ts | 5 -- .../html-video-player.component.ts | 89 +++++++------------ .../lib/vjs-player/vjs-player.component.ts | 10 ++- 10 files changed, 112 insertions(+), 130 deletions(-) diff --git a/apps/web/src/app/app.component.ts b/apps/web/src/app/app.component.ts index 0fb45dadd..3a1201377 100644 --- a/apps/web/src/app/app.component.ts +++ b/apps/web/src/app/app.component.ts @@ -120,15 +120,21 @@ export class AppComponent implements OnInit, OnDestroy { .getValueFromLocalStorage(STORE_KEY.Settings) .subscribe((settings: Settings) => { if (settings && Object.keys(settings).length > 0) { - this.dataService.sendIpcEvent(SETTINGS_UPDATE, settings); + // Send settings to Electron main process + if (window.electron) { + window.electron.updateSettings(settings); + } + this.translate.use(settings.language ?? this.DEFAULT_LANG); - /* if ( + + // Fetch EPG if URLs are configured + if ( + window.electron && settings.epgUrl?.length > 0 && - settings.epgUrl?.some((u) => u !== '') && - isTauri() + settings.epgUrl?.some((u) => u !== '') ) { this.epgService.fetchEpg(settings.epgUrl); - } */ + } if (settings.theme) { this.settingsService.changeTheme(settings.theme); diff --git a/apps/web/src/app/home/video-player/video-player.component.ts b/apps/web/src/app/home/video-player/video-player.component.ts index 6017108f1..8b9e635f5 100644 --- a/apps/web/src/app/home/video-player/video-player.component.ts +++ b/apps/web/src/app/home/video-player/video-player.component.ts @@ -35,7 +35,6 @@ import { import { Observable, combineLatestWith, filter, map, switchMap } from 'rxjs'; import { DataService, PlaylistsService } from 'services'; import { - CHANNEL_SET_USER_AGENT, COMPONENT_OVERLAY_REF, Channel, ERROR, @@ -44,14 +43,12 @@ import { Playlist, STORE_KEY, Settings, + SidebarView, VideoPlayer, } from 'shared-interfaces'; import { SettingsStore } from '../../services/settings-store.service'; import { SettingsComponent } from '../../settings/settings.component'; -/** Possible sidebar view options */ -export type SidebarView = 'CHANNELS' | 'PLAYLISTS'; - @Component({ imports: [ AsyncPipe, @@ -175,15 +172,13 @@ export class VideoPlayerComponent implements OnInit { ); return this.playlistsService.getPlaylist(params['id']).pipe( map((playlist) => { - this.dataService.sendIpcEvent( - CHANNEL_SET_USER_AGENT, - playlist.userAgent - ? { - referer: 'localhost', - userAgent: playlist.userAgent, - } - : {} - ); + // Set user agent if specified on playlist level + if (playlist.userAgent) { + window.electron?.setUserAgent( + playlist.userAgent, + 'localhost' + ); + } this.store.dispatch( PlaylistActions.setChannels({ diff --git a/apps/web/src/app/services/electron.service.ts b/apps/web/src/app/services/electron.service.ts index 53a567e08..64f475e56 100644 --- a/apps/web/src/app/services/electron.service.ts +++ b/apps/web/src/app/services/electron.service.ts @@ -5,7 +5,6 @@ import { DataService } from 'services'; import { AUTO_UPDATE_PLAYLISTS, AUTO_UPDATE_PLAYLISTS_RESPONSE, - EPG_GET_PROGRAM_DONE, ERROR, Playlist, PLAYLIST_PARSE_BY_URL, @@ -92,11 +91,6 @@ export class ElectronService extends DataService { console.error('VLC launch error:', error); throw error; } - } else if (type === 'EPG_FETCH_DONE') { - window.postMessage({ - type: EPG_GET_PROGRAM_DONE, - payload, - }); } else if (type === AUTO_UPDATE_PLAYLISTS) { const data = payload as Playlist[]; const playlists = await window.electron.autoUpdatePlaylists(data); diff --git a/apps/web/src/app/services/settings-store.service.ts b/apps/web/src/app/services/settings-store.service.ts index e9735cb01..6215f28dc 100644 --- a/apps/web/src/app/services/settings-store.service.ts +++ b/apps/web/src/app/services/settings-store.service.ts @@ -36,14 +36,19 @@ export const SettingsStore = signalStore( withState(DEFAULT_SETTINGS), withMethods((store, storage = inject(StorageMap)) => ({ async loadSettings() { - const stored = await firstValueFrom( - storage.get(STORE_KEY.Settings) - ); - if (stored) { - patchState(store, { - ...DEFAULT_SETTINGS, - ...(stored as Settings), - }); + try { + const stored = await firstValueFrom( + storage.get(STORE_KEY.Settings) + ); + if (stored) { + patchState(store, { + ...DEFAULT_SETTINGS, + ...(stored as Settings), + }); + } + } catch (error) { + console.error('Failed to load settings:', error); + // Keep default settings if loading fails } }, @@ -51,9 +56,14 @@ export const SettingsStore = signalStore( patchState(store, settings); // Save the complete settings object, not just the partial update const completeSettings = this.getSettings(); - await firstValueFrom( - storage.set(STORE_KEY.Settings, completeSettings) - ); + try { + await firstValueFrom( + storage.set(STORE_KEY.Settings, completeSettings) + ); + } catch (error) { + console.error('Failed to save settings:', error); + throw error; + } }, getSettings() { diff --git a/apps/web/src/app/settings/settings.component.ts b/apps/web/src/app/settings/settings.component.ts index 2f69ea6ed..136bc4ce4 100644 --- a/apps/web/src/app/settings/settings.component.ts +++ b/apps/web/src/app/settings/settings.component.ts @@ -41,8 +41,6 @@ import { DataService, EpgService, PlaylistsService } from 'services'; import { Language, Playlist, - SET_MPV_PLAYER_PATH, - SET_VLC_PLAYER_PATH, StreamFormat, Theme, VideoPlayer, @@ -165,7 +163,9 @@ export class SettingsComponent implements OnInit { * Reads the config object from the browsers * storage (indexed db) */ - ngOnInit(): void { + async ngOnInit(): Promise { + // Wait for settings to load before setting the form + await this.settingsStore.loadSettings(); this.setSettings(); this.checkAppVersion(); } @@ -252,21 +252,18 @@ export class SettingsComponent implements OnInit { onSubmit(): void { this.settingsStore.updateSettings(this.settingsForm.value).then(() => { this.applyChangedSettings(); - /* this.dataService.sendIpcEvent( - SETTINGS_UPDATE, - this.settingsForm.value - ); */ - window.electron?.updateSettings(this.settingsForm.value); - - this.dataService.sendIpcEvent( - SET_MPV_PLAYER_PATH, - this.settingsForm.value.mpvPlayerPath - ); - - this.dataService.sendIpcEvent( - SET_VLC_PLAYER_PATH, - this.settingsForm.value.mpvPlayerPath - ); + + if (window.electron) { + window.electron.updateSettings(this.settingsForm.value); + + // Set player paths if using external players + if (this.settingsForm.value.mpvPlayerPath) { + window.electron.setMpvPlayerPath(this.settingsForm.value.mpvPlayerPath); + } + if (this.settingsForm.value.vlcPlayerPath) { + window.electron.setVlcPlayerPath(this.settingsForm.value.vlcPlayerPath); + } + } }); if (this.isDialog) { this.matDialog.closeAll(); diff --git a/libs/m3u-state/src/lib/effects.ts b/libs/m3u-state/src/lib/effects.ts index 8860543ba..b15fdd71d 100644 --- a/libs/m3u-state/src/lib/effects.ts +++ b/libs/m3u-state/src/lib/effects.ts @@ -13,10 +13,8 @@ import { tap, withLatestFrom, } from 'rxjs'; -import { DataService, PlaylistsService } from 'services'; +import { DataService, EpgService, PlaylistsService } from 'services'; import { - CHANNEL_SET_USER_AGENT, - EPG_GET_PROGRAM, OPEN_MPV_PLAYER, OPEN_VLC_PLAYER, Playlist, @@ -36,6 +34,7 @@ export class PlaylistEffects { private actions$ = inject(Actions); private playlistsService = inject(PlaylistsService); private dataService = inject(DataService); + private epgService = inject(EpgService); private router = inject(Router); private snackBar = inject(MatSnackBar); private storage = inject(StorageMap); @@ -126,15 +125,19 @@ export class PlaylistEffects { ofType(PlaylistActions.setActiveChannel), map((action) => { const { channel } = action; - this.dataService.sendIpcEvent(EPG_GET_PROGRAM, { - channel, - }); + + // Use modern EPG service to get channel programs + const channelId = channel.tvg?.id || channel.name; + if (channelId) { + this.epgService.getChannelPrograms(channelId); + } + + // Set user agent if specified on channel if (channel.http['user-agent']) { - this.dataService.sendIpcEvent(CHANNEL_SET_USER_AGENT, { - referer: channel.http.referrer, - userAgent: channel.http['user-agent'], - origin: channel.http.origin, - }); + window.electron?.setUserAgent( + channel.http['user-agent'], + channel.http.referrer + ); } firstValueFrom(this.storage.get(STORE_KEY.Settings)).then( diff --git a/libs/shared/interfaces/src/lib/channel.model.ts b/libs/shared/interfaces/src/lib/channel.model.ts index fe11cb104..9ef7f065f 100755 --- a/libs/shared/interfaces/src/lib/channel.model.ts +++ b/libs/shared/interfaces/src/lib/channel.model.ts @@ -1,4 +1,4 @@ -import { Channel } from 'shared-interfaces'; +import { Channel } from './channel.interface'; /** * Creates new channel object based on the given fields @@ -15,3 +15,6 @@ export function createChannel(params: Partial): Channel { http: params.http, } as Channel; } + +/** Possible sidebar view options */ +export type SidebarView = 'CHANNELS' | 'PLAYLISTS'; diff --git a/libs/shared/interfaces/src/lib/ipc-commands.ts b/libs/shared/interfaces/src/lib/ipc-commands.ts index 84783f203..871747f70 100644 --- a/libs/shared/interfaces/src/lib/ipc-commands.ts +++ b/libs/shared/interfaces/src/lib/ipc-commands.ts @@ -2,8 +2,6 @@ export const EPG_FETCH = 'EPG:FETCH'; export const EPG_FETCH_DONE = 'EPG:FETCH_DONE'; export const EPG_ERROR = 'EPG:ERROR'; -export const EPG_GET_PROGRAM = 'EPG:GET_PROGRAM'; -export const EPG_GET_PROGRAM_DONE = 'EPG:GET_PROGRAM_DONE'; export const EPG_GET_CHANNELS = 'EPG:GET_CHANNELS'; export const EPG_GET_CHANNELS_DONE = 'EPG:GET_CHANNELS_DONE'; export const EPG_GET_CHANNELS_BY_RANGE = 'EPG:EPG_GET_CHANNELS_BY_RANGE'; @@ -21,9 +19,6 @@ export const PLAYLIST_UPDATE_RESPONSE = 'PLAYLIST:UPDATE_RESPONSE'; export const ERROR = 'ERROR'; export const OPEN_FILE = 'OPEN_FILE'; -// Channels -export const CHANNEL_SET_USER_AGENT = 'CHANNEL:SET_USER_AGENT'; - // Views export const VIEW_SETTINGS = 'VIEW:SETTINGS'; export const VIEW_ADD_PLAYLIST = 'VIEW:PLAYLISTS'; diff --git a/libs/ui/components/src/lib/html-video-player/html-video-player.component.ts b/libs/ui/components/src/lib/html-video-player/html-video-player.component.ts index 256482b03..27270b909 100644 --- a/libs/ui/components/src/lib/html-video-player/html-video-player.component.ts +++ b/libs/ui/components/src/lib/html-video-player/html-video-player.component.ts @@ -12,7 +12,7 @@ import { import Hls from 'hls.js'; import { getExtensionFromUrl } from 'm3u-utils'; import { DataService } from 'services'; -import { Channel, CHANNEL_SET_USER_AGENT } from 'shared-interfaces'; +import { Channel } from 'shared-interfaces'; /** * This component contains the implementation of HTML5 based video player @@ -74,61 +74,38 @@ export class HtmlVideoPlayerComponent implements OnInit, OnChanges, OnDestroy { const url = channel.url + (channel.epgParams ?? ''); const extension = getExtensionFromUrl(channel.url); - // Send IPC event and handle the response - this.dataService - .sendIpcEvent(CHANNEL_SET_USER_AGENT, { - userAgent: channel.http?.['user-agent'] ?? '', - referer: channel.http?.referrer ?? '', - origin: channel.http?.origin ?? '', - }) - .then(() => { - if ( - extension !== 'mp4' && - extension !== 'mpv' && - Hls && - Hls.isSupported() - ) { - console.log( - '... switching channel to ', - channel.name, - url - ); - this.hls = new Hls(); - this.hls.attachMedia(this.videoPlayer.nativeElement); - this.hls.loadSource(url); - this.handlePlayOperation(); - } else { - console.log('Using native video player...'); - this.addSourceToVideo( - this.videoPlayer.nativeElement, - url, - 'video/mp4' - ); - this.videoPlayer.nativeElement.play(); - } - }) - .catch((error: any) => { - console.error('Error setting user agent:', error); - // Continue playback even if setting user agent fails - if ( - extension !== 'mp4' && - extension !== 'mpv' && - Hls && - Hls.isSupported() - ) { - this.hls = new Hls(); - this.hls.attachMedia(this.videoPlayer.nativeElement); - this.hls.loadSource(url); - this.handlePlayOperation(); - } else { - this.addSourceToVideo( - this.videoPlayer.nativeElement, - url, - 'video/mp4' - ); - this.videoPlayer.nativeElement.play(); - } - }); + // Set user agent if specified on channel + if (channel.http?.['user-agent']) { + window.electron?.setUserAgent( + channel.http['user-agent'], + channel.http.referrer + ); + } + + if ( + extension !== 'mp4' && + extension !== 'mpv' && + Hls && + Hls.isSupported() + ) { + console.log( + '... switching channel to ', + channel.name, + url + ); + this.hls = new Hls(); + this.hls.attachMedia(this.videoPlayer.nativeElement); + this.hls.loadSource(url); + this.handlePlayOperation(); + } else { + console.log('Using native video player...'); + this.addSourceToVideo( + this.videoPlayer.nativeElement, + url, + 'video/mp4' + ); + this.videoPlayer.nativeElement.play(); + } } } diff --git a/libs/ui/components/src/lib/vjs-player/vjs-player.component.ts b/libs/ui/components/src/lib/vjs-player/vjs-player.component.ts index e6dc50074..172c4fecc 100644 --- a/libs/ui/components/src/lib/vjs-player/vjs-player.component.ts +++ b/libs/ui/components/src/lib/vjs-player/vjs-player.component.ts @@ -12,7 +12,7 @@ import { import '@yangkghjh/videojs-aspect-ratio-panel'; import videoJs from 'video.js'; import 'videojs-contrib-quality-levels'; -import 'videojs-hls-quality-selector'; +//import 'videojs-hls-quality-selector'; /** * This component contains the implementation of video player that is based on video.js library @@ -28,9 +28,9 @@ export class VjsPlayerComponent implements OnInit, OnChanges, OnDestroy { /** DOM-element reference */ @ViewChild('target', { static: true }) target!: ElementRef; /** Options of VideoJs player */ - @Input() options!: videoJs.PlayerOptions; + @Input() options!: any; /** VideoJs object */ - player!: videoJs.Player; + player!: any; @Input() volume = 1; /** @@ -56,9 +56,11 @@ export class VjsPlayerComponent implements OnInit, OnChanges, OnDestroy { }); } ); - this.player.hlsQualitySelector({ + /* this.player.hlsQualitySelector({ displayCurrentQuality: true, }); + // this one produces warning in console + */ this.player['aspectRatioPanel'](); }