mirror of
https://github.com/Qortal/qapp-core.git
synced 2025-06-15 18:01:21 +00:00
added videojs
This commit is contained in:
parent
1ba3bfca26
commit
df67a7a2fa
539
package-lock.json
generated
539
package-lock.json
generated
@ -20,9 +20,11 @@
|
|||||||
"idb-keyval": "^6.2.2",
|
"idb-keyval": "^6.2.2",
|
||||||
"react-dropzone": "^14.3.8",
|
"react-dropzone": "^14.3.8",
|
||||||
"react-hot-toast": "^2.5.2",
|
"react-hot-toast": "^2.5.2",
|
||||||
|
"react-idle-timer": "^5.7.2",
|
||||||
"react-intersection-observer": "^9.16.0",
|
"react-intersection-observer": "^9.16.0",
|
||||||
"short-unique-id": "^5.2.0",
|
"short-unique-id": "^5.2.0",
|
||||||
"ts-key-enum": "^3.0.13",
|
"ts-key-enum": "^3.0.13",
|
||||||
|
"video.js": "^8.23.3",
|
||||||
"zustand": "^4.3.2"
|
"zustand": "^4.3.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@ -42,6 +44,7 @@
|
|||||||
"@emotion/styled": "^11.14.0",
|
"@emotion/styled": "^11.14.0",
|
||||||
"@mui/icons-material": "^7.0.1",
|
"@mui/icons-material": "^7.0.1",
|
||||||
"@mui/material": "^7.0.1",
|
"@mui/material": "^7.0.1",
|
||||||
|
"mediainfo.js": "^0.3.5",
|
||||||
"react": "^19.0.0"
|
"react": "^19.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -125,7 +128,6 @@
|
|||||||
"version": "7.27.0",
|
"version": "7.27.0",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.0.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.0.tgz",
|
||||||
"integrity": "sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==",
|
"integrity": "sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"regenerator-runtime": "^0.14.0"
|
"regenerator-runtime": "^0.14.0"
|
||||||
},
|
},
|
||||||
@ -1424,6 +1426,75 @@
|
|||||||
"integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==",
|
"integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==",
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
|
"node_modules/@videojs/http-streaming": {
|
||||||
|
"version": "3.17.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@videojs/http-streaming/-/http-streaming-3.17.0.tgz",
|
||||||
|
"integrity": "sha512-Ch1P3tvvIEezeZXyK11UfWgp4cWKX4vIhZ30baN/lRinqdbakZ5hiAI3pGjRy3d+q/Epyc8Csz5xMdKNNGYpcw==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": "^7.12.5",
|
||||||
|
"@videojs/vhs-utils": "^4.1.1",
|
||||||
|
"aes-decrypter": "^4.0.2",
|
||||||
|
"global": "^4.4.0",
|
||||||
|
"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": "^8.19.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"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": ">=8",
|
||||||
|
"npm": ">=5"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@videojs/xhr": {
|
||||||
|
"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",
|
||||||
|
"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==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"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": "^4.1.1",
|
||||||
|
"global": "^4.4.0",
|
||||||
|
"pkcs7": "^1.0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/aggregate-error": {
|
"node_modules/aggregate-error": {
|
||||||
"version": "4.0.1",
|
"version": "4.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-4.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-4.0.1.tgz",
|
||||||
@ -1680,6 +1751,100 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/cliui": {
|
||||||
|
"version": "8.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
|
||||||
|
"integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
|
||||||
|
"license": "ISC",
|
||||||
|
"peer": true,
|
||||||
|
"dependencies": {
|
||||||
|
"string-width": "^4.2.0",
|
||||||
|
"strip-ansi": "^6.0.1",
|
||||||
|
"wrap-ansi": "^7.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/cliui/node_modules/ansi-regex": {
|
||||||
|
"version": "5.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
||||||
|
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/cliui/node_modules/ansi-styles": {
|
||||||
|
"version": "4.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||||
|
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
|
"dependencies": {
|
||||||
|
"color-convert": "^2.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/cliui/node_modules/emoji-regex": {
|
||||||
|
"version": "8.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||||
|
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peer": true
|
||||||
|
},
|
||||||
|
"node_modules/cliui/node_modules/string-width": {
|
||||||
|
"version": "4.2.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
||||||
|
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
|
"dependencies": {
|
||||||
|
"emoji-regex": "^8.0.0",
|
||||||
|
"is-fullwidth-code-point": "^3.0.0",
|
||||||
|
"strip-ansi": "^6.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/cliui/node_modules/strip-ansi": {
|
||||||
|
"version": "6.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
|
||||||
|
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
|
"dependencies": {
|
||||||
|
"ansi-regex": "^5.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/cliui/node_modules/wrap-ansi": {
|
||||||
|
"version": "7.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
|
||||||
|
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
|
"dependencies": {
|
||||||
|
"ansi-styles": "^4.0.0",
|
||||||
|
"string-width": "^4.1.0",
|
||||||
|
"strip-ansi": "^6.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/clsx": {
|
"node_modules/clsx": {
|
||||||
"version": "2.1.1",
|
"version": "2.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz",
|
||||||
@ -1693,7 +1858,6 @@
|
|||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||||
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"color-name": "~1.1.4"
|
"color-name": "~1.1.4"
|
||||||
},
|
},
|
||||||
@ -1704,8 +1868,7 @@
|
|||||||
"node_modules/color-name": {
|
"node_modules/color-name": {
|
||||||
"version": "1.1.4",
|
"version": "1.1.4",
|
||||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"node_modules/commander": {
|
"node_modules/commander": {
|
||||||
"version": "4.1.1",
|
"version": "4.1.1",
|
||||||
@ -1902,6 +2065,11 @@
|
|||||||
"csstype": "^3.0.2"
|
"csstype": "^3.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"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/dompurify": {
|
"node_modules/dompurify": {
|
||||||
"version": "3.2.4",
|
"version": "3.2.4",
|
||||||
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.4.tgz",
|
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.4.tgz",
|
||||||
@ -1971,6 +2139,16 @@
|
|||||||
"@esbuild/win32-x64": "0.25.2"
|
"@esbuild/win32-x64": "0.25.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/escalade": {
|
||||||
|
"version": "3.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
|
||||||
|
"integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/escape-string-regexp": {
|
"node_modules/escape-string-regexp": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
|
||||||
@ -2009,10 +2187,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/fdir": {
|
"node_modules/fdir": {
|
||||||
"version": "6.4.3",
|
"version": "6.4.6",
|
||||||
"resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.3.tgz",
|
"resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz",
|
||||||
"integrity": "sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw==",
|
"integrity": "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"picomatch": "^3 || ^4"
|
"picomatch": "^3 || ^4"
|
||||||
},
|
},
|
||||||
@ -2090,6 +2269,16 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/get-caller-file": {
|
||||||
|
"version": "2.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
|
||||||
|
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
|
||||||
|
"license": "ISC",
|
||||||
|
"peer": true,
|
||||||
|
"engines": {
|
||||||
|
"node": "6.* || 8.* || >= 10.*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/glob": {
|
"node_modules/glob": {
|
||||||
"version": "10.4.5",
|
"version": "10.4.5",
|
||||||
"resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
|
"resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
|
||||||
@ -2122,6 +2311,16 @@
|
|||||||
"node": ">= 6"
|
"node": ">= 6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/global": {
|
||||||
|
"version": "4.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz",
|
||||||
|
"integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"min-document": "^2.19.0",
|
||||||
|
"process": "^0.11.10"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/globals": {
|
"node_modules/globals": {
|
||||||
"version": "11.12.0",
|
"version": "11.12.0",
|
||||||
"resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
|
"resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
|
||||||
@ -2329,11 +2528,16 @@
|
|||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
||||||
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
|
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
|
||||||
"dev": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"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==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/is-glob": {
|
"node_modules/is-glob": {
|
||||||
"version": "4.0.3",
|
"version": "4.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
|
||||||
@ -2480,6 +2684,33 @@
|
|||||||
"integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
|
"integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"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/mediainfo.js": {
|
||||||
|
"version": "0.3.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/mediainfo.js/-/mediainfo.js-0.3.5.tgz",
|
||||||
|
"integrity": "sha512-frLJzKOoAUC0sbPzmg9VOR+WFbNj5CarbTuOzXeH9cOl33haU/CGcyXUTWK00HPXCVS2N5eT0o0dirVxaPIOIw==",
|
||||||
|
"license": "BSD-2-Clause",
|
||||||
|
"peer": true,
|
||||||
|
"dependencies": {
|
||||||
|
"yargs": "^17.7.2"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"mediainfo.js": "dist/esm/cli.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/meow": {
|
"node_modules/meow": {
|
||||||
"version": "12.1.1",
|
"version": "12.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/meow/-/meow-12.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/meow/-/meow-12.1.1.tgz",
|
||||||
@ -2526,6 +2757,14 @@
|
|||||||
"url": "https://github.com/sponsors/jonschlinkert"
|
"url": "https://github.com/sponsors/jonschlinkert"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"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/minimatch": {
|
"node_modules/minimatch": {
|
||||||
"version": "9.0.5",
|
"version": "9.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
|
||||||
@ -2550,12 +2789,44 @@
|
|||||||
"node": ">=16 || 14 >=14.17"
|
"node": ">=16 || 14 >=14.17"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/mpd-parser": {
|
||||||
|
"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": "^4.0.0",
|
||||||
|
"@xmldom/xmldom": "^0.8.3",
|
||||||
|
"global": "^4.4.0"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"mpd-to-m3u8-json": "bin/parse.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/ms": {
|
"node_modules/ms": {
|
||||||
"version": "2.1.3",
|
"version": "2.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"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/mz": {
|
"node_modules/mz": {
|
||||||
"version": "2.7.0",
|
"version": "2.7.0",
|
||||||
"resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
|
"resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
|
||||||
@ -2567,6 +2838,27 @@
|
|||||||
"thenify-all": "^1.0.0"
|
"thenify-all": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/nanoid": {
|
||||||
|
"version": "3.3.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
|
||||||
|
"integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
|
||||||
|
"dev": true,
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/ai"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"peer": true,
|
||||||
|
"bin": {
|
||||||
|
"nanoid": "bin/nanoid.cjs"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/nested-error-stacks": {
|
"node_modules/nested-error-stacks": {
|
||||||
"version": "2.1.1",
|
"version": "2.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/nested-error-stacks/-/nested-error-stacks-2.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/nested-error-stacks/-/nested-error-stacks-2.1.1.tgz",
|
||||||
@ -2753,6 +3045,49 @@
|
|||||||
"node": ">= 6"
|
"node": ">= 6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"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==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": "^7.5.5"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"pkcs7": "bin/cli.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/postcss": {
|
||||||
|
"version": "8.5.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.4.tgz",
|
||||||
|
"integrity": "sha512-QSa9EBe+uwlGTFmHsPKokv3B/oEMQZxfqW0QqNCyhpa6mB1afzulwn8hihglqAb2pOw+BJgNlmXQ8la2VeHB7w==",
|
||||||
|
"dev": true,
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/postcss/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "tidelift",
|
||||||
|
"url": "https://tidelift.com/funding/github/npm/postcss"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/ai"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"peer": true,
|
||||||
|
"dependencies": {
|
||||||
|
"nanoid": "^3.3.11",
|
||||||
|
"picocolors": "^1.1.1",
|
||||||
|
"source-map-js": "^1.2.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^10 || ^12 || >=14"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/postcss-load-config": {
|
"node_modules/postcss-load-config": {
|
||||||
"version": "6.0.1",
|
"version": "6.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-6.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-6.0.1.tgz",
|
||||||
@ -2795,6 +3130,15 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"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==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/prop-types": {
|
"node_modules/prop-types": {
|
||||||
"version": "15.8.1",
|
"version": "15.8.1",
|
||||||
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
|
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
|
||||||
@ -2891,6 +3235,16 @@
|
|||||||
"react-dom": ">=16"
|
"react-dom": ">=16"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/react-idle-timer": {
|
||||||
|
"version": "5.7.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-idle-timer/-/react-idle-timer-5.7.2.tgz",
|
||||||
|
"integrity": "sha512-+BaPfc7XEUU5JFkwZCx6fO1bLVK+RBlFH+iY4X34urvIzZiZINP6v2orePx3E6pAztJGE7t4DzvL7if2SL/0GQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">=16",
|
||||||
|
"react-dom": ">=16"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/react-intersection-observer": {
|
"node_modules/react-intersection-observer": {
|
||||||
"version": "9.16.0",
|
"version": "9.16.0",
|
||||||
"resolved": "https://registry.npmjs.org/react-intersection-observer/-/react-intersection-observer-9.16.0.tgz",
|
"resolved": "https://registry.npmjs.org/react-intersection-observer/-/react-intersection-observer-9.16.0.tgz",
|
||||||
@ -2948,8 +3302,17 @@
|
|||||||
"node_modules/regenerator-runtime": {
|
"node_modules/regenerator-runtime": {
|
||||||
"version": "0.14.1",
|
"version": "0.14.1",
|
||||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
|
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
|
||||||
"integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==",
|
"integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw=="
|
||||||
"dev": true
|
},
|
||||||
|
"node_modules/require-directory": {
|
||||||
|
"version": "2.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
|
||||||
|
"integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"node_modules/resolve": {
|
"node_modules/resolve": {
|
||||||
"version": "1.22.10",
|
"version": "1.22.10",
|
||||||
@ -3129,6 +3492,18 @@
|
|||||||
"node": ">= 8"
|
"node": ">= 8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/source-map-js": {
|
||||||
|
"version": "1.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
|
||||||
|
"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "BSD-3-Clause",
|
||||||
|
"optional": true,
|
||||||
|
"peer": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/string-width": {
|
"node_modules/string-width": {
|
||||||
"version": "5.1.2",
|
"version": "5.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
|
||||||
@ -3293,12 +3668,13 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/tinyglobby": {
|
"node_modules/tinyglobby": {
|
||||||
"version": "0.2.12",
|
"version": "0.2.14",
|
||||||
"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.12.tgz",
|
"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz",
|
||||||
"integrity": "sha512-qkf4trmKSIiMTs/E63cxH+ojC2unam7rJ0WrauAzpT3ECNTxGRMlaXxVbfxMUC/w0LaYk6jQ4y/nGR9uBO3tww==",
|
"integrity": "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"fdir": "^6.4.3",
|
"fdir": "^6.4.4",
|
||||||
"picomatch": "^4.0.2"
|
"picomatch": "^4.0.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@ -3427,6 +3803,57 @@
|
|||||||
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/video.js": {
|
||||||
|
"version": "8.23.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/video.js/-/video.js-8.23.3.tgz",
|
||||||
|
"integrity": "sha512-Toe0VLlDZcUhiaWfcePS1OEdT3ATfktm0hk/PELfD7zUoPDHeT+cJf/wZmCy5M5eGVwtGUg25RWPCj1L/1XufA==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": "^7.12.5",
|
||||||
|
"@videojs/http-streaming": "^3.17.0",
|
||||||
|
"@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/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-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-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==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"dependencies": {
|
||||||
|
"global": "^4.3.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/webidl-conversions": {
|
"node_modules/webidl-conversions": {
|
||||||
"version": "4.0.2",
|
"version": "4.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz",
|
||||||
@ -3558,6 +3985,90 @@
|
|||||||
"cuint": "^0.2.2"
|
"cuint": "^0.2.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/y18n": {
|
||||||
|
"version": "5.0.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
|
||||||
|
"integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
|
||||||
|
"license": "ISC",
|
||||||
|
"peer": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/yargs": {
|
||||||
|
"version": "17.7.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
|
||||||
|
"integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
|
"dependencies": {
|
||||||
|
"cliui": "^8.0.1",
|
||||||
|
"escalade": "^3.1.1",
|
||||||
|
"get-caller-file": "^2.0.5",
|
||||||
|
"require-directory": "^2.1.1",
|
||||||
|
"string-width": "^4.2.3",
|
||||||
|
"y18n": "^5.0.5",
|
||||||
|
"yargs-parser": "^21.1.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/yargs-parser": {
|
||||||
|
"version": "21.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
|
||||||
|
"integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
|
||||||
|
"license": "ISC",
|
||||||
|
"peer": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/yargs/node_modules/ansi-regex": {
|
||||||
|
"version": "5.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
||||||
|
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/yargs/node_modules/emoji-regex": {
|
||||||
|
"version": "8.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||||
|
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peer": true
|
||||||
|
},
|
||||||
|
"node_modules/yargs/node_modules/string-width": {
|
||||||
|
"version": "4.2.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
||||||
|
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
|
"dependencies": {
|
||||||
|
"emoji-regex": "^8.0.0",
|
||||||
|
"is-fullwidth-code-point": "^3.0.0",
|
||||||
|
"strip-ansi": "^6.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/yargs/node_modules/strip-ansi": {
|
||||||
|
"version": "6.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
|
||||||
|
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
|
"dependencies": {
|
||||||
|
"ansi-regex": "^5.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/zustand": {
|
"node_modules/zustand": {
|
||||||
"version": "4.5.6",
|
"version": "4.5.6",
|
||||||
"resolved": "https://registry.npmjs.org/zustand/-/zustand-4.5.6.tgz",
|
"resolved": "https://registry.npmjs.org/zustand/-/zustand-4.5.6.tgz",
|
||||||
|
@ -34,9 +34,11 @@
|
|||||||
"idb-keyval": "^6.2.2",
|
"idb-keyval": "^6.2.2",
|
||||||
"react-dropzone": "^14.3.8",
|
"react-dropzone": "^14.3.8",
|
||||||
"react-hot-toast": "^2.5.2",
|
"react-hot-toast": "^2.5.2",
|
||||||
|
"react-idle-timer": "^5.7.2",
|
||||||
"react-intersection-observer": "^9.16.0",
|
"react-intersection-observer": "^9.16.0",
|
||||||
"short-unique-id": "^5.2.0",
|
"short-unique-id": "^5.2.0",
|
||||||
"ts-key-enum": "^3.0.13",
|
"ts-key-enum": "^3.0.13",
|
||||||
|
"video.js": "^8.23.3",
|
||||||
"zustand": "^4.3.2"
|
"zustand": "^4.3.2"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
@ -44,6 +46,7 @@
|
|||||||
"@emotion/styled": "^11.14.0",
|
"@emotion/styled": "^11.14.0",
|
||||||
"@mui/icons-material": "^7.0.1",
|
"@mui/icons-material": "^7.0.1",
|
||||||
"@mui/material": "^7.0.1",
|
"@mui/material": "^7.0.1",
|
||||||
|
"mediainfo.js": "^0.3.5",
|
||||||
"react": "^19.0.0"
|
"react": "^19.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
14
src/common/useIdleTimeout.ts
Normal file
14
src/common/useIdleTimeout.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import { useContext, useState } from "react";
|
||||||
|
import { useIdleTimer } from "react-idle-timer";
|
||||||
|
|
||||||
|
const useIdleTimeout = ({ onIdle, onActive, idleTime = 10_000 }: any) => {
|
||||||
|
const idleTimer = useIdleTimer({
|
||||||
|
timeout: idleTime,
|
||||||
|
onIdle: onIdle,
|
||||||
|
onActive: onActive,
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
idleTimer,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
export default useIdleTimeout;
|
@ -160,7 +160,7 @@ const addItems = useListStore((s) => s.addItems);
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
const searchIntervalRef = useRef<null | number>(null)
|
const searchIntervalRef = useRef<any>(null)
|
||||||
const lastItemTimestampRef = useRef<null | number>(null)
|
const lastItemTimestampRef = useRef<null | number>(null)
|
||||||
const stringifiedEntityParams = useMemo(()=> {
|
const stringifiedEntityParams = useMemo(()=> {
|
||||||
if(!entityParams) return null
|
if(!entityParams) return null
|
||||||
|
@ -19,6 +19,7 @@ export const LoadingVideo = ({
|
|||||||
const progress = percentLoaded;
|
const progress = percentLoaded;
|
||||||
return Number.isNaN(progress) ? "" : progress.toFixed(0) + "%";
|
return Number.isNaN(progress) ? "" : progress.toFixed(0) + "%";
|
||||||
};
|
};
|
||||||
|
if(status === 'READY') return null
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Box, IconButton, Slider, Typography } from "@mui/material";
|
import { Box, IconButton, Popper, Slider, Typography } from "@mui/material";
|
||||||
export const fontSizeExSmall = "60%";
|
export const fontSizeExSmall = "60%";
|
||||||
export const fontSizeSmall = "80%";
|
export const fontSizeSmall = "80%";
|
||||||
import AspectRatioIcon from "@mui/icons-material/AspectRatio";
|
import AspectRatioIcon from "@mui/icons-material/AspectRatio";
|
||||||
@ -13,6 +13,7 @@ import {
|
|||||||
} from "@mui/icons-material";
|
} from "@mui/icons-material";
|
||||||
import { formatTime } from "../../utils/time.js";
|
import { formatTime } from "../../utils/time.js";
|
||||||
import { CustomFontTooltip } from "./CustomFontTooltip.js";
|
import { CustomFontTooltip } from "./CustomFontTooltip.js";
|
||||||
|
import { useCallback, useEffect, useRef, useState } from "react";
|
||||||
|
|
||||||
const buttonPaddingBig = "6px";
|
const buttonPaddingBig = "6px";
|
||||||
const buttonPaddingSmall = "4px";
|
const buttonPaddingSmall = "4px";
|
||||||
@ -49,36 +50,183 @@ export const ReloadButton = ({reloadVideo, isScreenSmall}: any) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const ProgressSlider = ({progress, duration, videoRef}: any) => {
|
export const ProgressSlider = ({progress, duration, playerRef, extractFrames}: any) => {
|
||||||
const onProgressChange = async (_: any, value: number | number[]) => {
|
const sliderRef = useRef(null);
|
||||||
if (!videoRef.current) return;
|
|
||||||
videoRef.current.currentTime = value as number;
|
const [hoverX, setHoverX] = useState<number | null>(null);
|
||||||
|
const [thumbnailUrl, setThumbnailUrl] = useState<string | null>(null);
|
||||||
|
const [showDuration, setShowDuration] = useState(0)
|
||||||
|
const onProgressChange = (_: any, value: number | number[]) => {
|
||||||
|
if (!playerRef.current) return;
|
||||||
|
playerRef.current.currentTime(value as number);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const THUMBNAIL_DEBOUNCE = 500;
|
||||||
|
const THUMBNAIL_MIN_DIFF = 10;
|
||||||
|
|
||||||
|
const lastRequestedTimeRef = useRef<number | null>(null);
|
||||||
|
const debounceTimeoutRef = useRef<any>(null);
|
||||||
|
const previousBlobUrlRef = useRef<string | null>(null);
|
||||||
|
|
||||||
|
const debouncedExtract = useCallback(
|
||||||
|
(time: number, clientX: number) => {
|
||||||
|
const last = lastRequestedTimeRef.current;
|
||||||
|
console.log('hello101')
|
||||||
|
console.log('last', last)
|
||||||
|
if (last !== null && Math.abs(time - last) < THUMBNAIL_MIN_DIFF) return;
|
||||||
|
lastRequestedTimeRef.current = time;
|
||||||
|
console.log('hello102')
|
||||||
|
|
||||||
|
extractFrames(time).then((blobUrl: string | null) => {
|
||||||
|
console.log('blobUrl', blobUrl)
|
||||||
|
if (!blobUrl) return;
|
||||||
|
|
||||||
|
// Clean up previous blob URL
|
||||||
|
if (previousBlobUrlRef.current) {
|
||||||
|
URL.revokeObjectURL(previousBlobUrlRef.current);
|
||||||
|
}
|
||||||
|
|
||||||
|
previousBlobUrlRef.current = blobUrl;
|
||||||
|
setThumbnailUrl(blobUrl);
|
||||||
|
|
||||||
|
});
|
||||||
|
},
|
||||||
|
[extractFrames]
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleMouseMove = (e: React.MouseEvent) => {
|
||||||
|
const slider = sliderRef.current;
|
||||||
|
if (!slider) return;
|
||||||
|
|
||||||
|
const rect = slider.getBoundingClientRect();
|
||||||
|
const x = e.clientX - rect.left;
|
||||||
|
const percent = x / rect.width;
|
||||||
|
const time = Math.min(Math.max(0, percent * duration), duration);
|
||||||
|
console.log('hello100')
|
||||||
|
setHoverX(e.clientX);
|
||||||
|
|
||||||
|
setShowDuration(time)
|
||||||
|
if (debounceTimeoutRef.current) clearTimeout(debounceTimeoutRef.current);
|
||||||
|
|
||||||
|
// debounceTimeoutRef.current = setTimeout(() => {
|
||||||
|
// debouncedExtract(time, e.clientX);
|
||||||
|
// }, THUMBNAIL_DEBOUNCE);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleMouseLeave = () => {
|
||||||
|
lastRequestedTimeRef.current = null;
|
||||||
|
setThumbnailUrl(null);
|
||||||
|
setHoverX(null);
|
||||||
|
if (debounceTimeoutRef.current) clearTimeout(debounceTimeoutRef.current);
|
||||||
|
|
||||||
|
if (previousBlobUrlRef.current) {
|
||||||
|
URL.revokeObjectURL(previousBlobUrlRef.current);
|
||||||
|
previousBlobUrlRef.current = null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Clean up on unmount
|
||||||
|
useEffect(() => {
|
||||||
|
return () => {
|
||||||
|
if (previousBlobUrlRef.current) {
|
||||||
|
URL.revokeObjectURL(previousBlobUrlRef.current);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const hoverAnchorRef = useRef<HTMLDivElement | null>(null);
|
||||||
|
if(hoverX){
|
||||||
|
console.log('thumbnailUrl', thumbnailUrl, hoverX)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<Box position="relative" sx={{
|
||||||
|
width: '100%',
|
||||||
|
padding: '0px 10px'
|
||||||
|
}}>
|
||||||
|
<Box
|
||||||
|
ref={hoverAnchorRef}
|
||||||
|
sx={{
|
||||||
|
position: 'absolute',
|
||||||
|
left: hoverX ?? -9999,
|
||||||
|
top: 0,
|
||||||
|
width: '1px',
|
||||||
|
height: '1px',
|
||||||
|
pointerEvents: 'none',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
<Slider
|
<Slider
|
||||||
|
ref={sliderRef}
|
||||||
|
onMouseMove={handleMouseMove}
|
||||||
|
onMouseLeave={handleMouseLeave}
|
||||||
value={progress}
|
value={progress}
|
||||||
onChange={onProgressChange}
|
onChange={onProgressChange}
|
||||||
min={0}
|
min={0}
|
||||||
max={duration || 100}
|
max={duration || 100}
|
||||||
step={0.1}
|
step={0.1}
|
||||||
sx={{
|
sx={{
|
||||||
position: "absolute",
|
|
||||||
bottom: "42px",
|
|
||||||
color: "#00abff",
|
color: "#00abff",
|
||||||
padding: "0px",
|
padding: "0px",
|
||||||
// prevents the slider from jumping up 20px in certain mobile conditions
|
borderRadius: '0px',
|
||||||
|
height: '0px',
|
||||||
"@media (pointer: coarse)": { padding: "0px" },
|
"@media (pointer: coarse)": { padding: "0px" },
|
||||||
|
|
||||||
"& .MuiSlider-thumb": {
|
"& .MuiSlider-thumb": {
|
||||||
backgroundColor: "#fff",
|
backgroundColor: "red",
|
||||||
width: "16px",
|
width: "14px",
|
||||||
height: "16px",
|
height: "14px",
|
||||||
},
|
},
|
||||||
"& .MuiSlider-thumb::after": { width: "20px", height: "20px" },
|
"& .MuiSlider-thumb::after": { width: "14px", height: "14px", backgroundColor: 'red' },
|
||||||
"& .MuiSlider-rail": { opacity: 0.5, height: "6px" },
|
"& .MuiSlider-rail": { opacity: 0.5, height: "6px", backgroundColor: '#73859f80' },
|
||||||
"& .MuiSlider-track": { height: "6px", border: "0px" },
|
"& .MuiSlider-track": { height: "6px", border: "0px" , backgroundColor: 'red'},
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
{hoverX !== null && (
|
||||||
|
<Popper
|
||||||
|
open
|
||||||
|
anchorEl={hoverAnchorRef.current} placement="top"
|
||||||
|
|
||||||
|
|
||||||
|
disablePortal
|
||||||
|
modifiers={[{ name: "offset", options: { offset: [-20, 0] } }]}
|
||||||
|
>
|
||||||
|
<Box sx={{
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
alignItems: 'center'
|
||||||
|
}}>
|
||||||
|
{/* <Box
|
||||||
|
sx={{
|
||||||
|
width: 250,
|
||||||
|
height: 125,
|
||||||
|
backgroundColor: "black",
|
||||||
|
border: "1px solid white",
|
||||||
|
overflow: "hidden",
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
borderRadius: '7px',
|
||||||
|
background: '#444444',
|
||||||
|
padding: '2px'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
|
||||||
|
<img
|
||||||
|
src={thumbnailUrl}
|
||||||
|
alt="preview"
|
||||||
|
style={{ width: "100%", height: "100%", objectFit: "cover" }}
|
||||||
|
/>
|
||||||
|
</Box> */}
|
||||||
|
<Typography sx={{
|
||||||
|
fontSize: '0.8rom',
|
||||||
|
textShadow: '0 0 5px rgba(0, 0, 0, 0.7)'
|
||||||
|
|
||||||
|
}}>{formatTime(showDuration)}</Typography>
|
||||||
|
</Box>
|
||||||
|
</Popper>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -26,9 +26,15 @@ interface VideoControlsBarProps {
|
|||||||
reloadVideo: ()=> void;
|
reloadVideo: ()=> void;
|
||||||
volume: number
|
volume: number
|
||||||
onVolumeChange: (_: any, val: number)=> void
|
onVolumeChange: (_: any, val: number)=> void
|
||||||
|
toggleFullscreen: ()=> void
|
||||||
|
extractFrames: (time: number)=> void
|
||||||
|
showControls: boolean;
|
||||||
|
showControlsFullScreen: boolean;
|
||||||
|
isFullScreen: boolean;
|
||||||
|
playerRef: any
|
||||||
}
|
}
|
||||||
|
|
||||||
export const VideoControlsBar = ({reloadVideo, onVolumeChange, volume, isPlaying, canPlay, isScreenSmall, controlsHeight, videoRef, duration, progress, togglePlay}: VideoControlsBarProps) => {
|
export const VideoControlsBar = ({showControls, isFullScreen, showControlsFullScreen, reloadVideo, onVolumeChange, volume, isPlaying, canPlay, isScreenSmall, controlsHeight, videoRef, playerRef, duration, progress, togglePlay, toggleFullscreen, extractFrames}: VideoControlsBarProps) => {
|
||||||
|
|
||||||
const showMobileControls = isScreenSmall && canPlay;
|
const showMobileControls = isScreenSmall && canPlay;
|
||||||
|
|
||||||
@ -39,23 +45,46 @@ export const VideoControlsBar = ({reloadVideo, onVolumeChange, volume, isPlaying
|
|||||||
height: controlsHeight,
|
height: controlsHeight,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let additionalStyles: React.CSSProperties = {}
|
||||||
|
if(isFullScreen && showControlsFullScreen){
|
||||||
|
additionalStyles = {
|
||||||
|
opacity: 1,
|
||||||
|
position: 'fixed',
|
||||||
|
bottom: 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ControlsContainer
|
<ControlsContainer
|
||||||
style={{
|
style={{
|
||||||
padding: "0px",
|
padding: "0px",
|
||||||
height: controlsHeight,
|
opacity: showControls ? 1 : 0,
|
||||||
|
pointerEvents: showControls ? 'auto' : 'none',
|
||||||
|
transition: 'opacity 0.4s ease-in-out',
|
||||||
|
// ...additionalStyles
|
||||||
|
// height: controlsHeight,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{showMobileControls ? (
|
{showMobileControls ? (
|
||||||
null
|
null
|
||||||
// <MobileControlsBar />
|
// <MobileControlsBar />
|
||||||
) : canPlay ? (
|
) : canPlay ? (
|
||||||
<>
|
<Box sx={{
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
width: '100%'
|
||||||
|
}}>
|
||||||
|
|
||||||
|
<ProgressSlider extractFrames={extractFrames} playerRef={playerRef} progress={progress} duration={duration} />
|
||||||
|
<Box sx={{
|
||||||
|
width: '100%',
|
||||||
|
display: 'flex'
|
||||||
|
}}>
|
||||||
<Box sx={controlGroupSX}>
|
<Box sx={controlGroupSX}>
|
||||||
<PlayButton isPlaying={isPlaying} togglePlay={togglePlay}/>
|
<PlayButton isPlaying={isPlaying} togglePlay={togglePlay}/>
|
||||||
<ReloadButton reloadVideo={reloadVideo} />
|
<ReloadButton reloadVideo={reloadVideo} />
|
||||||
|
|
||||||
<ProgressSlider videoRef={videoRef} progress={progress} duration={duration} />
|
|
||||||
|
|
||||||
<VolumeControl onVolumeChange={onVolumeChange} volume={volume} sliderWidth={"100px"} />
|
<VolumeControl onVolumeChange={onVolumeChange} volume={volume} sliderWidth={"100px"} />
|
||||||
<VideoTime videoRef={videoRef} progress={progress}/>
|
<VideoTime videoRef={videoRef} progress={progress}/>
|
||||||
@ -65,9 +94,10 @@ export const VideoControlsBar = ({reloadVideo, onVolumeChange, volume, isPlaying
|
|||||||
<PlaybackRate />
|
<PlaybackRate />
|
||||||
<ObjectFitButton />
|
<ObjectFitButton />
|
||||||
<PictureInPictureButton />
|
<PictureInPictureButton />
|
||||||
<FullscreenButton />
|
<FullscreenButton toggleFullscreen={toggleFullscreen} />
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
</>
|
|
||||||
) : null}
|
) : null}
|
||||||
</ControlsContainer>
|
</ControlsContainer>
|
||||||
);
|
);
|
||||||
|
@ -11,19 +11,33 @@ export const VideoContainer = styled(Box)(({ theme }) => ({
|
|||||||
height: "100%",
|
height: "100%",
|
||||||
margin: 0,
|
margin: 0,
|
||||||
padding: 0,
|
padding: 0,
|
||||||
|
borderRadius: '12px',
|
||||||
|
overflow: 'hidden',
|
||||||
"&:focus": { outline: "none" },
|
"&:focus": { outline: "none" },
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const VideoElement = styled("video")(({ theme }) => ({
|
export const VideoElement = styled("video")(({ theme }) => ({
|
||||||
width: "100%",
|
position: 'absolute',
|
||||||
|
top: 0,
|
||||||
|
bottom: 0,
|
||||||
|
right: 0,
|
||||||
|
left: 0,
|
||||||
background: "rgb(33, 33, 33)",
|
background: "rgb(33, 33, 33)",
|
||||||
"&:focus": { outline: "none" },
|
"&:focus": { outline: "none" },
|
||||||
|
"&::-webkit-media-controls": {
|
||||||
|
display:"none !important"
|
||||||
|
},
|
||||||
|
"&:fullscreen": {
|
||||||
|
paddingBottom: '50px'
|
||||||
|
}
|
||||||
}));
|
}));
|
||||||
//1075 x 604
|
//1075 x 604
|
||||||
export const ControlsContainer = styled(Box)`
|
export const ControlsContainer = styled(Box)`
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
background-color: rgba(0, 0, 0, 0.6);
|
background-image: linear-gradient(0deg,#000,#0000);
|
||||||
`;
|
`;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Ref, RefObject, useCallback, useEffect, useMemo, useRef, useState } from "react";
|
import { ReactEventHandler, Ref, RefObject, useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||||
import { QortalGetMetadata } from "../../types/interfaces/resources";
|
import { QortalGetMetadata } from "../../types/interfaces/resources";
|
||||||
import { VideoContainer, VideoElement } from "./VideoPlayer-styles";
|
import { VideoContainer, VideoElement } from "./VideoPlayer-styles";
|
||||||
import { useVideoPlayerHotKeys } from "./useVideoPlayerHotKeys";
|
import { useVideoPlayerHotKeys } from "./useVideoPlayerHotKeys";
|
||||||
@ -6,14 +6,19 @@ import { useProgressStore, useVideoStore } from "../../state/video";
|
|||||||
import { useVideoPlayerController } from "./useVideoPlayerController";
|
import { useVideoPlayerController } from "./useVideoPlayerController";
|
||||||
import { LoadingVideo } from "./LoadingVideo";
|
import { LoadingVideo } from "./LoadingVideo";
|
||||||
import { VideoControlsBar } from "./VideoControlsBar";
|
import { VideoControlsBar } from "./VideoControlsBar";
|
||||||
|
import videojs from 'video.js';
|
||||||
|
import 'video.js/dist/video-js.css';
|
||||||
|
|
||||||
|
import Player from "video.js/dist/types/player";
|
||||||
|
|
||||||
|
|
||||||
type StretchVideoType = "contain" | "fill" | "cover" | "none" | "scale-down";
|
type StretchVideoType = "contain" | "fill" | "cover" | "none" | "scale-down";
|
||||||
|
|
||||||
export interface VideoPlayerProps {
|
|
||||||
|
interface VideoPlayerProps {
|
||||||
qortalVideoResource: QortalGetMetadata;
|
qortalVideoResource: QortalGetMetadata;
|
||||||
videoRef: Ref<HTMLVideoElement>;
|
videoRef: Ref<HTMLVideoElement>;
|
||||||
retryAttempts?: number;
|
retryAttempts?: number;
|
||||||
showControls?: boolean;
|
|
||||||
poster?: string;
|
poster?: string;
|
||||||
autoPlay?: boolean;
|
autoPlay?: boolean;
|
||||||
onEnded?: (e: React.SyntheticEvent<HTMLVideoElement, Event>) => void;
|
onEnded?: (e: React.SyntheticEvent<HTMLVideoElement, Event>) => void;
|
||||||
@ -27,7 +32,6 @@ export const VideoPlayer = ({
|
|||||||
videoRef,
|
videoRef,
|
||||||
qortalVideoResource,
|
qortalVideoResource,
|
||||||
retryAttempts,
|
retryAttempts,
|
||||||
showControls,
|
|
||||||
poster,
|
poster,
|
||||||
autoPlay,
|
autoPlay,
|
||||||
onEnded,
|
onEnded,
|
||||||
@ -39,14 +43,15 @@ export const VideoPlayer = ({
|
|||||||
volume: state.playbackSettings.volume,
|
volume: state.playbackSettings.volume,
|
||||||
setVolume: state.setVolume,
|
setVolume: state.setVolume,
|
||||||
}));
|
}));
|
||||||
|
const playerRef = useRef<Player | null>(null);
|
||||||
|
|
||||||
|
const [videoCodec, setVideoCodec] = useState<null | false | string>(null)
|
||||||
const [isMuted, setIsMuted] = useState(false);
|
const [isMuted, setIsMuted] = useState(false);
|
||||||
const { setProgress } = useProgressStore();
|
const { setProgress } = useProgressStore();
|
||||||
const [localProgress, setLocalProgress] = useState(0)
|
const [localProgress, setLocalProgress] = useState(0)
|
||||||
const [duration, setDuration] = useState(0)
|
const [duration, setDuration] = useState(0)
|
||||||
const [isLoading, setIsLoading] = useState(true);
|
const [isLoading, setIsLoading] = useState(true);
|
||||||
|
const [showControls, setShowControls] = useState(false)
|
||||||
|
|
||||||
const {
|
const {
|
||||||
reloadVideo,
|
reloadVideo,
|
||||||
togglePlay,
|
togglePlay,
|
||||||
@ -54,8 +59,6 @@ export const VideoPlayer = ({
|
|||||||
increaseSpeed,
|
increaseSpeed,
|
||||||
decreaseSpeed,
|
decreaseSpeed,
|
||||||
toggleMute,
|
toggleMute,
|
||||||
showControlsFullScreen,
|
|
||||||
setShowControlsFullScreen,
|
|
||||||
isFullscreen,
|
isFullscreen,
|
||||||
toggleObjectFit,
|
toggleObjectFit,
|
||||||
controlsHeight,
|
controlsHeight,
|
||||||
@ -68,7 +71,8 @@ export const VideoPlayer = ({
|
|||||||
startPlay,
|
startPlay,
|
||||||
setProgressAbsolute,
|
setProgressAbsolute,
|
||||||
setAlwaysShowControls,
|
setAlwaysShowControls,
|
||||||
status, percentLoaded
|
status, percentLoaded,
|
||||||
|
showControlsFullScreen
|
||||||
} = useVideoPlayerController({
|
} = useVideoPlayerController({
|
||||||
autoPlay,
|
autoPlay,
|
||||||
videoRef,
|
videoRef,
|
||||||
@ -105,6 +109,13 @@ export const VideoPlayer = ({
|
|||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const videoLocation = useMemo(() => {
|
const videoLocation = useMemo(() => {
|
||||||
if (!qortalVideoResource) return null;
|
if (!qortalVideoResource) return null;
|
||||||
return `${qortalVideoResource.service}-${qortalVideoResource.name}-${qortalVideoResource.identifier}`;
|
return `${qortalVideoResource.service}-${qortalVideoResource.name}-${qortalVideoResource.identifier}`;
|
||||||
@ -145,29 +156,26 @@ export const VideoPlayer = ({
|
|||||||
[setIsMuted, setVolume]
|
[setIsMuted, setVolume]
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleMouseEnter = useCallback(() => {
|
|
||||||
setShowControlsFullScreen(true);
|
|
||||||
}, [setShowControlsFullScreen]);
|
|
||||||
|
|
||||||
const handleMouseLeave = useCallback(() => {
|
|
||||||
setShowControlsFullScreen(false);
|
|
||||||
}, [setShowControlsFullScreen]);
|
|
||||||
|
|
||||||
const videoStylesContainer = useMemo(() => {
|
const videoStylesContainer = useMemo(() => {
|
||||||
return {
|
return {
|
||||||
cursor: !showControlsFullScreen && isFullscreen ? "none" : "auto",
|
cursor: !showControls && isFullscreen ? "none" : "auto",
|
||||||
...videoStyles?.videoContainer,
|
...videoStyles?.videoContainer,
|
||||||
};
|
};
|
||||||
}, [showControlsFullScreen, isFullscreen]);
|
}, [showControls, isFullscreen]);
|
||||||
|
|
||||||
|
console.log('isFullscreen', isFullscreen, showControlsFullScreen)
|
||||||
|
|
||||||
const videoStylesVideo = useMemo(() => {
|
const videoStylesVideo = useMemo(() => {
|
||||||
return {
|
return {
|
||||||
...videoStyles?.video,
|
...videoStyles?.video,
|
||||||
objectFit: videoObjectFit,
|
objectFit: videoObjectFit,
|
||||||
backgroundColor: "#000000",
|
backgroundColor: "#000000",
|
||||||
height: isFullscreen && showControls ? "calc(100vh - 40px)" : "100%",
|
height: isFullscreen ? "calc(100vh - 40px)" : "100%",
|
||||||
|
width: '100%'
|
||||||
};
|
};
|
||||||
}, [videoObjectFit, showControls, isFullscreen]);
|
}, [videoObjectFit, isFullscreen]);
|
||||||
|
|
||||||
const handleEnded = useCallback(
|
const handleEnded = useCallback(
|
||||||
(e: React.SyntheticEvent<HTMLVideoElement, Event>) => {
|
(e: React.SyntheticEvent<HTMLVideoElement, Event>) => {
|
||||||
@ -201,20 +209,156 @@ export const VideoPlayer = ({
|
|||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const enterFullscreen = () => {
|
||||||
|
const ref = containerRef?.current as any;
|
||||||
|
console.log('refffff', ref)
|
||||||
|
if (!ref) return;
|
||||||
|
|
||||||
|
if (ref.requestFullscreen && !isFullscreen) {
|
||||||
|
console.log('requset ')
|
||||||
|
ref.requestFullscreen();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
const exitFullscreen = () => {
|
||||||
|
if (isFullscreen) document.exitFullscreen();
|
||||||
|
};
|
||||||
|
|
||||||
|
const toggleFullscreen = () => {
|
||||||
|
isFullscreen ? exitFullscreen() : enterFullscreen();
|
||||||
|
};
|
||||||
|
|
||||||
|
const canvasRef = useRef(null)
|
||||||
|
const videoRefForCanvas = useRef<any>(null)
|
||||||
|
const extractFrames = useCallback(async (time: number): Promise<string | null> => {
|
||||||
|
const video = videoRefForCanvas?.current;
|
||||||
|
const canvas: any = canvasRef.current;
|
||||||
|
|
||||||
|
if (!video || !canvas) return null;
|
||||||
|
|
||||||
|
// Avoid unnecessary resize if already correct
|
||||||
|
if (canvas.width !== video.videoWidth || canvas.height !== video.videoHeight) {
|
||||||
|
canvas.width = video.videoWidth;
|
||||||
|
canvas.height = video.videoHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
const context = canvas.getContext("2d");
|
||||||
|
if (!context) return null;
|
||||||
|
|
||||||
|
// If video is already near the correct time, don't seek again
|
||||||
|
const threshold = 0.01; // 10ms threshold
|
||||||
|
if (Math.abs(video.currentTime - time) > threshold) {
|
||||||
|
await new Promise<void>((resolve) => {
|
||||||
|
const onSeeked = () => resolve();
|
||||||
|
video.addEventListener("seeked", onSeeked, { once: true });
|
||||||
|
video.currentTime = time;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
context.drawImage(video, 0, 0, canvas.width, canvas.height);
|
||||||
|
|
||||||
|
// Use a faster method for image export (optional tradeoff)
|
||||||
|
const blob = await new Promise<Blob | null>((resolve) => {
|
||||||
|
canvas.toBlob((blob: any) => resolve(blob), "image/webp", 0.7);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!blob) return null;
|
||||||
|
|
||||||
|
return URL.createObjectURL(blob);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
|
||||||
|
const hideTimeout = useRef<any>(null);
|
||||||
|
|
||||||
|
|
||||||
|
const resetHideTimer = () => {
|
||||||
|
setShowControls(true);
|
||||||
|
if (hideTimeout.current) clearTimeout(hideTimeout.current);
|
||||||
|
hideTimeout.current = setTimeout(() => {
|
||||||
|
setShowControls(false);
|
||||||
|
}, 2500); // 3s of inactivity
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleMouseMove = () => {
|
||||||
|
resetHideTimer();
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
resetHideTimer(); // initial show
|
||||||
|
return () => {
|
||||||
|
if (hideTimeout.current) clearTimeout(hideTimeout.current);
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const handleMouseLeave = useCallback(() => {
|
||||||
|
setShowControls(false);
|
||||||
|
if (hideTimeout.current) clearTimeout(hideTimeout.current);
|
||||||
|
}, [setShowControls]);
|
||||||
|
|
||||||
|
const onLoadedMetadata= (e: any)=> {
|
||||||
|
console.log('eeeeeeeeeee', e)
|
||||||
|
const ref = videoRef as any;
|
||||||
|
if (!ref.current) return;
|
||||||
|
console.log('datataa', ref.current.audioTracks , // List of available audio tracks
|
||||||
|
ref.current.textTracks , // Subtitles/closed captions
|
||||||
|
ref.current.videoTracks )
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if(!resourceUrl || !isReady) return
|
||||||
|
const options = {
|
||||||
|
autoplay: true,
|
||||||
|
controls: false,
|
||||||
|
responsive: true,
|
||||||
|
fluid: true,
|
||||||
|
poster: startPlay ? "" : poster,
|
||||||
|
sources: [
|
||||||
|
{
|
||||||
|
src: resourceUrl,
|
||||||
|
type: 'video/mp4'
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
const ref = videoRef as any;
|
||||||
|
if (!ref.current) return;
|
||||||
|
// Only initialize once
|
||||||
|
if (!playerRef.current && ref.current) {
|
||||||
|
playerRef.current = videojs(ref.current, options, () => {
|
||||||
|
playerRef.current?.poster('');
|
||||||
|
if (playerRef.current){
|
||||||
|
playerRef.current.play()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
if (playerRef.current) {
|
||||||
|
playerRef.current.dispose();
|
||||||
|
playerRef.current = null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}, [isReady, resourceUrl]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<VideoContainer
|
<VideoContainer
|
||||||
tabIndex={0}
|
tabIndex={0}
|
||||||
style={videoStylesContainer}
|
style={videoStylesContainer}
|
||||||
onMouseEnter={handleMouseEnter}
|
onMouseMove={handleMouseMove}
|
||||||
onMouseLeave={handleMouseLeave}
|
onMouseLeave={handleMouseLeave}
|
||||||
ref={containerRef}
|
ref={containerRef}
|
||||||
>
|
>
|
||||||
<LoadingVideo togglePlay={togglePlay} isReady={isReady} status={status} percentLoaded={percentLoaded} isLoading={isLoading} />
|
<LoadingVideo togglePlay={togglePlay} isReady={isReady} status={status} percentLoaded={percentLoaded} isLoading={isLoading} />
|
||||||
<VideoElement
|
<VideoElement
|
||||||
id={qortalVideoResource?.identifier}
|
|
||||||
ref={videoRef}
|
ref={videoRef}
|
||||||
tabIndex={0}
|
tabIndex={0}
|
||||||
src={isReady && startPlay ? resourceUrl || undefined : undefined}
|
className="video-js"
|
||||||
|
|
||||||
|
// src={isReady && startPlay ? resourceUrl || undefined : undefined}
|
||||||
poster={startPlay ? "" : poster}
|
poster={startPlay ? "" : poster}
|
||||||
onTimeUpdate={updateProgress}
|
onTimeUpdate={updateProgress}
|
||||||
autoPlay={autoPlay}
|
autoPlay={autoPlay}
|
||||||
@ -226,8 +370,18 @@ export const VideoPlayer = ({
|
|||||||
onPlay={onPlay}
|
onPlay={onPlay}
|
||||||
onPause={onPause}
|
onPause={onPause}
|
||||||
onVolumeChange={onVolumeChangeHandler}
|
onVolumeChange={onVolumeChangeHandler}
|
||||||
|
controls={false}
|
||||||
|
onLoadedMetadata={onLoadedMetadata}
|
||||||
|
|
||||||
/>
|
/>
|
||||||
<VideoControlsBar onVolumeChange={onVolumeChange} volume={volume} togglePlay={togglePlay} reloadVideo={hotkeyHandlers.reloadVideo} isPlaying={isPlaying} canPlay={true} isScreenSmall={false} controlsHeight={controlsHeight} videoRef={videoRef} duration={duration} progress={localProgress} />
|
<canvas ref={canvasRef} style={{ display: "none" }}></canvas>
|
||||||
|
<video src={isReady && startPlay ? resourceUrl || undefined : undefined} ref={videoRefForCanvas} style={{ display: "none" }}></video>
|
||||||
|
|
||||||
|
{isReady && (
|
||||||
|
<VideoControlsBar playerRef={playerRef} isFullScreen={isFullscreen} showControlsFullScreen={showControlsFullScreen} showControls={showControls} extractFrames={extractFrames} toggleFullscreen={toggleFullscreen} onVolumeChange={onVolumeChange} volume={volume} togglePlay={togglePlay} reloadVideo={hotkeyHandlers.reloadVideo} isPlaying={isPlaying} canPlay={true} isScreenSmall={false} controlsHeight={controlsHeight} videoRef={videoRef} duration={duration} progress={localProgress} />
|
||||||
|
)}
|
||||||
|
|
||||||
|
|
||||||
</VideoContainer>
|
</VideoContainer>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -8,11 +8,10 @@ import {
|
|||||||
useRef,
|
useRef,
|
||||||
useImperativeHandle,
|
useImperativeHandle,
|
||||||
} from "react";
|
} from "react";
|
||||||
import { Key } from "ts-key-enum";
|
|
||||||
import { useProgressStore, useVideoStore } from "../../state/video";
|
import { useProgressStore, useVideoStore } from "../../state/video";
|
||||||
import { VideoPlayerProps } from "./VideoPlayer";
|
|
||||||
import { QortalGetMetadata } from "../../types/interfaces/resources";
|
import { QortalGetMetadata } from "../../types/interfaces/resources";
|
||||||
import { useResourceStatus } from "../../hooks/useResourceStatus";
|
import { useResourceStatus } from "../../hooks/useResourceStatus";
|
||||||
|
import useIdleTimeout from "../../common/useIdleTimeout";
|
||||||
|
|
||||||
const controlsHeight = "42px";
|
const controlsHeight = "42px";
|
||||||
const minSpeed = 0.25;
|
const minSpeed = 0.25;
|
||||||
@ -30,10 +29,10 @@ export const useVideoPlayerController = (props: UseVideoControls) => {
|
|||||||
const { autoPlay, videoRef, qortalVideoResource, retryAttempts } = props;
|
const { autoPlay, videoRef, qortalVideoResource, retryAttempts } = props;
|
||||||
|
|
||||||
const [isFullscreen, setIsFullscreen] = useState(false);
|
const [isFullscreen, setIsFullscreen] = useState(false);
|
||||||
|
const [showControlsFullScreen, setShowControlsFullScreen] = useState(false)
|
||||||
const [videoObjectFit, setVideoObjectFit] = useState<"contain" | "fill">(
|
const [videoObjectFit, setVideoObjectFit] = useState<"contain" | "fill">(
|
||||||
"contain"
|
"contain"
|
||||||
);
|
);
|
||||||
const [showControlsFullScreen, setShowControlsFullScreen] = useState(true);
|
|
||||||
const [alwaysShowControls, setAlwaysShowControls] = useState(false);
|
const [alwaysShowControls, setAlwaysShowControls] = useState(false);
|
||||||
const [startPlay, setStartPlay] = useState(false);
|
const [startPlay, setStartPlay] = useState(false);
|
||||||
const [startedFetch, setStartedFetch] = useState(false);
|
const [startedFetch, setStartedFetch] = useState(false);
|
||||||
@ -47,6 +46,12 @@ export const useVideoPlayerController = (props: UseVideoControls) => {
|
|||||||
retryAttempts,
|
retryAttempts,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const idleTime = 5000; // Time in milliseconds
|
||||||
|
useIdleTimeout({
|
||||||
|
onIdle: () => (setShowControlsFullScreen(false)),
|
||||||
|
onActive: () => (setShowControlsFullScreen(true)),
|
||||||
|
idleTime,
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
const videoLocation = useMemo(() => {
|
const videoLocation = useMemo(() => {
|
||||||
@ -213,7 +218,6 @@ export const useVideoPlayerController = (props: UseVideoControls) => {
|
|||||||
increaseSpeed,
|
increaseSpeed,
|
||||||
decreaseSpeed,
|
decreaseSpeed,
|
||||||
toggleMute,
|
toggleMute,
|
||||||
showControlsFullScreen,
|
|
||||||
isFullscreen,
|
isFullscreen,
|
||||||
toggleObjectFit,
|
toggleObjectFit,
|
||||||
controlsHeight,
|
controlsHeight,
|
||||||
@ -221,12 +225,11 @@ export const useVideoPlayerController = (props: UseVideoControls) => {
|
|||||||
toggleAlwaysShowControls,
|
toggleAlwaysShowControls,
|
||||||
changeVolume,
|
changeVolume,
|
||||||
setProgressAbsolute,
|
setProgressAbsolute,
|
||||||
setShowControlsFullScreen,
|
|
||||||
setAlwaysShowControls,
|
setAlwaysShowControls,
|
||||||
startedFetch,
|
startedFetch,
|
||||||
isReady,
|
isReady,
|
||||||
resourceUrl,
|
resourceUrl,
|
||||||
startPlay,
|
startPlay,
|
||||||
status, percentLoaded
|
status, percentLoaded, showControlsFullScreen
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import { useEffect, useCallback } from 'react';
|
import { useEffect, useCallback } from 'react';
|
||||||
import { Key } from 'ts-key-enum';
|
|
||||||
|
|
||||||
interface UseVideoControls {
|
interface UseVideoControls {
|
||||||
reloadVideo: () => void;
|
reloadVideo: () => void;
|
||||||
@ -39,7 +38,7 @@ const isTypingOrInteractive =
|
|||||||
role === "button";
|
role === "button";
|
||||||
|
|
||||||
if (isTypingOrInteractive) return;
|
if (isTypingOrInteractive) return;
|
||||||
e.preventDefault()
|
e.preventDefault();
|
||||||
const key = e.key;
|
const key = e.key;
|
||||||
const mod = (s: number) => setProgressRelative(s);
|
const mod = (s: number) => setProgressRelative(s);
|
||||||
|
|
||||||
@ -50,32 +49,30 @@ const isTypingOrInteractive =
|
|||||||
case "c":
|
case "c":
|
||||||
toggleAlwaysShowControls();
|
toggleAlwaysShowControls();
|
||||||
break;
|
break;
|
||||||
case Key.Add:
|
|
||||||
case "+":
|
case "+":
|
||||||
case ">":
|
case ">":
|
||||||
increaseSpeed(false);
|
increaseSpeed(false);
|
||||||
break;
|
break;
|
||||||
case Key.Subtract:
|
|
||||||
case "-":
|
case "-":
|
||||||
case "<":
|
case "<":
|
||||||
decreaseSpeed();
|
decreaseSpeed();
|
||||||
break;
|
break;
|
||||||
case Key.ArrowLeft:
|
case "ArrowLeft":
|
||||||
if (e.shiftKey) mod(-300);
|
if (e.shiftKey) mod(-300);
|
||||||
else if (e.ctrlKey) mod(-60);
|
else if (e.ctrlKey) mod(-60);
|
||||||
else if (e.altKey) mod(-10);
|
else if (e.altKey) mod(-10);
|
||||||
else mod(-5);
|
else mod(-5);
|
||||||
break;
|
break;
|
||||||
case Key.ArrowRight:
|
case "ArrowRight":
|
||||||
if (e.shiftKey) mod(300);
|
if (e.shiftKey) mod(300);
|
||||||
else if (e.ctrlKey) mod(60);
|
else if (e.ctrlKey) mod(60);
|
||||||
else if (e.altKey) mod(10);
|
else if (e.altKey) mod(10);
|
||||||
else mod(5);
|
else mod(5);
|
||||||
break;
|
break;
|
||||||
case Key.ArrowDown:
|
case "ArrowDown":
|
||||||
changeVolume(-0.05);
|
changeVolume(-0.05);
|
||||||
break;
|
break;
|
||||||
case Key.ArrowUp:
|
case "ArrowUp":
|
||||||
changeVolume(0.05);
|
changeVolume(0.05);
|
||||||
break;
|
break;
|
||||||
case " ":
|
case " ":
|
||||||
@ -139,6 +136,5 @@ const isTypingOrInteractive =
|
|||||||
};
|
};
|
||||||
}, [handleKeyDown]);
|
}, [handleKeyDown]);
|
||||||
|
|
||||||
// Optional: return if you still want manual use
|
return null;
|
||||||
return null
|
|
||||||
};
|
};
|
||||||
|
@ -12,8 +12,8 @@ export const useResourceStatus = ({
|
|||||||
}: PropsUseResourceStatus) => {
|
}: PropsUseResourceStatus) => {
|
||||||
const resourceId = !resource ? null : `${resource.service}-${resource.name}-${resource.identifier}`;
|
const resourceId = !resource ? null : `${resource.service}-${resource.name}-${resource.identifier}`;
|
||||||
const status = usePublishStore((state)=> state.getResourceStatus(resourceId)) || null
|
const status = usePublishStore((state)=> state.getResourceStatus(resourceId)) || null
|
||||||
const intervalRef = useRef<null | number>(null)
|
const intervalRef = useRef<any>(null)
|
||||||
const timeoutRef = useRef<null | number>(null)
|
const timeoutRef = useRef<any>(null)
|
||||||
const setResourceStatus = usePublishStore((state) => state.setResourceStatus);
|
const setResourceStatus = usePublishStore((state) => state.setResourceStatus);
|
||||||
const statusRef = useRef<ResourceStatus | null>(null)
|
const statusRef = useRef<ResourceStatus | null>(null)
|
||||||
|
|
||||||
|
@ -5,3 +5,4 @@
|
|||||||
margin: 0px;
|
margin: 0px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,6 +9,8 @@
|
|||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
"forceConsistentCasingInFileNames": true
|
"forceConsistentCasingInFileNames": true
|
||||||
|
|
||||||
|
|
||||||
},
|
},
|
||||||
"include": ["src"]
|
"include": ["src"]
|
||||||
}
|
}
|
||||||
|
@ -10,5 +10,6 @@ export default defineConfig({
|
|||||||
'@mui/system',
|
'@mui/system',
|
||||||
'@emotion/react',
|
'@emotion/react',
|
||||||
'@emotion/styled',
|
'@emotion/styled',
|
||||||
|
'mediainfo.js'
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user