add size control
This commit is contained in:
parent
9b6c1eaf62
commit
c297fc8204
5 changed files with 264 additions and 23 deletions
217
package-lock.json
generated
217
package-lock.json
generated
|
@ -10,6 +10,7 @@
|
||||||
"license": "AGPL-3.0-or-later",
|
"license": "AGPL-3.0-or-later",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ffmpeg-static": "^5.1.0",
|
"ffmpeg-static": "^5.1.0",
|
||||||
|
"get-video-duration": "^4.1.0",
|
||||||
"typescript": "^5.1.6"
|
"typescript": "^5.1.6"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
@ -471,6 +472,123 @@
|
||||||
"node": ">=10"
|
"node": ">=10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@ffprobe-installer/darwin-arm64": {
|
||||||
|
"version": "5.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@ffprobe-installer/darwin-arm64/-/darwin-arm64-5.0.1.tgz",
|
||||||
|
"integrity": "sha512-vwNCNjokH8hfkbl6m95zICHwkSzhEvDC3GVBcUp5HX8+4wsX10SP3B+bGur7XUzTIZ4cQpgJmEIAx6TUwRepMg==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"hasInstallScript": true,
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"darwin"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"node_modules/@ffprobe-installer/darwin-x64": {
|
||||||
|
"version": "5.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@ffprobe-installer/darwin-x64/-/darwin-x64-5.0.0.tgz",
|
||||||
|
"integrity": "sha512-Zl0UkZ+wW/eyMKBPLTUCcNQch2VDnZz/cBn1DXv3YtCBVbYd9aYzGj4MImdxgWcoE0+GpbfbO6mKGwMq5HCm6A==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"hasInstallScript": true,
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"darwin"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"node_modules/@ffprobe-installer/ffprobe": {
|
||||||
|
"version": "1.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@ffprobe-installer/ffprobe/-/ffprobe-1.4.1.tgz",
|
||||||
|
"integrity": "sha512-3WJvxU0f4d7IOZdzoVCAj9fYtiQNC6E0521FJFe9iP5Ej8auTXU7TsrUzIAG1CydeQI+BnM3vGog92SCcF9KtA==",
|
||||||
|
"optionalDependencies": {
|
||||||
|
"@ffprobe-installer/darwin-arm64": "5.0.1",
|
||||||
|
"@ffprobe-installer/darwin-x64": "5.0.0",
|
||||||
|
"@ffprobe-installer/linux-arm": "5.0.0",
|
||||||
|
"@ffprobe-installer/linux-arm64": "5.0.0",
|
||||||
|
"@ffprobe-installer/linux-ia32": "5.0.0",
|
||||||
|
"@ffprobe-installer/linux-x64": "5.0.0",
|
||||||
|
"@ffprobe-installer/win32-ia32": "5.0.0",
|
||||||
|
"@ffprobe-installer/win32-x64": "5.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@ffprobe-installer/linux-arm": {
|
||||||
|
"version": "5.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@ffprobe-installer/linux-arm/-/linux-arm-5.0.0.tgz",
|
||||||
|
"integrity": "sha512-mM1PPxP2UX5SUvhy0urcj5U8UolwbYgmnXA/eBWbW78k6N2Wk1COvcHYzOPs6c5yXXL6oshS2rZHU1kowigw7g==",
|
||||||
|
"cpu": [
|
||||||
|
"arm"
|
||||||
|
],
|
||||||
|
"hasInstallScript": true,
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"node_modules/@ffprobe-installer/linux-arm64": {
|
||||||
|
"version": "5.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@ffprobe-installer/linux-arm64/-/linux-arm64-5.0.0.tgz",
|
||||||
|
"integrity": "sha512-IwFbzhe1UydR849YXLPP0RMpHgHXSuPO1kznaCHcU5FscFBV5gOZLkdD8e/xrcC8g/nhKqy0xMjn5kv6KkFQlQ==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"hasInstallScript": true,
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"node_modules/@ffprobe-installer/linux-ia32": {
|
||||||
|
"version": "5.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@ffprobe-installer/linux-ia32/-/linux-ia32-5.0.0.tgz",
|
||||||
|
"integrity": "sha512-c3bWlWEDMST59SAZycVh0oyc2eNS/CxxeRjoNryGRgqcZX3EJWJJQL1rAXbpQOMLMi8to1RqnmMuwPJgLLjjUA==",
|
||||||
|
"cpu": [
|
||||||
|
"ia32"
|
||||||
|
],
|
||||||
|
"hasInstallScript": true,
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"node_modules/@ffprobe-installer/linux-x64": {
|
||||||
|
"version": "5.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@ffprobe-installer/linux-x64/-/linux-x64-5.0.0.tgz",
|
||||||
|
"integrity": "sha512-zgLnWJFvMGCaw1txGtz84sMEQt6mQUzdw86ih9S/kZOWnp06Gj/ams/EXxEkAxgAACCVM6/O0mkDe/6biY5tgA==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"hasInstallScript": true,
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"node_modules/@ffprobe-installer/win32-ia32": {
|
||||||
|
"version": "5.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@ffprobe-installer/win32-ia32/-/win32-ia32-5.0.0.tgz",
|
||||||
|
"integrity": "sha512-NnDdAZD6ShFXzJeCkAFl2ZjAv7GcJWYudLA+0T/vjZwvskBop+sq1PGfdmVltfFDcdQiomoThRhn9Xiy9ZC71g==",
|
||||||
|
"cpu": [
|
||||||
|
"ia32"
|
||||||
|
],
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"win32"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"node_modules/@ffprobe-installer/win32-x64": {
|
||||||
|
"version": "5.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@ffprobe-installer/win32-x64/-/win32-x64-5.0.0.tgz",
|
||||||
|
"integrity": "sha512-P4ZMRFxVMnfMsOyTfBM/+nkTodLeOUfXNPo+X1bKEWBiZxRErqX/IHS5sLA0yAH8XmtKZcL7Cu6M26ztGcQYxw==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"win32"
|
||||||
|
]
|
||||||
|
},
|
||||||
"node_modules/@isaacs/cliui": {
|
"node_modules/@isaacs/cliui": {
|
||||||
"version": "8.0.2",
|
"version": "8.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
|
||||||
|
@ -1288,7 +1406,6 @@
|
||||||
"version": "7.0.3",
|
"version": "7.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
||||||
"integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
|
"integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"path-key": "^3.1.0",
|
"path-key": "^3.1.0",
|
||||||
"shebang-command": "^2.0.0",
|
"shebang-command": "^2.0.0",
|
||||||
|
@ -2099,6 +2216,71 @@
|
||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/get-video-duration": {
|
||||||
|
"version": "4.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/get-video-duration/-/get-video-duration-4.1.0.tgz",
|
||||||
|
"integrity": "sha512-kDmnD/C/WFHmZx7eV2duUNCwAH6w9YwpigiUHmq7cRNmxuTvcJ/otvcxa4A5GDus2iSZ+CZEA5e0va/r5ZWumw==",
|
||||||
|
"dependencies": {
|
||||||
|
"@ffprobe-installer/ffprobe": "^1.4.1",
|
||||||
|
"execa": "^5.0.0",
|
||||||
|
"is-stream": "^2.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/get-video-duration/node_modules/execa": {
|
||||||
|
"version": "5.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
|
||||||
|
"integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
|
||||||
|
"dependencies": {
|
||||||
|
"cross-spawn": "^7.0.3",
|
||||||
|
"get-stream": "^6.0.0",
|
||||||
|
"human-signals": "^2.1.0",
|
||||||
|
"is-stream": "^2.0.0",
|
||||||
|
"merge-stream": "^2.0.0",
|
||||||
|
"npm-run-path": "^4.0.1",
|
||||||
|
"onetime": "^5.1.2",
|
||||||
|
"signal-exit": "^3.0.3",
|
||||||
|
"strip-final-newline": "^2.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sindresorhus/execa?sponsor=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/get-video-duration/node_modules/get-stream": {
|
||||||
|
"version": "6.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
|
||||||
|
"integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/get-video-duration/node_modules/is-stream": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/get-video-duration/node_modules/npm-run-path": {
|
||||||
|
"version": "4.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
|
||||||
|
"integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
|
||||||
|
"dependencies": {
|
||||||
|
"path-key": "^3.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/glob": {
|
"node_modules/glob": {
|
||||||
"version": "7.2.3",
|
"version": "7.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
|
||||||
|
@ -2380,6 +2562,14 @@
|
||||||
"node": ">= 6"
|
"node": ">= 6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/human-signals": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.17.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/humanize-ms": {
|
"node_modules/humanize-ms": {
|
||||||
"version": "1.2.1",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz",
|
||||||
|
@ -2620,8 +2810,7 @@
|
||||||
"node_modules/isexe": {
|
"node_modules/isexe": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
||||||
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
|
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"node_modules/jackspeak": {
|
"node_modules/jackspeak": {
|
||||||
"version": "2.2.2",
|
"version": "2.2.2",
|
||||||
|
@ -2901,6 +3090,11 @@
|
||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/merge-stream": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w=="
|
||||||
|
},
|
||||||
"node_modules/merge2": {
|
"node_modules/merge2": {
|
||||||
"version": "1.4.1",
|
"version": "1.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
|
||||||
|
@ -2927,7 +3121,6 @@
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
|
||||||
"integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
|
"integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
|
||||||
"dev": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
|
@ -3314,7 +3507,6 @@
|
||||||
"version": "5.1.2",
|
"version": "5.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
|
||||||
"integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
|
"integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"mimic-fn": "^2.1.0"
|
"mimic-fn": "^2.1.0"
|
||||||
},
|
},
|
||||||
|
@ -3498,7 +3690,6 @@
|
||||||
"version": "3.1.1",
|
"version": "3.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
|
||||||
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
|
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
|
||||||
"dev": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
|
@ -4117,7 +4308,6 @@
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
||||||
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
|
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"shebang-regex": "^3.0.0"
|
"shebang-regex": "^3.0.0"
|
||||||
},
|
},
|
||||||
|
@ -4129,7 +4319,6 @@
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
|
||||||
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
|
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
|
||||||
"dev": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
|
@ -4137,8 +4326,7 @@
|
||||||
"node_modules/signal-exit": {
|
"node_modules/signal-exit": {
|
||||||
"version": "3.0.7",
|
"version": "3.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
|
||||||
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
|
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"node_modules/slice-ansi": {
|
"node_modules/slice-ansi": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
|
@ -4342,6 +4530,14 @@
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/strip-final-newline": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/strip-outer": {
|
"node_modules/strip-outer": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz",
|
||||||
|
@ -4616,7 +4812,6 @@
|
||||||
"version": "2.0.2",
|
"version": "2.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||||
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
|
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"isexe": "^2.0.0"
|
"isexe": "^2.0.0"
|
||||||
},
|
},
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
"license": "AGPL-3.0-or-later",
|
"license": "AGPL-3.0-or-later",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ffmpeg-static": "^5.1.0",
|
"ffmpeg-static": "^5.1.0",
|
||||||
|
"get-video-duration": "^4.1.0",
|
||||||
"typescript": "^5.1.6"
|
"typescript": "^5.1.6"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|
50
src/main.ts
50
src/main.ts
|
@ -1,8 +1,16 @@
|
||||||
import { BrowserWindow, app, dialog, ipcMain } from "electron";
|
import { BrowserWindow, app, dialog, ipcMain } from "electron";
|
||||||
import { unlink } from "fs";
|
import { unlink, statSync } from "fs";
|
||||||
import path = require("path");
|
import path = require("path");
|
||||||
import ffmpegPath = require("ffmpeg-static");
|
import ffmpegPath = require("ffmpeg-static");
|
||||||
import child_process = require("child_process");
|
import child_process = require("child_process");
|
||||||
|
import { getVideoDurationInSeconds } from "get-video-duration";
|
||||||
|
|
||||||
|
const moviesFilter = {
|
||||||
|
name: "Videos",
|
||||||
|
extensions: ["mp4", "mkv"],
|
||||||
|
};
|
||||||
|
|
||||||
|
const isWindows = process.platform === "win32";
|
||||||
|
|
||||||
/** Create a new window */
|
/** Create a new window */
|
||||||
const createWindow = () => {
|
const createWindow = () => {
|
||||||
|
@ -20,11 +28,6 @@ const createWindow = () => {
|
||||||
return win;
|
return win;
|
||||||
};
|
};
|
||||||
|
|
||||||
const moviesFilter = {
|
|
||||||
name: "Videos",
|
|
||||||
extensions: ["mp4", "mkv"],
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Create a new filename from the OG one */
|
/* Create a new filename from the OG one */
|
||||||
const getNewFilename = (ogFile: string, part: string) => {
|
const getNewFilename = (ogFile: string, part: string) => {
|
||||||
const oldFile = path.parse(ogFile);
|
const oldFile = path.parse(ogFile);
|
||||||
|
@ -32,18 +35,18 @@ const getNewFilename = (ogFile: string, part: string) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Merge all audios track of a video into one */
|
/** Merge all audios track of a video into one */
|
||||||
const mergeAudio = (file: string) => {
|
const mergeAudio = async (file: string) => {
|
||||||
const tmp_file = getNewFilename(file, "TMP_");
|
const tmp_file = getNewFilename(file, "TMP_");
|
||||||
const outFile = getNewFilename(file, "(merged audio) ");
|
const outFile = getNewFilename(file, "(merged audio) ");
|
||||||
|
|
||||||
// Merge 2 audio
|
// Merge 2 audio
|
||||||
child_process.execSync(
|
child_process.execSync(
|
||||||
`${ffmpegPath} -i "${file}" -filter_complex "[0:a]amerge=inputs=2[a]" -ac 1 -map 0:v -map "[a]" -c:v copy -y "${tmp_file}"`
|
`${ffmpegPath} -y -i "${file}" -filter_complex "[0:a]amerge=inputs=2[a]" -ac 1 -map 0:v -map "[a]" -c:v copy "${tmp_file}"`
|
||||||
);
|
);
|
||||||
|
|
||||||
// Add merged audio as first position to original video
|
// Add merged audio as first position to original video
|
||||||
child_process.execSync(
|
child_process.execSync(
|
||||||
`${ffmpegPath} -i "${tmp_file}" -i "${file}" -map 0 -map 1:a -c:v copy -y "${outFile}"`
|
`${ffmpegPath} -y -i "${tmp_file}" -i "${file}" -map 0 -map 1:a -c:v copy "${outFile}"`
|
||||||
);
|
);
|
||||||
|
|
||||||
// Delete the temporary file
|
// Delete the temporary file
|
||||||
|
@ -53,7 +56,31 @@ const mergeAudio = (file: string) => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return outFile;
|
const duration = await getVideoDurationInSeconds(outFile);
|
||||||
|
const stats = statSync(outFile);
|
||||||
|
|
||||||
|
return { title: outFile, size: stats.size / 1024 / 1024, duration };
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Reduce size of a file */
|
||||||
|
const reduceSize = (file: string, bitrate: number) => {
|
||||||
|
const audioBitrate = 128;
|
||||||
|
const videoBitrate = Math.floor(bitrate) - audioBitrate;
|
||||||
|
|
||||||
|
/* Trash the output, depends on the platform */
|
||||||
|
const nul = isWindows ? "NUL" : "/dev/null";
|
||||||
|
|
||||||
|
/* AND operator, depends on the platform */
|
||||||
|
const and = isWindows ? "^" : "&&";
|
||||||
|
|
||||||
|
const finalFile = getNewFilename(file, "Compressed - ");
|
||||||
|
|
||||||
|
child_process.execSync(
|
||||||
|
`${ffmpegPath} -y -i "${file}" -c:v libx264 -b:v ${videoBitrate}k -pass 1 -an -f null ${nul} ${and} \
|
||||||
|
${ffmpegPath} -y -i "${file}" -c:v libx264 -b:v ${videoBitrate}k -pass 2 -c:a aac -b:a ${audioBitrate}k "${finalFile}"`
|
||||||
|
);
|
||||||
|
|
||||||
|
return finalFile;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Ready to create the window */
|
/* Ready to create the window */
|
||||||
|
@ -78,6 +105,9 @@ app.whenReady().then(() => {
|
||||||
ipcMain.handle("allowedExtensions", () => moviesFilter);
|
ipcMain.handle("allowedExtensions", () => moviesFilter);
|
||||||
ipcMain.handle("askFile", () => askFile());
|
ipcMain.handle("askFile", () => askFile());
|
||||||
ipcMain.handle("mergeAudio", (_, file: string) => mergeAudio(file));
|
ipcMain.handle("mergeAudio", (_, file: string) => mergeAudio(file));
|
||||||
|
ipcMain.handle("reduceSize", (_, file: string, bitrate: number) =>
|
||||||
|
reduceSize(file, bitrate)
|
||||||
|
);
|
||||||
ipcMain.handle("exit", async () => app.quit());
|
ipcMain.handle("exit", async () => app.quit());
|
||||||
ipcMain.handle("confirmation", async (_, text: string) => confirmation(text));
|
ipcMain.handle("confirmation", async (_, text: string) => confirmation(text));
|
||||||
});
|
});
|
||||||
|
|
|
@ -6,6 +6,8 @@ contextBridge.exposeInMainWorld("internals", {
|
||||||
allowedExtensions: () => ipcRenderer.invoke("allowedExtensions"),
|
allowedExtensions: () => ipcRenderer.invoke("allowedExtensions"),
|
||||||
askFile: () => ipcRenderer.invoke("askFile"),
|
askFile: () => ipcRenderer.invoke("askFile"),
|
||||||
mergeAudio: (file: string) => ipcRenderer.invoke("mergeAudio", file),
|
mergeAudio: (file: string) => ipcRenderer.invoke("mergeAudio", file),
|
||||||
|
reduceSize: (file: string, bitrate: number) =>
|
||||||
|
ipcRenderer.invoke("reduceSize", file, bitrate),
|
||||||
exit: () => ipcRenderer.invoke("exit"),
|
exit: () => ipcRenderer.invoke("exit"),
|
||||||
confirmation: (text: string) => ipcRenderer.invoke("confirmation", text),
|
confirmation: (text: string) => ipcRenderer.invoke("confirmation", text),
|
||||||
});
|
});
|
||||||
|
|
|
@ -6,7 +6,10 @@ let internals: {
|
||||||
}>;
|
}>;
|
||||||
askFile: () => Promise<string[] | undefined>;
|
askFile: () => Promise<string[] | undefined>;
|
||||||
exit: () => Promise<void>;
|
exit: () => Promise<void>;
|
||||||
mergeAudio: (filename: string) => Promise<string>;
|
mergeAudio: (
|
||||||
|
filename: string
|
||||||
|
) => Promise<{ title: string; duration: number; size: number }>;
|
||||||
|
reduceSize: (file: string, bitrate: number) => Promise<string>;
|
||||||
confirmation: (text: string) => Promise<void>;
|
confirmation: (text: string) => Promise<void>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -30,9 +33,19 @@ const getFile = async () => {
|
||||||
|
|
||||||
/** Main function */
|
/** Main function */
|
||||||
const main = async () => {
|
const main = async () => {
|
||||||
|
const maxSizeDiscord = 25;
|
||||||
const file = await getFile();
|
const file = await getFile();
|
||||||
const newFile = await internals.mergeAudio(file);
|
const newFile = await internals.mergeAudio(file);
|
||||||
await internals.confirmation(`File ok @ ${newFile}!`);
|
let finalTitle = newFile.title;
|
||||||
|
if (newFile.size > maxSizeDiscord) {
|
||||||
|
const targetSize = maxSizeDiscord - 2;
|
||||||
|
finalTitle = await internals.reduceSize(
|
||||||
|
newFile.title,
|
||||||
|
// https://trac.ffmpeg.org/wiki/Encode/H.264#twopass
|
||||||
|
(targetSize * 8388.608) / newFile.duration
|
||||||
|
);
|
||||||
|
}
|
||||||
|
await internals.confirmation(`File ok @ ${finalTitle}!`);
|
||||||
await internals.exit();
|
await internals.exit();
|
||||||
};
|
};
|
||||||
main();
|
main();
|
||||||
|
|
Loading…
Reference in a new issue