Compare commits

...

16 commits

Author SHA1 Message Date
Stratuma
15067b19a4
Merge pull request #1181 from ektatas/fix-useless-first-comma
Some checks are pending
auto-documentation / documentation (push) Waiting to run
build and push docker image / build-node (push) Waiting to run
Style and build test / tsc (push) Waiting to run
Style and build test / eslint (push) Blocked by required conditions
Style and build test / prettier (push) Blocked by required conditions
Style and build test / build-test-windows-arm64 (push) Blocked by required conditions
Style and build test / build-test-linux-arm64 (push) Blocked by required conditions
Style and build test / build-test-macos-arm64 (push) Blocked by required conditions
Style and build test / build-test-windows-x64 (push) Blocked by required conditions
Style and build test / build-test-linux-x64 (push) Blocked by required conditions
Style and build test / build-test-macos-x64 (push) Blocked by required conditions
fix first comma when select all episodes
2026-01-11 01:09:42 +01:00
ektatas
3bb33819a7
fix first comma when select all episodes 2026-01-03 15:28:04 +01:00
stratumadev
51b4c173ab chore(crunchy): update basic auth token and user-agent
Some checks failed
auto-documentation / documentation (push) Has been cancelled
build and push docker image / build-node (push) Has been cancelled
Style and build test / tsc (push) Has been cancelled
Style and build test / eslint (push) Has been cancelled
Style and build test / prettier (push) Has been cancelled
Style and build test / build-test-windows-arm64 (push) Has been cancelled
Style and build test / build-test-linux-arm64 (push) Has been cancelled
Style and build test / build-test-macos-arm64 (push) Has been cancelled
Style and build test / build-test-windows-x64 (push) Has been cancelled
Style and build test / build-test-linux-x64 (push) Has been cancelled
Style and build test / build-test-macos-x64 (push) Has been cancelled
2025-12-21 20:20:55 +01:00
stratumadev
46f352af8c chore(main): update packages
Some checks failed
auto-documentation / documentation (push) Has been cancelled
build and push docker image / build-node (push) Has been cancelled
Style and build test / tsc (push) Has been cancelled
Style and build test / eslint (push) Has been cancelled
Style and build test / prettier (push) Has been cancelled
Style and build test / build-test-windows-arm64 (push) Has been cancelled
Style and build test / build-test-linux-arm64 (push) Has been cancelled
Style and build test / build-test-macos-arm64 (push) Has been cancelled
Style and build test / build-test-windows-x64 (push) Has been cancelled
Style and build test / build-test-linux-x64 (push) Has been cancelled
Style and build test / build-test-macos-x64 (push) Has been cancelled
2025-12-18 11:01:35 +01:00
stratumadev
c9aa27df23 chore(main): update packages
Some checks failed
auto-documentation / documentation (push) Has been cancelled
build and push docker image / build-node (push) Has been cancelled
Style and build test / tsc (push) Has been cancelled
Style and build test / eslint (push) Has been cancelled
Style and build test / prettier (push) Has been cancelled
Style and build test / build-test-windows-arm64 (push) Has been cancelled
Style and build test / build-test-linux-arm64 (push) Has been cancelled
Style and build test / build-test-macos-arm64 (push) Has been cancelled
Style and build test / build-test-windows-x64 (push) Has been cancelled
Style and build test / build-test-linux-x64 (push) Has been cancelled
Style and build test / build-test-macos-x64 (push) Has been cancelled
2025-12-07 12:00:26 +01:00
stratumadev
a42dafe608 chore(gui): update express
Some checks failed
auto-documentation / documentation (push) Has been cancelled
build and push docker image / build-node (push) Has been cancelled
Style and build test / tsc (push) Has been cancelled
Style and build test / eslint (push) Has been cancelled
Style and build test / prettier (push) Has been cancelled
Style and build test / build-test-windows-arm64 (push) Has been cancelled
Style and build test / build-test-linux-arm64 (push) Has been cancelled
Style and build test / build-test-macos-arm64 (push) Has been cancelled
Style and build test / build-test-windows-x64 (push) Has been cancelled
Style and build test / build-test-linux-x64 (push) Has been cancelled
Style and build test / build-test-macos-x64 (push) Has been cancelled
2025-12-02 01:49:47 +01:00
stratumadev
61cf5a59a6 chore(main): update express and yaml 2025-12-02 01:45:27 +01:00
stratumadev
e8bec44982 perf(merger): remove unused functions and imports
Some checks failed
auto-documentation / documentation (push) Has been cancelled
build and push docker image / build-node (push) Has been cancelled
Style and build test / tsc (push) Has been cancelled
Style and build test / eslint (push) Has been cancelled
Style and build test / prettier (push) Has been cancelled
Style and build test / build-test-windows-arm64 (push) Has been cancelled
Style and build test / build-test-linux-arm64 (push) Has been cancelled
Style and build test / build-test-macos-arm64 (push) Has been cancelled
Style and build test / build-test-windows-x64 (push) Has been cancelled
Style and build test / build-test-linux-x64 (push) Has been cancelled
Style and build test / build-test-macos-x64 (push) Has been cancelled
2025-11-30 03:16:06 +01:00
stratumadev
1ff93f2fbd refactor(merger): move from ffprobe to mediainfo
Removes the necessity of ffprobe completely.
Also removed the mention of ffprobe requirement from the readme.
2025-11-30 03:10:28 +01:00
stratumadev
e4afedfc9c chore(args): remove unwanted console.log 2025-11-30 01:52:40 +01:00
stratumadev
aa1180df48 fix(args): transformer also applies to default values 2025-11-30 01:51:00 +01:00
stratumadev
429bb2d690 fix(args): resolve issue with short flag parsing in overrideArguments function
Some checks are pending
auto-documentation / documentation (push) Waiting to run
build and push docker image / build-node (push) Waiting to run
Style and build test / tsc (push) Waiting to run
Style and build test / eslint (push) Blocked by required conditions
Style and build test / prettier (push) Blocked by required conditions
Style and build test / build-test-windows-arm64 (push) Blocked by required conditions
Style and build test / build-test-linux-arm64 (push) Blocked by required conditions
Style and build test / build-test-macos-arm64 (push) Blocked by required conditions
Style and build test / build-test-windows-x64 (push) Blocked by required conditions
Style and build test / build-test-linux-x64 (push) Blocked by required conditions
Style and build test / build-test-macos-x64 (push) Blocked by required conditions
2025-11-28 22:22:00 +01:00
stratumadev
c9ca51e6ef chore(main): remove unused/outdated files and move to typescript only
Some checks are pending
auto-documentation / documentation (push) Waiting to run
build and push docker image / build-node (push) Waiting to run
Style and build test / tsc (push) Waiting to run
Style and build test / eslint (push) Blocked by required conditions
Style and build test / prettier (push) Blocked by required conditions
Style and build test / build-test-windows-arm64 (push) Blocked by required conditions
Style and build test / build-test-linux-arm64 (push) Blocked by required conditions
Style and build test / build-test-macos-arm64 (push) Blocked by required conditions
Style and build test / build-test-windows-x64 (push) Blocked by required conditions
Style and build test / build-test-linux-x64 (push) Blocked by required conditions
Style and build test / build-test-macos-x64 (push) Blocked by required conditions
2025-11-28 13:49:27 +01:00
stratumadev
7d828a3d47 docs(main): bump version 2025-11-28 12:35:41 +00:00
stratumadev
0bb757f655 chore(main): bump version 2025-11-28 13:34:21 +01:00
stratumadev
1bf0af08e6 fix(args): correct parsing so string options don't treat the next option as a value 2025-11-28 13:30:55 +01:00
20 changed files with 509 additions and 643 deletions

15
TODO.md
View file

@ -1,15 +0,0 @@
# Todo/Future Ideas list
- [ ] Look into implementing wvd file support
- [ ] Merge sync branch with latest master
- [ ] Finish implementing old algorithm
- [ ] Look into adding suggested algorithm [#599](https://github.com/anidl/multi-downloader-nx/issues/599)
- [ ] Remove Funimation
- [ ] Remove old hidive API or find a way to make it work
- [ ] Look into adding other services
- [ ] Refactor downloading code
- [ ] Allow audio and video download at the same time
- [ ] Reduce/Refactor the amount of duplicate/boilerplate code required
- [ ] Create a generic service class for the CLI with set inputs/outputs
- [ ] Modularize site modules to ease addition of new sites
- [ ] Create generic MPD/M3U8 playlist downloader

View file

@ -1,5 +1,4 @@
ffmpeg: 'ffmpeg.exe'
mkvmerge: 'mkvmerge.exe'
ffprobe: 'ffprobe.exe'
mp4decrypt: 'mp4decrypt.exe'
shaka: 'shaka-packager.exe'

23
dev.js
View file

@ -1,23 +0,0 @@
const { exec } = require('child_process');
const path = require('path');
const toRun = process.argv.slice(2).join(' ').split('---');
const waitForProcess = async (proc) => {
return new Promise((resolve, reject) => {
proc.stdout?.on('data', (data) => process.stdout.write(data));
proc.stderr?.on('data', (data) => process.stderr.write(data));
proc.on('close', resolve);
proc.on('error', reject);
});
};
(async () => {
await waitForProcess(exec('pnpm run tsc test false'));
for (let command of toRun) {
await waitForProcess(
exec(`node index.js --service hidive ${command}`, {
cwd: path.join(__dirname, 'lib')
})
);
}
})();

View file

@ -1,200 +0,0 @@
## Change Log
This changelog is out of date and wont be continued. Please see the releases comments, or if not present the commit comments.
### 4.7.0 (unreleased)
- Change subtitles parser from ttml to vtt
- Improve help command
- Update modules
#### Known issues:
- Proxy not supported
### 4.6.1 (2020/09/19)
- Update modules
#### Known issues:
- Proxy not supported
### 4.6.0 (2020/06/03)
- Bug fixes and improvements
#### Known issues:
- Proxy not supported
### 4.5.1 (2020/03/10)
- Better binary files handling
- Binary build for windows
#### Known issues:
- Proxy not supported
### 4.5.0 (2020/01/21)
- Resume downloading
#### Known issues:
- Proxy not supported
### 4.4.2 (2019/07/21)
- Better proxy handling for stream download
### 4.4.1 (2019/07/21)
- Fixed proxy for stream download
### 4.4.0 (2019/06/04)
- Added `--novids` option (Thanks to @subdiox)
- Update modules
### 4.3.2 (2019/05/09)
- Code improvements
- Fix `hls-download` error printing
### 4.3.1 (2019/05/09)
- Fix auto detection max quality (Regression in d7d280c)
### 4.3.0 (2019/05/09)
- Better server selection (Closes #42)
### 4.2.1 (2019/05/04)
- Filter duplicate urls for cloudfront.net (Closes #40)
### 4.2.0 (2019/05/02)
- Replace `request` module with `got`
- Changed proxy cli options
- Changed `login` option name to `auth`
- Changed `hls-download` parallel download configuration from 5 parts to 10
- Update modules
### 4.1.0 (2019/04/05)
- CLI options for login moved to CUI
- Removed showing set token at startup
### 4.0.5 (2019/02/09)
- Fix downloading shows with autoselect max quality
### 4.0.4 (2019/01/26)
- Fix search when shows not found
- Update modules
### 4.0.3 (2018/12/06)
- Select only non-encrypted (HLS) streams, encrypted streams is MPEG-DASH
### 4.0.2 (2018/11/25)
- Fix typos and update modules
### 4.0.1 (2018/11/23)
- Code refactoring and small fixes
### 4.0.0 RC 1 (2018/11/17)
- Select range of episodes using hyphen-sequence
- Skip muxing if executables not found
- Fixed typos and duplicate options
### 4.0.0 Beta 2 (2018/11/12)
- Select alternative server
- Updated readme
### 4.0.0 Beta 1 (2018/11/10)
- Rearrange folders structure
- Configuration changed to yaml format
- Muxing changed to MKV by default
- tsMuxeR+mp4box replaced with FFMPEG
- Updated commands help and readme
- Fixed typos and duplicate options
- `ttml2srt` moved to separate module
- Drop `m3u8-stream-list` module
- Code improvements
### 3.2.8 (2018/06/16)
- Fix video request when token not specified
### 3.2.7 (2018/06/15)
- Update modules
### 3.2.6 (2018/02/18)
- Fix commands help
### 3.2.5 (2018/02/12)
- Fixes and update modules
### 3.2.4 (2018/02/01)
- Update modules
### 3.2.3 (2018/01/31)
- Rearrange folders structure
### 3.2.2 (2018/01/16)
- Update modules
### 3.2.1 (2018/01/16)
- Update modules
- Small fixes
### 3.2.0 (2018/01/16)
- `hls-download` module moved to independent module
- Auth for socks proxy
### 3.1.0 (2017/12/30)
- Convert DXFP (TTML) subtitles to SRT format
### 3.0.1 (2017/12/05)
- Check subtitles availability
- Download subtitles in SRT format instead of VTT
- Extended hls download progress info
### 3.0.0 Beta 3 (2017/12/03)
- Restored MKV and MP4 muxing
- Convert VTT subtitles to SRT format
### 3.0.0 Beta 2 (2017/10/18)
- Fix video downloading
### 3.0.0 Beta 1 (2017/10/17)
- Major code changes and improvements
- Drop Streamlink and added own module for hls download
### 2.5.0 (2017/09/04)
- `nosubs` option
- Request video with app api
### 2.4.1 (2017/09/02)
- Fixed typo in package.json
- Fix #11: URL for getting video stream url was changed
### 2.4.0 (2017/07/04)
- IPv4 Socks5 proxy support
### 2.3.3 (2017/06/19)
- Removed forgotten debug code
### 2.3.2 (2017/06/19)
- Fix #5: Script fails to multiplex unique file names
### 2.3.1 (2017/04/29)
- Code improvements
### 2.3.0 (2017/04/27)
- Code improvements
### 2.2.5 (2017/04/17)
- Minor code improvements and fixes
### 2.1.4 (2017/04/10)
- Minor changes
### 2.1.3 (2017/04/10)
- Minor changes and fixes
### 2.1.2 (2017/04/10)
- Fix config path
### 2.1.1 (2017/04/10)
- Minor text changes
- Fix config
- Minor changes
### 2.1.0 (2017/04/10)
- First stable release
### 2.0.0 Beta (lost in time)
- First public release

View file

@ -1,4 +1,4 @@
# multi-downloader-nx (v5.6.8)
# multi-downloader-nx (v5.6.9)
If you find any bugs in this documentation or in the program itself please report it [over on GitHub](https://github.com/anidl/multi-downloader-nx/issues).

View file

@ -126,7 +126,6 @@ C:.
12. Great! Now we have all dependencies installed and available in our PATH. To confirm that everything is working, open a new Command Prompt window and run the following commands:
```
ffmpeg
ffprobe
mkvmerge
mp4decrypt (or shaka-packager's .exe name, if you chose that instead)
```

View file

@ -18,7 +18,6 @@ This application is not endorsed by or affiliated with *Crunchyroll*, *Hidive* o
By default this application uses the following paths to programs (main executables):
* `ffmpeg.exe` (Windows) or `ffmpeg` (other) (From PATH)
* `ffprobe.exe` (Windows) or `ffprobe` (other) (From PATH)
* `mkvmerge.exe` (Windows) or `mkvmerge` (other) (From PATH)
* `mp4decrypt.exe` (Windows) or `mp4decrypt` (other) (From PATH) (or shaka-packager)
* `shaka-packager.exe` (Windows) or `shaka-packager` (other) (From PATH) (or mp4decrypt)

View file

@ -33,7 +33,7 @@ export default tseslint.config(
}
},
{
ignores: ['**/lib', '**/videos', '**/build', 'dev.js', 'tsc.ts']
ignores: ['**/lib', '**/videos', '**/build', 'tsc.ts']
},
{
files: ['gui/react/**/*'],

View file

@ -1168,8 +1168,8 @@ packages:
balanced-match@1.0.2:
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
baseline-browser-mapping@2.8.31:
resolution: {integrity: sha512-a28v2eWrrRWPpJSzxc+mKwm0ZtVx/G8SepdQZDArnXYU/XS+IF6mp8aB/4E+hH1tyGCoDo3KlUCdlSxGDsRkAw==}
baseline-browser-mapping@2.8.32:
resolution: {integrity: sha512-OPz5aBThlyLFgxyhdwf/s2+8ab3OvT7AdTNvKHBwpXomIYeXqpUUuT8LrdtxZSsWJ4R4CU1un4XGh5Ez3nlTpw==}
hasBin: true
batch@0.6.1:
@ -1179,8 +1179,8 @@ packages:
resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==}
engines: {node: '>=8'}
body-parser@1.20.3:
resolution: {integrity: sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==}
body-parser@1.20.4:
resolution: {integrity: sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==}
engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16}
bonjour-service@1.3.0:
@ -1321,11 +1321,11 @@ packages:
convert-source-map@2.0.0:
resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==}
cookie-signature@1.0.6:
resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==}
cookie-signature@1.0.7:
resolution: {integrity: sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==}
cookie@0.7.1:
resolution: {integrity: sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==}
cookie@0.7.2:
resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==}
engines: {node: '>= 0.6'}
core-js-compat@3.47.0:
@ -1539,8 +1539,8 @@ packages:
resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==}
engines: {node: '>=0.8.x'}
express@4.21.2:
resolution: {integrity: sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==}
express@4.22.1:
resolution: {integrity: sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==}
engines: {node: '>= 0.10.0'}
fast-deep-equal@3.1.3:
@ -1561,8 +1561,8 @@ packages:
resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
engines: {node: '>=8'}
finalhandler@1.3.1:
resolution: {integrity: sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==}
finalhandler@1.3.2:
resolution: {integrity: sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==}
engines: {node: '>= 0.8'}
find-root@1.1.0:
@ -1712,6 +1712,10 @@ packages:
resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==}
engines: {node: '>= 0.8'}
http-errors@2.0.1:
resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==}
engines: {node: '>= 0.8'}
http-parser-js@0.5.10:
resolution: {integrity: sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA==}
@ -1769,8 +1773,8 @@ packages:
resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==}
engines: {node: '>= 0.10'}
ipaddr.js@2.2.0:
resolution: {integrity: sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==}
ipaddr.js@2.3.0:
resolution: {integrity: sha512-Zv/pA+ciVFbCSBBjGfaKUya/CcGmUHzTydLMaTwrUUEM2DIEO3iZvueGxmacvmN50fGpGVKeTXpb2LcYQxeVdg==}
engines: {node: '>= 10'}
is-arrayish@0.2.1:
@ -1912,8 +1916,8 @@ packages:
resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==}
engines: {node: '>= 0.6'}
memfs@4.51.0:
resolution: {integrity: sha512-4zngfkVM/GpIhC8YazOsM6E8hoB33NP0BCESPOA6z7qaL6umPJNqkO8CNYaLV2FB2MV6H1O3x2luHHOSqppv+A==}
memfs@4.51.1:
resolution: {integrity: sha512-Eyt3XrufitN2ZL9c/uIRMyDwXanLI88h/L3MoWqNY747ha3dMR9dWqp8cRT5ntjZ0U1TNuq4U91ZXK0sMBjYOQ==}
merge-descriptors@1.0.3:
resolution: {integrity: sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==}
@ -2135,8 +2139,8 @@ packages:
peerDependencies:
postcss: ^8.1.0
postcss-selector-parser@7.1.0:
resolution: {integrity: sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==}
postcss-selector-parser@7.1.1:
resolution: {integrity: sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==}
engines: {node: '>=4'}
postcss-value-parser@4.2.0:
@ -2159,8 +2163,8 @@ packages:
resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==}
engines: {node: '>= 0.10'}
qs@6.13.0:
resolution: {integrity: sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==}
qs@6.14.0:
resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==}
engines: {node: '>=0.6'}
randombytes@2.1.0:
@ -2170,8 +2174,8 @@ packages:
resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==}
engines: {node: '>= 0.6'}
raw-body@2.5.2:
resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==}
raw-body@2.5.3:
resolution: {integrity: sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==}
engines: {node: '>= 0.8'}
react-dom@19.2.0:
@ -2314,6 +2318,10 @@ packages:
resolution: {integrity: sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==}
engines: {node: '>= 0.8.0'}
send@0.19.1:
resolution: {integrity: sha512-p4rRk4f23ynFEfcD9LA0xRYngj+IyGiEYyqqOak8kaN0TvNmuxC2dcVeBn62GpCeR2CpWqyHCNScTP91QbAVFg==}
engines: {node: '>= 0.8.0'}
serialize-javascript@6.0.2:
resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==}
@ -2400,6 +2408,10 @@ packages:
resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==}
engines: {node: '>= 0.8'}
statuses@2.0.2:
resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==}
engines: {node: '>= 0.8'}
string-width@4.2.3:
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
engines: {node: '>=8'}
@ -4007,24 +4019,24 @@ snapshots:
balanced-match@1.0.2: {}
baseline-browser-mapping@2.8.31: {}
baseline-browser-mapping@2.8.32: {}
batch@0.6.1: {}
binary-extensions@2.3.0: {}
body-parser@1.20.3:
body-parser@1.20.4:
dependencies:
bytes: 3.1.2
content-type: 1.0.5
debug: 2.6.9
depd: 2.0.0
destroy: 1.2.0
http-errors: 2.0.0
http-errors: 2.0.1
iconv-lite: 0.4.24
on-finished: 2.4.1
qs: 6.13.0
raw-body: 2.5.2
qs: 6.14.0
raw-body: 2.5.3
type-is: 1.6.18
unpipe: 1.0.0
transitivePeerDependencies:
@ -4048,7 +4060,7 @@ snapshots:
browserslist@4.28.0:
dependencies:
baseline-browser-mapping: 2.8.31
baseline-browser-mapping: 2.8.32
caniuse-lite: 1.0.30001757
electron-to-chromium: 1.5.262
node-releases: 2.0.27
@ -4175,9 +4187,9 @@ snapshots:
convert-source-map@2.0.0: {}
cookie-signature@1.0.6: {}
cookie-signature@1.0.7: {}
cookie@0.7.1: {}
cookie@0.7.2: {}
core-js-compat@3.47.0:
dependencies:
@ -4357,36 +4369,36 @@ snapshots:
events@3.3.0: {}
express@4.21.2:
express@4.22.1:
dependencies:
accepts: 1.3.8
array-flatten: 1.1.1
body-parser: 1.20.3
body-parser: 1.20.4
content-disposition: 0.5.4
content-type: 1.0.5
cookie: 0.7.1
cookie-signature: 1.0.6
cookie: 0.7.2
cookie-signature: 1.0.7
debug: 2.6.9
depd: 2.0.0
encodeurl: 2.0.0
escape-html: 1.0.3
etag: 1.8.1
finalhandler: 1.3.1
finalhandler: 1.3.2
fresh: 0.5.2
http-errors: 2.0.0
http-errors: 2.0.1
merge-descriptors: 1.0.3
methods: 1.1.2
on-finished: 2.4.1
parseurl: 1.3.3
path-to-regexp: 0.1.12
proxy-addr: 2.0.7
qs: 6.13.0
qs: 6.14.0
range-parser: 1.2.1
safe-buffer: 5.2.1
send: 0.19.0
send: 0.19.1
serve-static: 1.16.2
setprototypeof: 1.2.0
statuses: 2.0.1
statuses: 2.0.2
type-is: 1.6.18
utils-merge: 1.0.1
vary: 1.1.2
@ -4407,14 +4419,14 @@ snapshots:
dependencies:
to-regex-range: 5.0.1
finalhandler@1.3.1:
finalhandler@1.3.2:
dependencies:
debug: 2.6.9
encodeurl: 2.0.0
escape-html: 1.0.3
on-finished: 2.4.1
parseurl: 1.3.3
statuses: 2.0.1
statuses: 2.0.2
unpipe: 1.0.0
transitivePeerDependencies:
- supports-color
@ -4564,6 +4576,14 @@ snapshots:
statuses: 2.0.1
toidentifier: 1.0.1
http-errors@2.0.1:
dependencies:
depd: 2.0.0
inherits: 2.0.4
setprototypeof: 1.2.0
statuses: 2.0.2
toidentifier: 1.0.1
http-parser-js@0.5.10: {}
http-proxy-middleware@2.0.9(@types/express@4.17.25):
@ -4619,7 +4639,7 @@ snapshots:
ipaddr.js@1.9.1: {}
ipaddr.js@2.2.0: {}
ipaddr.js@2.3.0: {}
is-arrayish@0.2.1: {}
@ -4727,7 +4747,7 @@ snapshots:
media-typer@0.3.0: {}
memfs@4.51.0:
memfs@4.51.1:
dependencies:
'@jsonjoy.com/json-pack': 1.21.0(tslib@2.8.1)
'@jsonjoy.com/util': 1.9.0(tslib@2.8.1)
@ -4908,20 +4928,20 @@ snapshots:
dependencies:
icss-utils: 5.1.0(postcss@8.5.6)
postcss: 8.5.6
postcss-selector-parser: 7.1.0
postcss-selector-parser: 7.1.1
postcss-value-parser: 4.2.0
postcss-modules-scope@3.2.1(postcss@8.5.6):
dependencies:
postcss: 8.5.6
postcss-selector-parser: 7.1.0
postcss-selector-parser: 7.1.1
postcss-modules-values@4.0.0(postcss@8.5.6):
dependencies:
icss-utils: 5.1.0(postcss@8.5.6)
postcss: 8.5.6
postcss-selector-parser@7.1.0:
postcss-selector-parser@7.1.1:
dependencies:
cssesc: 3.0.0
util-deprecate: 1.0.2
@ -4952,7 +4972,7 @@ snapshots:
forwarded: 0.2.0
ipaddr.js: 1.9.1
qs@6.13.0:
qs@6.14.0:
dependencies:
side-channel: 1.1.0
@ -4962,10 +4982,10 @@ snapshots:
range-parser@1.2.1: {}
raw-body@2.5.2:
raw-body@2.5.3:
dependencies:
bytes: 3.1.2
http-errors: 2.0.0
http-errors: 2.0.1
iconv-lite: 0.4.24
unpipe: 1.0.0
@ -5118,6 +5138,24 @@ snapshots:
transitivePeerDependencies:
- supports-color
send@0.19.1:
dependencies:
debug: 2.6.9
depd: 2.0.0
destroy: 1.2.0
encodeurl: 2.0.0
escape-html: 1.0.3
etag: 1.8.1
fresh: 0.5.2
http-errors: 2.0.0
mime: 1.6.0
ms: 2.1.3
on-finished: 2.4.1
range-parser: 1.2.1
statuses: 2.0.1
transitivePeerDependencies:
- supports-color
serialize-javascript@6.0.2:
dependencies:
randombytes: 2.1.0
@ -5231,6 +5269,8 @@ snapshots:
statuses@2.0.1: {}
statuses@2.0.2: {}
string-width@4.2.3:
dependencies:
emoji-regex: 8.0.0
@ -5394,7 +5434,7 @@ snapshots:
webpack-dev-middleware@7.4.5(webpack@5.103.0):
dependencies:
colorette: 2.0.20
memfs: 4.51.0
memfs: 4.51.1
mime-types: 3.0.2
on-finished: 2.4.1
range-parser: 1.2.1
@ -5418,10 +5458,10 @@ snapshots:
colorette: 2.0.20
compression: 1.8.1
connect-history-api-fallback: 2.0.0
express: 4.21.2
express: 4.22.1
graceful-fs: 4.2.11
http-proxy-middleware: 2.0.9(@types/express@4.17.25)
ipaddr.js: 2.2.0
ipaddr.js: 2.3.0
launch-editor: 2.12.0
open: 10.2.0
p-retry: 6.2.1

View file

@ -27,17 +27,15 @@ const EpisodeListing: React.FC = () => {
}, [store.episodeListing]);
const close = () => {
dispatch({
type: 'episodeListing',
payload: []
});
const mergedEpisodes = [...parseEpisodes(store.downloadOptions.e), ...selected];
dispatch({
type: 'downloadOptions',
payload: {
...store.downloadOptions,
e: `${[...new Set([...parseSelect(store.downloadOptions.e), ...selected])].join(',')}`
e: serializeEpisodes(mergedEpisodes)
}
});
dispatch({ type: 'episodeListing', payload: [] });
};
const getEpisodesForSeason = (season: string | 'all') => {
@ -168,6 +166,16 @@ const EpisodeListing: React.FC = () => {
</Dialog>
);
};
const parseEpisodes = (e: string): string[] => {
if (!e) return [];
return e
.split(',')
.map((s) => s.trim())
.filter((s) => s.length > 0);
};
const serializeEpisodes = (episodes: string[]): string => {
return [...new Set(episodes)].join(',');
};
const parseSelect = (s: string): string[] => {
const ret: string[] = [];

View file

@ -52,10 +52,6 @@ const SERVICES: Record<string, any> = {
const ids = makeCommand(argv.service);
for (const id of ids) {
overrideArguments(cfg.cli, id);
/* Reimport module to override appArgv */
// Object.keys(require.cache).forEach((key) => {
// if (key.endsWith('crunchy.js') || key.endsWith('hidive.js')) delete require.cache[key];
// });
const Service = SERVICES[argv.service];
if (!Service) {
console.error('Unknown service:', argv.service);

View file

@ -105,7 +105,6 @@ async function buildBinary(buildType: BuildTypes, gui: boolean) {
const binConf = {
ffmpeg: `ffmpeg${ext}`,
mkvmerge: `mkvmerge${ext}`,
ffprobe: `ffprobe${ext}`,
mp4decrypt: `mp4decrypt${ext}`,
shaka: `shaka-packager${ext}`
};

View file

@ -53,7 +53,7 @@ const api: APIType = {
bundlejs: 'https://static.crunchyroll.com/vilos-v2/web/vilos/js/bundle.js',
//
// Crunchyroll API
basic_auth_token: 'bmR0aTZicXlqcm9wNXZnZjF0dnU6elpIcS00SEJJVDlDb2FMcnBPREJjRVRCTUNHai1QNlg=',
basic_auth_token: 'b2g0cnYxbHpsOXR5ZzF4b2NqZ2o6cDI4bEhwM3J1ZVV0ek1aNDRhZmNyam84MUNmaFZGemg=',
auth: `${domain.cr_api}/auth/v1/token`,
me: `${domain.cr_api}/accounts/v1/me`,
profile: `${domain.cr_api}/accounts/v1/me/profile`,
@ -71,7 +71,7 @@ const api: APIType = {
cms_auth: `${domain.cr_api}/index/v2`,
//
// Crunchyroll Headers
crunchyDefUserAgent: 'Crunchyroll/ANDROIDTV/3.50.0_22282 (Android 12; en-US; SHIELD Android TV Build/SR1A.211012.001)',
crunchyDefUserAgent: 'Crunchyroll/ANDROIDTV/3.53.1_22290 (Android 12; en-US; SHIELD Android TV Build/SR1A.211012.001)',
crunchyDefHeader: {},
crunchyAuthHeader: {},
crunchyAuthRefreshHeader: {},

View file

@ -182,9 +182,9 @@ const overrideArguments = (cfg: { [key: string]: unknown }, override: Partial<ty
for (const [key, val] of Object.entries(override)) {
if (val === undefined) continue;
if (typeof val === 'boolean') {
if (val) baseArgv.push(`--${key}`);
if (val) baseArgv.push(key.length > 1 ? `--${key}` : `-${key}`);
} else {
baseArgv.push(`--${key}`, String(val));
baseArgv.push(key.length > 1 ? `--${key}` : `-${key}`, String(val));
}
}
@ -250,9 +250,16 @@ const getCommander = (cfg: Record<string, unknown>, isGUI: boolean) => {
: `--${item.name}`) + (item.type === 'boolean' ? '' : ` <value>`),
item.describe ?? ''
);
if (item.default !== undefined) option.default(item.default);
if (item.default !== undefined) option.default(item.transformer ? item.transformer(item.default) : item.default);
const optionNames = [...args.map((a) => `--${a.name}`), ...args.map((a) => (a.alias ? `-${a.alias}` : null)).filter(Boolean)];
option.argParser((value) => {
if (item.transformer) return item.transformer(value);
// Prevent from passing other options als value for option
if (value && typeof value === 'string' && value.startsWith('-') && optionNames.includes(value)) return undefined;
if (item.type === 'boolean') {
if (value === undefined) return true;
if (value === 'true') return true;
@ -277,14 +284,17 @@ const getCommander = (cfg: Record<string, unknown>, isGUI: boolean) => {
return Number.isFinite(num) ? num : 0;
}
if (item.type === 'string') {
if (value === undefined) return undefined;
return value;
}
if (item.choices && !(isGUI && item.name === 'service')) {
if (!item.choices.includes(value)) {
console.error(`Invalid value '${value}' for --${item.name}. Allowed: ${item.choices.join(', ')}`);
process.exit(1);
}
}
if (item.transformer) return item.transformer(value);
return value;
});

View file

@ -85,7 +85,6 @@ export type ConfigObject = {
bin: {
ffmpeg?: string;
mkvmerge?: string;
ffprobe?: string;
mp4decrypt?: string;
shaka?: string;
};
@ -150,7 +149,6 @@ const loadBinCfg = async () => {
const defaultBin = {
ffmpeg: 'ffmpeg',
mkvmerge: 'mkvmerge',
ffprobe: 'ffprobe',
mp4decrypt: 'mp4decrypt',
shaka: 'shaka-packager'
};

View file

@ -1,14 +1,14 @@
import * as iso639 from 'iso-639';
import * as yamlCfg from './module.cfg-loader';
import { fontFamilies, fontMime } from './module.fontsData';
import path from 'path';
import fs from 'fs';
import fsp from 'fs/promises';
import { LanguageItem } from './module.langsData';
import { AvailableMuxer } from './module.args';
import { console } from './log';
import ffprobe from 'ffprobe';
import Helper from './module.helper';
import { convertChaptersToFFmpegFormat } from './module.ffmpegChapter';
import { mediaInfoFactory } from 'mediainfo.js';
export type MergerInput = {
path: string;
@ -67,13 +67,26 @@ class Merger {
public async createDelays() {
//Don't bother scanning it if there is only 1 vna stream
if (this.options.videoAndAudio.length > 1) {
const bin = await yamlCfg.loadBinCfg();
const vnas = this.options.videoAndAudio;
//get and set durations on each videoAndAudio Stream
for (const [vnaIndex, vna] of vnas.entries()) {
const streamInfo = await ffprobe(vna.path, { path: bin.ffprobe as string });
const videoInfo = streamInfo.streams.filter((stream) => stream.codec_type == 'video');
vnas[vnaIndex].duration = parseInt(videoInfo[0].duration as string);
const file = await fsp.open(vna.path);
const { size } = await fsp.stat(vna.path);
// Mediainfo
const mediaInfo = await mediaInfoFactory();
const result = await mediaInfo.analyzeData(
() => size,
async (size, offset) => {
const buf = Buffer.alloc(size);
const { bytesRead } = await file.read(buf, 0, size, offset);
return buf.subarray(0, bytesRead);
}
);
await file.close();
const videoInfo = result?.media?.track?.filter((stream) => stream['@type'] == 'Video');
vnas[vnaIndex].duration = videoInfo?.[0].Duration;
}
//Sort videoAndAudio streams by duration (shortest first)
vnas.sort((a, b) => {

View file

@ -1,7 +1,7 @@
{
"name": "multi-downloader-nx",
"short_name": "aniDL",
"version": "5.6.8",
"version": "5.6.9",
"description": "Downloader for Crunchyroll, Hidive, and AnimationDigitalNetwork with CLI and GUI",
"keywords": [
"download",
@ -40,44 +40,44 @@
},
"license": "MIT",
"dependencies": {
"@bufbuild/protobuf": "^2.10.1",
"@bufbuild/protobuf": "^2.10.2",
"commander": "^14.0.2",
"express": "^5.1.0",
"ffprobe": "^1.1.2",
"express": "^5.2.1",
"iso-639": "^0.2.2",
"leven": "^4.1.0",
"log4js": "^6.9.1",
"lookpath": "^1.2.3",
"m3u8-parser": "^7.2.0",
"mediainfo.js": "^0.3.6",
"mpd-parser": "^1.3.1",
"node-playready": "^1.1.1",
"open": "^11.0.0",
"undici": "^7.16.0",
"widevine": "^1.0.3",
"ws": "^8.18.3",
"yaml": "^2.8.1"
"yaml": "^2.8.2"
},
"devDependencies": {
"@commitlint/cli": "^20.1.0",
"@commitlint/config-conventional": "^20.0.0",
"@eslint/js": "^9.39.1",
"@types/express": "^5.0.5",
"@types/ffprobe": "^1.1.8",
"@commitlint/cli": "^20.2.0",
"@commitlint/config-conventional": "^20.2.0",
"@eslint/js": "^9.39.2",
"@types/express": "^5.0.6",
"@types/m3u8-parser": "^7.2.5",
"@types/node": "^24.10.1",
"@types/node": "^25.0.3",
"@types/ws": "^8.18.1",
"@typescript-eslint/eslint-plugin": "^8.48.0",
"@typescript-eslint/parser": "^8.48.0",
"@yao-pkg/pkg": "^6.10.1",
"@typescript-eslint/eslint-plugin": "^8.50.0",
"@typescript-eslint/parser": "^8.50.0",
"@yao-pkg/pkg": "^6.11.0",
"esbuild": "0.26.0",
"eslint": "^9.39.1",
"eslint": "^9.39.2",
"eslint-config-prettier": "^10.1.8",
"husky": "^9.1.7",
"prettier": "^3.7.1",
"jiti": "^2.6.1",
"prettier": "^3.7.4",
"removeNPMAbsolutePaths": "^3.0.1",
"ts-node": "^10.9.2",
"typescript": "^5.9.3",
"typescript-eslint": "^8.48.0"
"typescript-eslint": "^8.50.0"
},
"scripts": {
"prestart": "pnpm run tsc test",

File diff suppressed because it is too large Load diff

1
tsc.ts
View file

@ -28,7 +28,6 @@ const ignore = [
'*/*\\.tsx?$',
'./fonts*',
'./gui/react*',
'./dev.js$',
'*/node_modules/*',
'./widevine/*',
'./playready/*',