diff --git a/package-lock.json b/package-lock.json index 5db3ab8b..d004d7a8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "lx-music-desktop", - "version": "2.2.2", + "version": "2.3.0-beta", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "lx-music-desktop", - "version": "2.2.2", + "version": "2.3.0-beta", "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { @@ -33,8 +33,8 @@ "ws": "^8.13.0" }, "devDependencies": { - "@babel/core": "^7.21.5", - "@babel/eslint-parser": "^7.21.3", + "@babel/core": "^7.21.8", + "@babel/eslint-parser": "^7.21.8", "@babel/plugin-proposal-class-properties": "^7.18.6", "@babel/plugin-syntax-dynamic-import": "^7.8.3", "@babel/plugin-transform-modules-umd": "^7.18.6", @@ -44,9 +44,9 @@ "@types/better-sqlite3": "^7.6.4", "@types/needle": "^3.2.0", "@types/tunnel": "^0.0.3", - "@typescript-eslint/eslint-plugin": "^5.59.1", - "@typescript-eslint/parser": "^5.59.1", - "@volar/vue-language-plugin-pug": "^1.6.1", + "@typescript-eslint/eslint-plugin": "^5.59.2", + "@typescript-eslint/parser": "^5.59.2", + "@volar/vue-language-plugin-pug": "^1.6.3", "babel-loader": "^9.1.2", "browserslist": "^4.21.5", "chalk": "^4.1.2", @@ -61,7 +61,7 @@ "electron-builder": "^24.3.0", "electron-debug": "^3.2.0", "electron-devtools-installer": "^3.2.0", - "electron-to-chromium": "^1.4.377", + "electron-to-chromium": "^1.4.380", "electron-updater": "^6.1.0", "eslint": "^8.39.0", "eslint-config-standard": "^17.0.0", @@ -92,7 +92,7 @@ "terser-webpack-plugin": "^5.3.7", "ts-loader": "^9.4.2", "typescript": "^5.0.4", - "vue-eslint-parser": "^9.1.1", + "vue-eslint-parser": "^9.2.0", "vue-loader": "^17.1.0", "vue-template-compiler": "^2.7.14", "webpack": "^5.81.0", @@ -141,9 +141,9 @@ } }, "node_modules/@babel/core": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.21.5.tgz", - "integrity": "sha512-9M398B/QH5DlfCOTKDZT1ozXr0x8uBEeFd+dJraGUZGiaNpGCDVGCc14hZexsMblw3XxltJ+6kSvogp9J+5a9g==", + "version": "7.21.8", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.21.8.tgz", + "integrity": "sha512-YeM22Sondbo523Sz0+CirSPnbj9bG3P0CdHcBZdqUuaeOaYEFbOLoGU7lebvGP6P5J/WE9wOn7u7C4J9HvS1xQ==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.0", @@ -152,7 +152,7 @@ "@babel/helper-compilation-targets": "^7.21.5", "@babel/helper-module-transforms": "^7.21.5", "@babel/helpers": "^7.21.5", - "@babel/parser": "^7.21.5", + "@babel/parser": "^7.21.8", "@babel/template": "^7.20.7", "@babel/traverse": "^7.21.5", "@babel/types": "^7.21.5", @@ -171,9 +171,9 @@ } }, "node_modules/@babel/eslint-parser": { - "version": "7.21.3", - "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.21.3.tgz", - "integrity": "sha512-kfhmPimwo6k4P8zxNs8+T7yR44q1LdpsZdE1NkCsVlfiuTPRfnGgjaF8Qgug9q9Pou17u6wneYF0lDCZJATMFg==", + "version": "7.21.8", + "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.21.8.tgz", + "integrity": "sha512-HLhI+2q+BP3sf78mFUZNCGc10KEmoUqtUT1OCdMZsN+qr4qFeLUod62/zAnF3jNQstwyasDkZnVXwfK2Bml7MQ==", "dev": true, "dependencies": { "@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1", @@ -639,9 +639,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.5.tgz", - "integrity": "sha512-J+IxH2IsxV4HbnTrSWgMAQj0UEo61hDA4Ny8h8PCX0MLXiibqHbqIOVneqdocemSBc22VpBKxt4J6FQzy9HarQ==", + "version": "7.21.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.8.tgz", + "integrity": "sha512-6zavDGdzG3gUqAdWvlLFfk+36RilI+Pwyuuh7HItyeScCWP3k6i8vKclAQ0bM/0y/Kz/xiwvxhMv9MgTJP5gmA==", "bin": { "parser": "bin/babel-parser.js" }, @@ -3069,15 +3069,15 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.59.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.1.tgz", - "integrity": "sha512-AVi0uazY5quFB9hlp2Xv+ogpfpk77xzsgsIEWyVS7uK/c7MZ5tw7ZPbapa0SbfkqE0fsAMkz5UwtgMLVk2BQAg==", + "version": "5.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.2.tgz", + "integrity": "sha512-yVrXupeHjRxLDcPKL10sGQ/QlVrA8J5IYOEWVqk0lJaSZP7X5DfnP7Ns3cc74/blmbipQ1htFNVGsHX6wsYm0A==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.59.1", - "@typescript-eslint/type-utils": "5.59.1", - "@typescript-eslint/utils": "5.59.1", + "@typescript-eslint/scope-manager": "5.59.2", + "@typescript-eslint/type-utils": "5.59.2", + "@typescript-eslint/utils": "5.59.2", "debug": "^4.3.4", "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", @@ -3136,14 +3136,14 @@ "dev": true }, "node_modules/@typescript-eslint/parser": { - "version": "5.59.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.1.tgz", - "integrity": "sha512-nzjFAN8WEu6yPRDizIFyzAfgK7nybPodMNFGNH0M9tei2gYnYszRDqVA0xlnRjkl7Hkx2vYrEdb6fP2a21cG1g==", + "version": "5.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.2.tgz", + "integrity": "sha512-uq0sKyw6ao1iFOZZGk9F8Nro/8+gfB5ezl1cA06SrqbgJAt0SRoFhb9pXaHvkrxUpZaoLxt8KlovHNk8Gp6/HQ==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.59.1", - "@typescript-eslint/types": "5.59.1", - "@typescript-eslint/typescript-estree": "5.59.1", + "@typescript-eslint/scope-manager": "5.59.2", + "@typescript-eslint/types": "5.59.2", + "@typescript-eslint/typescript-estree": "5.59.2", "debug": "^4.3.4" }, "engines": { @@ -3163,13 +3163,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.59.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.1.tgz", - "integrity": "sha512-mau0waO5frJctPuAzcxiNWqJR5Z8V0190FTSqRw1Q4Euop6+zTwHAf8YIXNwDOT29tyUDrQ65jSg9aTU/H0omA==", + "version": "5.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.2.tgz", + "integrity": "sha512-dB1v7ROySwQWKqQ8rEWcdbTsFjh2G0vn8KUyvTXdPoyzSL6lLGkiXEV5CvpJsEe9xIdKV+8Zqb7wif2issoOFA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.59.1", - "@typescript-eslint/visitor-keys": "5.59.1" + "@typescript-eslint/types": "5.59.2", + "@typescript-eslint/visitor-keys": "5.59.2" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -3180,13 +3180,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "5.59.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.1.tgz", - "integrity": "sha512-ZMWQ+Oh82jWqWzvM3xU+9y5U7MEMVv6GLioM3R5NJk6uvP47kZ7YvlgSHJ7ERD6bOY7Q4uxWm25c76HKEwIjZw==", + "version": "5.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.2.tgz", + "integrity": "sha512-b1LS2phBOsEy/T381bxkkywfQXkV1dWda/z0PhnIy3bC5+rQWQDS7fk9CSpcXBccPY27Z6vBEuaPBCKCgYezyQ==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "5.59.1", - "@typescript-eslint/utils": "5.59.1", + "@typescript-eslint/typescript-estree": "5.59.2", + "@typescript-eslint/utils": "5.59.2", "debug": "^4.3.4", "tsutils": "^3.21.0" }, @@ -3207,9 +3207,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "5.59.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.1.tgz", - "integrity": "sha512-dg0ICB+RZwHlysIy/Dh1SP+gnXNzwd/KS0JprD3Lmgmdq+dJAJnUPe1gNG34p0U19HvRlGX733d/KqscrGC1Pg==", + "version": "5.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.2.tgz", + "integrity": "sha512-LbJ/HqoVs2XTGq5shkiKaNTuVv5tTejdHgfdjqRUGdYhjW1crm/M7og2jhVskMt8/4wS3T1+PfFvL1K3wqYj4w==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -3220,13 +3220,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.59.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.1.tgz", - "integrity": "sha512-lYLBBOCsFltFy7XVqzX0Ju+Lh3WPIAWxYpmH/Q7ZoqzbscLiCW00LeYCdsUnnfnj29/s1WovXKh2gwCoinHNGA==", + "version": "5.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.2.tgz", + "integrity": "sha512-+j4SmbwVmZsQ9jEyBMgpuBD0rKwi9RxRpjX71Brr73RsYnEr3Lt5QZ624Bxphp8HUkSKfqGnPJp1kA5nl0Sh7Q==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.59.1", - "@typescript-eslint/visitor-keys": "5.59.1", + "@typescript-eslint/types": "5.59.2", + "@typescript-eslint/visitor-keys": "5.59.2", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -3280,17 +3280,17 @@ "dev": true }, "node_modules/@typescript-eslint/utils": { - "version": "5.59.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.1.tgz", - "integrity": "sha512-MkTe7FE+K1/GxZkP5gRj3rCztg45bEhsd8HYjczBuYm+qFHP5vtZmjx3B0yUCDotceQ4sHgTyz60Ycl225njmA==", + "version": "5.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.2.tgz", + "integrity": "sha512-kSuF6/77TZzyGPhGO4uVp+f0SBoYxCDf+lW3GKhtKru/L8k/Hd7NFQxyWUeY7Z/KGB2C6Fe3yf2vVi4V9TsCSQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.59.1", - "@typescript-eslint/types": "5.59.1", - "@typescript-eslint/typescript-estree": "5.59.1", + "@typescript-eslint/scope-manager": "5.59.2", + "@typescript-eslint/types": "5.59.2", + "@typescript-eslint/typescript-estree": "5.59.2", "eslint-scope": "^5.1.1", "semver": "^7.3.7" }, @@ -3339,12 +3339,12 @@ "dev": true }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.59.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.1.tgz", - "integrity": "sha512-6waEYwBTCWryx0VJmP7JaM4FpipLsFl9CvYf2foAE8Qh/Y0s+bxWysciwOs0LTBED4JCaNxTZ5rGadB14M6dwA==", + "version": "5.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.2.tgz", + "integrity": "sha512-EEpsO8m3RASrKAHI9jpavNv9NlEUebV4qmF1OWxSTtKSFBpC1NCmWazDQHFivRf0O1DV11BA645yrLEVQ0/Lig==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.59.1", + "@typescript-eslint/types": "5.59.2", "eslint-visitor-keys": "^3.3.0" }, "engines": { @@ -3440,9 +3440,9 @@ } }, "node_modules/@volar/vue-language-plugin-pug": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/@volar/vue-language-plugin-pug/-/vue-language-plugin-pug-1.6.1.tgz", - "integrity": "sha512-sWYj04ukFBiOaAu4fmGDxnVm/fODSJ2hQtEB0GTAUHGjz9EzaaBjV1gWd8sX6KnerWx6MxYQiy0LIK7z++3h2w==", + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/@volar/vue-language-plugin-pug/-/vue-language-plugin-pug-1.6.3.tgz", + "integrity": "sha512-XIRT/mLT4mwiLjEIZNZmw4Sm+A/yJcjhHBTgvxIcQGAkAfTcDBihKAyrHARCdPJbwy59EacmIFlJX4JgqCpfTQ==", "dev": true, "dependencies": { "@volar-plugins/pug": "2.0.0", @@ -7263,9 +7263,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.377", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.377.tgz", - "integrity": "sha512-H3BYG6DW5Z+l0xcfXaicJGxrpA4kMlCxnN71+iNX+dBLkRMOdVJqFJiAmbNZZKA1zISpRg17JR03qGifXNsJtw==", + "version": "1.4.380", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.380.tgz", + "integrity": "sha512-XKGdI4pWM78eLH2cbXJHiBnWUwFSzZM7XujsB6stDiGu9AeSqziedP6amNLpJzE3i0rLTcfAwdCTs5ecP5yeSg==", "dev": true }, "node_modules/electron-updater": { @@ -17405,9 +17405,9 @@ } }, "node_modules/vue-eslint-parser": { - "version": "9.1.1", - "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.1.1.tgz", - "integrity": "sha512-C2aI/r85Q6tYcz4dpgvrs4wH/MqVrRAVIdpYedrxnATDHHkb+TroeRcDpKWGZCx/OcECMWfz7tVwQ8e+Opy6rA==", + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.2.0.tgz", + "integrity": "sha512-aFXipsUbKU4TzgP9OU6cXIm2Nnp9ryKJc2mzY0s2xzwfjHg6WDT33LUAQRGR9K0NFncBgUEZ2njdrS3Lj/sOLw==", "dev": true, "dependencies": { "debug": "^4.3.4", @@ -18097,9 +18097,9 @@ "dev": true }, "@babel/core": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.21.5.tgz", - "integrity": "sha512-9M398B/QH5DlfCOTKDZT1ozXr0x8uBEeFd+dJraGUZGiaNpGCDVGCc14hZexsMblw3XxltJ+6kSvogp9J+5a9g==", + "version": "7.21.8", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.21.8.tgz", + "integrity": "sha512-YeM22Sondbo523Sz0+CirSPnbj9bG3P0CdHcBZdqUuaeOaYEFbOLoGU7lebvGP6P5J/WE9wOn7u7C4J9HvS1xQ==", "dev": true, "requires": { "@ampproject/remapping": "^2.2.0", @@ -18108,7 +18108,7 @@ "@babel/helper-compilation-targets": "^7.21.5", "@babel/helper-module-transforms": "^7.21.5", "@babel/helpers": "^7.21.5", - "@babel/parser": "^7.21.5", + "@babel/parser": "^7.21.8", "@babel/template": "^7.20.7", "@babel/traverse": "^7.21.5", "@babel/types": "^7.21.5", @@ -18120,9 +18120,9 @@ } }, "@babel/eslint-parser": { - "version": "7.21.3", - "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.21.3.tgz", - "integrity": "sha512-kfhmPimwo6k4P8zxNs8+T7yR44q1LdpsZdE1NkCsVlfiuTPRfnGgjaF8Qgug9q9Pou17u6wneYF0lDCZJATMFg==", + "version": "7.21.8", + "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.21.8.tgz", + "integrity": "sha512-HLhI+2q+BP3sf78mFUZNCGc10KEmoUqtUT1OCdMZsN+qr4qFeLUod62/zAnF3jNQstwyasDkZnVXwfK2Bml7MQ==", "dev": true, "requires": { "@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1", @@ -18474,9 +18474,9 @@ } }, "@babel/parser": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.5.tgz", - "integrity": "sha512-J+IxH2IsxV4HbnTrSWgMAQj0UEo61hDA4Ny8h8PCX0MLXiibqHbqIOVneqdocemSBc22VpBKxt4J6FQzy9HarQ==" + "version": "7.21.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.8.tgz", + "integrity": "sha512-6zavDGdzG3gUqAdWvlLFfk+36RilI+Pwyuuh7HItyeScCWP3k6i8vKclAQ0bM/0y/Kz/xiwvxhMv9MgTJP5gmA==" }, "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { "version": "7.18.6", @@ -20276,15 +20276,15 @@ } }, "@typescript-eslint/eslint-plugin": { - "version": "5.59.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.1.tgz", - "integrity": "sha512-AVi0uazY5quFB9hlp2Xv+ogpfpk77xzsgsIEWyVS7uK/c7MZ5tw7ZPbapa0SbfkqE0fsAMkz5UwtgMLVk2BQAg==", + "version": "5.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.2.tgz", + "integrity": "sha512-yVrXupeHjRxLDcPKL10sGQ/QlVrA8J5IYOEWVqk0lJaSZP7X5DfnP7Ns3cc74/blmbipQ1htFNVGsHX6wsYm0A==", "dev": true, "requires": { "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.59.1", - "@typescript-eslint/type-utils": "5.59.1", - "@typescript-eslint/utils": "5.59.1", + "@typescript-eslint/scope-manager": "5.59.2", + "@typescript-eslint/type-utils": "5.59.2", + "@typescript-eslint/utils": "5.59.2", "debug": "^4.3.4", "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", @@ -20320,53 +20320,53 @@ } }, "@typescript-eslint/parser": { - "version": "5.59.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.1.tgz", - "integrity": "sha512-nzjFAN8WEu6yPRDizIFyzAfgK7nybPodMNFGNH0M9tei2gYnYszRDqVA0xlnRjkl7Hkx2vYrEdb6fP2a21cG1g==", + "version": "5.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.2.tgz", + "integrity": "sha512-uq0sKyw6ao1iFOZZGk9F8Nro/8+gfB5ezl1cA06SrqbgJAt0SRoFhb9pXaHvkrxUpZaoLxt8KlovHNk8Gp6/HQ==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.59.1", - "@typescript-eslint/types": "5.59.1", - "@typescript-eslint/typescript-estree": "5.59.1", + "@typescript-eslint/scope-manager": "5.59.2", + "@typescript-eslint/types": "5.59.2", + "@typescript-eslint/typescript-estree": "5.59.2", "debug": "^4.3.4" } }, "@typescript-eslint/scope-manager": { - "version": "5.59.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.1.tgz", - "integrity": "sha512-mau0waO5frJctPuAzcxiNWqJR5Z8V0190FTSqRw1Q4Euop6+zTwHAf8YIXNwDOT29tyUDrQ65jSg9aTU/H0omA==", + "version": "5.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.2.tgz", + "integrity": "sha512-dB1v7ROySwQWKqQ8rEWcdbTsFjh2G0vn8KUyvTXdPoyzSL6lLGkiXEV5CvpJsEe9xIdKV+8Zqb7wif2issoOFA==", "dev": true, "requires": { - "@typescript-eslint/types": "5.59.1", - "@typescript-eslint/visitor-keys": "5.59.1" + "@typescript-eslint/types": "5.59.2", + "@typescript-eslint/visitor-keys": "5.59.2" } }, "@typescript-eslint/type-utils": { - "version": "5.59.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.1.tgz", - "integrity": "sha512-ZMWQ+Oh82jWqWzvM3xU+9y5U7MEMVv6GLioM3R5NJk6uvP47kZ7YvlgSHJ7ERD6bOY7Q4uxWm25c76HKEwIjZw==", + "version": "5.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.2.tgz", + "integrity": "sha512-b1LS2phBOsEy/T381bxkkywfQXkV1dWda/z0PhnIy3bC5+rQWQDS7fk9CSpcXBccPY27Z6vBEuaPBCKCgYezyQ==", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "5.59.1", - "@typescript-eslint/utils": "5.59.1", + "@typescript-eslint/typescript-estree": "5.59.2", + "@typescript-eslint/utils": "5.59.2", "debug": "^4.3.4", "tsutils": "^3.21.0" } }, "@typescript-eslint/types": { - "version": "5.59.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.1.tgz", - "integrity": "sha512-dg0ICB+RZwHlysIy/Dh1SP+gnXNzwd/KS0JprD3Lmgmdq+dJAJnUPe1gNG34p0U19HvRlGX733d/KqscrGC1Pg==", + "version": "5.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.2.tgz", + "integrity": "sha512-LbJ/HqoVs2XTGq5shkiKaNTuVv5tTejdHgfdjqRUGdYhjW1crm/M7og2jhVskMt8/4wS3T1+PfFvL1K3wqYj4w==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "5.59.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.1.tgz", - "integrity": "sha512-lYLBBOCsFltFy7XVqzX0Ju+Lh3WPIAWxYpmH/Q7ZoqzbscLiCW00LeYCdsUnnfnj29/s1WovXKh2gwCoinHNGA==", + "version": "5.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.2.tgz", + "integrity": "sha512-+j4SmbwVmZsQ9jEyBMgpuBD0rKwi9RxRpjX71Brr73RsYnEr3Lt5QZ624Bxphp8HUkSKfqGnPJp1kA5nl0Sh7Q==", "dev": true, "requires": { - "@typescript-eslint/types": "5.59.1", - "@typescript-eslint/visitor-keys": "5.59.1", + "@typescript-eslint/types": "5.59.2", + "@typescript-eslint/visitor-keys": "5.59.2", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -20401,17 +20401,17 @@ } }, "@typescript-eslint/utils": { - "version": "5.59.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.1.tgz", - "integrity": "sha512-MkTe7FE+K1/GxZkP5gRj3rCztg45bEhsd8HYjczBuYm+qFHP5vtZmjx3B0yUCDotceQ4sHgTyz60Ycl225njmA==", + "version": "5.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.2.tgz", + "integrity": "sha512-kSuF6/77TZzyGPhGO4uVp+f0SBoYxCDf+lW3GKhtKru/L8k/Hd7NFQxyWUeY7Z/KGB2C6Fe3yf2vVi4V9TsCSQ==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.59.1", - "@typescript-eslint/types": "5.59.1", - "@typescript-eslint/typescript-estree": "5.59.1", + "@typescript-eslint/scope-manager": "5.59.2", + "@typescript-eslint/types": "5.59.2", + "@typescript-eslint/typescript-estree": "5.59.2", "eslint-scope": "^5.1.1", "semver": "^7.3.7" }, @@ -20443,12 +20443,12 @@ } }, "@typescript-eslint/visitor-keys": { - "version": "5.59.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.1.tgz", - "integrity": "sha512-6waEYwBTCWryx0VJmP7JaM4FpipLsFl9CvYf2foAE8Qh/Y0s+bxWysciwOs0LTBED4JCaNxTZ5rGadB14M6dwA==", + "version": "5.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.2.tgz", + "integrity": "sha512-EEpsO8m3RASrKAHI9jpavNv9NlEUebV4qmF1OWxSTtKSFBpC1NCmWazDQHFivRf0O1DV11BA645yrLEVQ0/Lig==", "dev": true, "requires": { - "@typescript-eslint/types": "5.59.1", + "@typescript-eslint/types": "5.59.2", "eslint-visitor-keys": "^3.3.0" }, "dependencies": { @@ -20521,9 +20521,9 @@ } }, "@volar/vue-language-plugin-pug": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/@volar/vue-language-plugin-pug/-/vue-language-plugin-pug-1.6.1.tgz", - "integrity": "sha512-sWYj04ukFBiOaAu4fmGDxnVm/fODSJ2hQtEB0GTAUHGjz9EzaaBjV1gWd8sX6KnerWx6MxYQiy0LIK7z++3h2w==", + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/@volar/vue-language-plugin-pug/-/vue-language-plugin-pug-1.6.3.tgz", + "integrity": "sha512-XIRT/mLT4mwiLjEIZNZmw4Sm+A/yJcjhHBTgvxIcQGAkAfTcDBihKAyrHARCdPJbwy59EacmIFlJX4JgqCpfTQ==", "dev": true, "requires": { "@volar-plugins/pug": "2.0.0", @@ -23485,9 +23485,9 @@ } }, "electron-to-chromium": { - "version": "1.4.377", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.377.tgz", - "integrity": "sha512-H3BYG6DW5Z+l0xcfXaicJGxrpA4kMlCxnN71+iNX+dBLkRMOdVJqFJiAmbNZZKA1zISpRg17JR03qGifXNsJtw==", + "version": "1.4.380", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.380.tgz", + "integrity": "sha512-XKGdI4pWM78eLH2cbXJHiBnWUwFSzZM7XujsB6stDiGu9AeSqziedP6amNLpJzE3i0rLTcfAwdCTs5ecP5yeSg==", "dev": true }, "electron-updater": { @@ -31235,9 +31235,9 @@ } }, "vue-eslint-parser": { - "version": "9.1.1", - "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.1.1.tgz", - "integrity": "sha512-C2aI/r85Q6tYcz4dpgvrs4wH/MqVrRAVIdpYedrxnATDHHkb+TroeRcDpKWGZCx/OcECMWfz7tVwQ8e+Opy6rA==", + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.2.0.tgz", + "integrity": "sha512-aFXipsUbKU4TzgP9OU6cXIm2Nnp9ryKJc2mzY0s2xzwfjHg6WDT33LUAQRGR9K0NFncBgUEZ2njdrS3Lj/sOLw==", "dev": true, "requires": { "debug": "^4.3.4", diff --git a/package.json b/package.json index e4f11c78..0a2293e4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "lx-music-desktop", - "version": "2.2.2", + "version": "2.3.0-beta", "description": "一个免费的音乐查找助手", "main": "./dist/main.js", "productName": "lx-music-desktop", @@ -205,8 +205,8 @@ }, "homepage": "https://github.com/lyswhut/lx-music-desktop#readme", "devDependencies": { - "@babel/core": "^7.21.5", - "@babel/eslint-parser": "^7.21.3", + "@babel/core": "^7.21.8", + "@babel/eslint-parser": "^7.21.8", "@babel/plugin-proposal-class-properties": "^7.18.6", "@babel/plugin-syntax-dynamic-import": "^7.8.3", "@babel/plugin-transform-modules-umd": "^7.18.6", @@ -216,9 +216,9 @@ "@types/better-sqlite3": "^7.6.4", "@types/needle": "^3.2.0", "@types/tunnel": "^0.0.3", - "@typescript-eslint/eslint-plugin": "^5.59.1", - "@typescript-eslint/parser": "^5.59.1", - "@volar/vue-language-plugin-pug": "^1.6.1", + "@typescript-eslint/eslint-plugin": "^5.59.2", + "@typescript-eslint/parser": "^5.59.2", + "@volar/vue-language-plugin-pug": "^1.6.3", "babel-loader": "^9.1.2", "browserslist": "^4.21.5", "chalk": "^4.1.2", @@ -233,7 +233,7 @@ "electron-builder": "^24.3.0", "electron-debug": "^3.2.0", "electron-devtools-installer": "^3.2.0", - "electron-to-chromium": "^1.4.377", + "electron-to-chromium": "^1.4.380", "electron-updater": "^6.1.0", "eslint": "^8.39.0", "eslint-config-standard": "^17.0.0", @@ -264,7 +264,7 @@ "terser-webpack-plugin": "^5.3.7", "ts-loader": "^9.4.2", "typescript": "^5.0.4", - "vue-eslint-parser": "^9.1.1", + "vue-eslint-parser": "^9.2.0", "vue-loader": "^17.1.0", "vue-template-compiler": "^2.7.14", "webpack": "^5.81.0", diff --git a/publish/changeLog.md b/publish/changeLog.md index 2b85a889..349046fe 100644 --- a/publish/changeLog.md +++ b/publish/changeLog.md @@ -1,4 +1,3 @@ -### 修复 +### 新增 -- 修复在低版本Linux amd64系统上无法启动的问题(glibc版本要求过高导致的,采用内置预编译二进制文件的方式解决) -- 修复添加歌曲弹窗默认列表名字显示问题 +- 新增音效设置(实验性功能),支持16段均衡器设置、3D立体环绕音效、内置的几个环境音效 diff --git a/src/common/defaultSetting.ts b/src/common/defaultSetting.ts index eb3240e1..b8d88764 100644 --- a/src/common/defaultSetting.ts +++ b/src/common/defaultSetting.ts @@ -40,6 +40,20 @@ const defaultSetting: LX.AppSetting = { 'player.waitPlayEndStop': true, 'player.waitPlayEndStopTime': '', 'player.autoSkipOnError': true, + 'player.soundEffect.convolution.fileName': '', + 'player.soundEffect.biquadFilter.hz31': 0, + 'player.soundEffect.biquadFilter.hz62': 0, + 'player.soundEffect.biquadFilter.hz125': 0, + 'player.soundEffect.biquadFilter.hz250': 0, + 'player.soundEffect.biquadFilter.hz500': 0, + 'player.soundEffect.biquadFilter.hz1000': 0, + 'player.soundEffect.biquadFilter.hz2000': 0, + 'player.soundEffect.biquadFilter.hz4000': 0, + 'player.soundEffect.biquadFilter.hz8000': 0, + 'player.soundEffect.biquadFilter.hz16000': 0, + 'player.soundEffect.panner.enable': false, + 'player.soundEffect.panner.soundR': 5, + 'player.soundEffect.panner.speed': 25, 'playDetail.isZoomActiveLrc': false, 'playDetail.isShowLyricProgressSetting': false, diff --git a/src/common/types/app_setting.d.ts b/src/common/types/app_setting.d.ts index a0e23abf..458c3bc6 100644 --- a/src/common/types/app_setting.d.ts +++ b/src/common/types/app_setting.d.ts @@ -163,6 +163,76 @@ declare global { */ 'player.waitPlayEndStopTime': string + /** + * 环境音效文件名 + */ + 'player.soundEffect.convolution.fileName': string | null + + /** + * 均衡器 31hz 值 + */ + 'player.soundEffect.biquadFilter.hz31': number + + /** + * 均衡器 62hz 值 + */ + 'player.soundEffect.biquadFilter.hz62': number + + /** + * 均衡器 125hz 值 + */ + 'player.soundEffect.biquadFilter.hz125': number + + /** + * 均衡器 250hz 值 + */ + 'player.soundEffect.biquadFilter.hz250': number + + /** + * 均衡器 500hz 值 + */ + 'player.soundEffect.biquadFilter.hz500': number + + /** + * 均衡器 1000hz 值 + */ + 'player.soundEffect.biquadFilter.hz1000': number + + /** + * 均衡器 2000hz 值 + */ + 'player.soundEffect.biquadFilter.hz2000': number + + /** + * 均衡器 4000hz 值 + */ + 'player.soundEffect.biquadFilter.hz4000': number + + /** + * 均衡器 8000hz 值 + */ + 'player.soundEffect.biquadFilter.hz8000': number + + /** + * 均衡器 16000hz 值 + */ + 'player.soundEffect.biquadFilter.hz16000': number + + /** + * 3D立体环绕是否启用 + */ + 'player.soundEffect.panner.enable': boolean + + /** + * 3D立体环绕声音距离 + */ + 'player.soundEffect.panner.soundR': number + + /** + * 3D立体环绕速度 + */ + 'player.soundEffect.panner.speed': number + /** * 是否启用音频加载失败时自动切歌 */ diff --git a/src/lang/en-us.json b/src/lang/en-us.json index 4ed978dd..20b813d1 100644 --- a/src/lang/en-us.json +++ b/src/lang/en-us.json @@ -9,10 +9,10 @@ "btn_save": "Save", "cancel_button_text": "Cancel", "close": "Close", - "comment__location": "From{location}", "comment__hot_load_error": "Hot comments failed to load, click to try to reload", "comment__hot_loading": "Hot comments are loading", "comment__hot_title": "Hot Comment", + "comment__location": "From{location}", "comment__new_load_error": "The latest comment failed to load, click to try to reload", "comment__new_loading": "Latest comments are loading", "comment__new_title": "Latest comment", @@ -78,8 +78,6 @@ "history_search": "History Searches", "import": "Import", "leaderboard": "Charts", - "list__name_default": "Default", - "list__name_love": "Love", "list__add_to": "Add to ...", "list__collect": "Collect", "list__copy_name": "Copy name", @@ -95,6 +93,8 @@ "list__move_to": "Move to ...", "list__movedown": "Movedown", "list__moveup": "Move up", + "list__name_default": "Default", + "list__name_love": "Love", "list__new_list_btn": "New List", "list__new_list_input": "New list...", "list__pause": "Pause Task", @@ -227,6 +227,19 @@ "player__playing": "Now playing...", "player__prev": "Prev", "player__refresh_url": "Music URL expired, refreshing...", + "player__sound_effect_biquad_filter": "Equalizer", + "player__sound_effect_biquad_filter_reset_btn": "Reset equalizer", + "player__sound_effect_convolution": "Ambient sound", + "player__sound_effect_convolution_bedroom": "Hall", + "player__sound_effect_convolution_church": "Church", + "player__sound_effect_convolution_feedback_spring": "Cave", + "player__sound_effect_convolution_kitchen": "Kitchen", + "player__sound_effect_convolution_spreader": "Indoor", + "player__sound_effect_convolution_telephone": "Telephone", + "player__sound_effect_panner": "3D stereo surround (need to use headphones)", + "player__sound_effect_panner_enabled": "enable", + "player__sound_effect_panner_sound_r": "Sound distance", + "player__sound_effect_panner_sound_speed": "Surround speed", "player__stop": "Paused", "player__volume": "Volume: ", "player__volume_mute_label": "Mute", diff --git a/src/lang/zh-cn.json b/src/lang/zh-cn.json index e87d7620..90879693 100644 --- a/src/lang/zh-cn.json +++ b/src/lang/zh-cn.json @@ -9,10 +9,10 @@ "btn_save": "保存", "cancel_button_text": "我不", "close": "关闭", - "comment__location": "来自{location}", "comment__hot_load_error": "热门评论加载失败,点击尝试重新加载", "comment__hot_loading": "热门评论加载中", "comment__hot_title": "热门评论", + "comment__location": "来自{location}", "comment__new_load_error": "最新评论加载失败,点击尝试重新加载", "comment__new_loading": "最新评论加载中", "comment__new_title": "最新评论", @@ -78,8 +78,6 @@ "history_search": "历史搜索", "import": "导入", "leaderboard": "排行榜", - "list__name_default": "试听列表", - "list__name_love": "我的收藏", "list__add_to": "添加到...", "list__collect": "收藏", "list__copy_name": "复制歌曲名", @@ -95,6 +93,8 @@ "list__move_to": "移动到...", "list__movedown": "下移", "list__moveup": "上移", + "list__name_default": "试听列表", + "list__name_love": "我的收藏", "list__new_list_btn": "新建列表", "list__new_list_input": "新列表...", "list__pause": "暂停任务", @@ -227,6 +227,19 @@ "player__playing": "播放中...", "player__prev": "上一首", "player__refresh_url": "URL过期,正在刷新URL...", + "player__sound_effect_biquad_filter": "均衡器", + "player__sound_effect_biquad_filter_reset_btn": "重置均衡器", + "player__sound_effect_convolution": "环境音效", + "player__sound_effect_convolution_bedroom": "大厅", + "player__sound_effect_convolution_church": "教堂", + "player__sound_effect_convolution_feedback_spring": "山洞", + "player__sound_effect_convolution_kitchen": "厨房", + "player__sound_effect_convolution_spreader": "室内", + "player__sound_effect_convolution_telephone": "电话", + "player__sound_effect_panner": "3D立体环绕(需使用耳机)", + "player__sound_effect_panner_enabled": "启用", + "player__sound_effect_panner_sound_r": "声音距离", + "player__sound_effect_panner_sound_speed": "环绕速度", "player__stop": "暂停播放", "player__volume": "当前音量:", "player__volume_mute_label": "静音", diff --git a/src/lang/zh-tw.json b/src/lang/zh-tw.json index 9a7d1dda..a6c80bf0 100644 --- a/src/lang/zh-tw.json +++ b/src/lang/zh-tw.json @@ -9,10 +9,10 @@ "btn_save": "保存", "cancel_button_text": "取消", "close": "關閉", - "comment__location": "來自{location}", "comment__hot_load_error": "熱門評論加載失敗,點擊嘗試重新加載", "comment__hot_loading": "熱門評論加載中", "comment__hot_title": "熱門評論", + "comment__location": "來自{location}", "comment__new_load_error": "最新評論加載失敗,點擊嘗試重新加載", "comment__new_loading": "最新評論加載中", "comment__new_title": "最新評論", @@ -78,8 +78,6 @@ "history_search": "歷史搜索", "import": "導入", "leaderboard": "排行榜", - "list__name_default": "試聽清單", - "list__name_love": "我的收藏", "list__add_to": "添加到...", "list__collect": "收藏", "list__copy_name": "複製歌曲名", @@ -95,6 +93,8 @@ "list__move_to": "移動到...", "list__movedown": "下移", "list__moveup": "上移", + "list__name_default": "試聽清單", + "list__name_love": "我的收藏", "list__new_list_btn": "新建列表", "list__new_list_input": "新列表...", "list__pause": "暫停任務", @@ -227,6 +227,19 @@ "player__playing": "播放中...", "player__prev": "上一首", "player__refresh_url": "URL過期,正在刷新URL...", + "player__sound_effect_biquad_filter": "均衡器", + "player__sound_effect_biquad_filter_reset_btn": "重置均衡器", + "player__sound_effect_convolution": "環境音效", + "player__sound_effect_convolution_bedroom": "大廳", + "player__sound_effect_convolution_church": "教堂", + "player__sound_effect_convolution_feedback_spring": "山洞", + "player__sound_effect_convolution_kitchen": "廚房", + "player__sound_effect_convolution_spreader": "室內", + "player__sound_effect_convolution_telephone": "電話", + "player__sound_effect_panner": "3D立體環繞(需使用耳機)", + "player__sound_effect_panner_enabled": "啟用", + "player__sound_effect_panner_sound_r": "聲音距離", + "player__sound_effect_panner_sound_speed": "環繞速度", "player__stop": "暫停播放", "player__volume": "當前音量:", "player__volume_mute_label": "靜音", diff --git a/src/renderer/assets/svgs/tune-variant.svg b/src/renderer/assets/svgs/tune-variant.svg new file mode 100644 index 00000000..02314ad1 --- /dev/null +++ b/src/renderer/assets/svgs/tune-variant.svg @@ -0,0 +1,5 @@ + + + diff --git a/src/renderer/components/common/BiquadFilterBtn.vue b/src/renderer/components/common/BiquadFilterBtn.vue new file mode 100644 index 00000000..beefd632 --- /dev/null +++ b/src/renderer/components/common/BiquadFilterBtn.vue @@ -0,0 +1,211 @@ + + + + + + + + + + + {{ $t('player__sound_effect_biquad_filter') }} + + + {{ v }} + + {{ values[i] }}db + + + + + {{ $t('player__sound_effect_biquad_filter_reset_btn') }} + + + + {{ $t('player__sound_effect_convolution') }} + + + + + + + + + + + + diff --git a/src/renderer/components/common/SoundEffectBtn/AudioConvolution.vue b/src/renderer/components/common/SoundEffectBtn/AudioConvolution.vue new file mode 100644 index 00000000..c1a65161 --- /dev/null +++ b/src/renderer/components/common/SoundEffectBtn/AudioConvolution.vue @@ -0,0 +1,48 @@ + + + {{ $t('player__sound_effect_convolution') }} + + + + + + + + + diff --git a/src/renderer/components/common/SoundEffectBtn/AudioPanner.vue b/src/renderer/components/common/SoundEffectBtn/AudioPanner.vue new file mode 100644 index 00000000..f664b6f1 --- /dev/null +++ b/src/renderer/components/common/SoundEffectBtn/AudioPanner.vue @@ -0,0 +1,116 @@ + + + + {{ $t('player__sound_effect_panner') }} + + + + + {{ $t('player__sound_effect_panner_sound_r') }} + + {{ appSetting['player.soundEffect.panner.soundR'] }} + + + {{ $t('player__sound_effect_panner_sound_speed') }} + + {{ appSetting['player.soundEffect.panner.speed'] }} + + + + + + + + diff --git a/src/renderer/components/common/SoundEffectBtn/BiquadFilter.vue b/src/renderer/components/common/SoundEffectBtn/BiquadFilter.vue new file mode 100644 index 00000000..5a65deb2 --- /dev/null +++ b/src/renderer/components/common/SoundEffectBtn/BiquadFilter.vue @@ -0,0 +1,98 @@ + + + + {{ $t('player__sound_effect_biquad_filter') }} + {{ $t('player__sound_effect_biquad_filter_reset_btn') }} + + + + {{ labels[i] }} + + {{ appSetting[`player.soundEffect.biquadFilter.hz${v}`] }}db + + + + + + + + + diff --git a/src/renderer/components/common/SoundEffectBtn/index.vue b/src/renderer/components/common/SoundEffectBtn/index.vue new file mode 100644 index 00000000..2d15f5ff --- /dev/null +++ b/src/renderer/components/common/SoundEffectBtn/index.vue @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/src/renderer/components/layout/PlayDetail/components/ControlBtns.vue b/src/renderer/components/layout/PlayDetail/components/ControlBtns.vue index f9c9a52f..6f871975 100644 --- a/src/renderer/components/layout/PlayDetail/components/ControlBtns.vue +++ b/src/renderer/components/layout/PlayDetail/components/ControlBtns.vue @@ -14,6 +14,7 @@ div(:class="$style.footerLeftControlBtns") button(:class="[$style.footerLeftControlBtn, {[$style.active]: isShowPlayComment}]" @click="toggleVisibleComment" :aria-label="$t('comment__show')") svg(version='1.1' xmlns='http://www.w3.org/2000/svg' xlink='http://www.w3.org/1999/xlink' width='95%' viewBox='0 0 24 24' space='preserve') use(xlink:href='#icon-comment') + common-sound-effect-btn common-playback-rate-btn common-volume-btn common-toggle-play-mode-btn diff --git a/src/renderer/core/useApp/usePlayer/usePlayer.ts b/src/renderer/core/useApp/usePlayer/usePlayer.ts index 5ec160dc..14d417a8 100644 --- a/src/renderer/core/useApp/usePlayer/usePlayer.ts +++ b/src/renderer/core/useApp/usePlayer/usePlayer.ts @@ -31,6 +31,7 @@ import useWatchList from './useWatchList' import { HOTKEY_PLAYER } from '@common/hotKey' import { playNext, pause, playPrev, togglePlay } from '@renderer/core/player' import usePlaybackRate from './usePlaybackRate' +import useSoundEffect from './useSoundEffect' export default () => { @@ -41,6 +42,7 @@ export default () => { usePlayEvent() useLyric() useVolume() + useSoundEffect() usePlaybackRate() useWatchList() diff --git a/src/renderer/core/useApp/usePlayer/useSoundEffect.ts b/src/renderer/core/useApp/usePlayer/useSoundEffect.ts new file mode 100644 index 00000000..109d922d --- /dev/null +++ b/src/renderer/core/useApp/usePlayer/useSoundEffect.ts @@ -0,0 +1,147 @@ +import { watch } from '@common/utils/vueTools' +import { + freqs, + convolutions, + getAudioContext, + getBiquadFilter, + setConvolver, + setPannerSoundR, + setPannerSpeed, + startPanner, + stopPanner, +} from '@renderer/plugins/player' + +import { appSetting } from '@renderer/store/setting' + +const cache = new Map() +const loadBuffer = async(name: string) => new Promise((resolve, reject) => { + // eslint-disable-next-line @typescript-eslint/no-var-requires + const path = require('@static/medias/filters/' + name) as string + if (cache.has(path)) { + resolve(cache.get(path) as AudioBuffer) + return + } + // Load buffer asynchronously + let request = new XMLHttpRequest() + request.open('GET', path, true) + request.responseType = 'arraybuffer' + + request.onload = function() { + // Asynchronously decode the audio file data in request.response + void getAudioContext().decodeAudioData(request.response, (buffer) => { + if (!buffer) { + reject(new Error('error decoding file data: ' + path)) + return + } + cache.set(path, buffer) + resolve(buffer) + }, + function(error) { + reject(error) + console.error('decodeAudioData error', error) + }) + } + + request.onerror = function() { + reject(new Error('XHR error')) + } + + request.send() +}) + +export default () => { + console.log(appSetting['player.soundEffect.panner.enable']) + if (appSetting['player.soundEffect.panner.enable']) startPanner() + setPannerSoundR(appSetting['player.soundEffect.panner.soundR'] / 10) + setPannerSpeed(2 * (appSetting['player.soundEffect.panner.speed'] / 10)) + if (freqs.some(v => appSetting[`player.soundEffect.biquadFilter.hz${v}`] != 0)) { + const bfs = getBiquadFilter() + for (const item of freqs) { + bfs.get(`hz${item}`)!.gain.value = appSetting[`player.soundEffect.biquadFilter.hz${item}`] + } + } + if (appSetting['player.soundEffect.convolution.fileName']) { + void loadBuffer(appSetting['player.soundEffect.convolution.fileName']).then((buffer) => { + const target = convolutions.find(c => c.source == appSetting['player.soundEffect.convolution.fileName']) + setConvolver(buffer, target!.sendGain, target!.mainGain) + }) + } + + + watch(() => appSetting['player.soundEffect.panner.enable'], (enable) => { + if (enable) { + startPanner() + } else { + stopPanner() + } + }) + watch(() => appSetting['player.soundEffect.panner.soundR'], (soundR) => { + setPannerSoundR(soundR / 10) + }) + watch(() => appSetting['player.soundEffect.panner.speed'], (speed) => { + setPannerSpeed(2 * (speed / 10)) + }) + watch(() => appSetting['player.soundEffect.convolution.fileName'], (fileName) => { + setTimeout(() => { + if (fileName) { + void loadBuffer(fileName).then((buffer) => { + const target = convolutions.find(c => c.source == fileName) + setConvolver(buffer, target!.sendGain, target!.mainGain) + }) + } else { + setConvolver(null, 0, 0) + } + }) + }) + watch(() => appSetting['player.soundEffect.biquadFilter.hz31'], (hz31) => { + const bfs = getBiquadFilter() + bfs.get('hz31')!.gain.value = hz31 + }) + watch(() => appSetting['player.soundEffect.biquadFilter.hz62'], (hz62) => { + const bfs = getBiquadFilter() + bfs.get('hz62')!.gain.value = hz62 + }) + watch(() => appSetting['player.soundEffect.biquadFilter.hz125'], (hz125) => { + const bfs = getBiquadFilter() + bfs.get('hz125')!.gain.value = hz125 + }) + watch(() => appSetting['player.soundEffect.biquadFilter.hz250'], (hz250) => { + const bfs = getBiquadFilter() + bfs.get('hz250')!.gain.value = hz250 + }) + watch(() => appSetting['player.soundEffect.biquadFilter.hz500'], (hz500) => { + const bfs = getBiquadFilter() + bfs.get('hz500')!.gain.value = hz500 + }) + watch(() => appSetting['player.soundEffect.biquadFilter.hz1000'], (hz1000) => { + const bfs = getBiquadFilter() + bfs.get('hz1000')!.gain.value = hz1000 + }) + watch(() => appSetting['player.soundEffect.biquadFilter.hz2000'], (hz2000) => { + const bfs = getBiquadFilter() + bfs.get('hz2000')!.gain.value = hz2000 + }) + watch(() => appSetting['player.soundEffect.biquadFilter.hz4000'], (hz4000) => { + const bfs = getBiquadFilter() + bfs.get('hz4000')!.gain.value = hz4000 + }) + watch(() => appSetting['player.soundEffect.biquadFilter.hz8000'], (hz8000) => { + const bfs = getBiquadFilter() + bfs.get('hz8000')!.gain.value = hz8000 + }) + watch(() => appSetting['player.soundEffect.biquadFilter.hz16000'], (hz16000) => { + const bfs = getBiquadFilter() + bfs.get('hz16000')!.gain.value = hz16000 + }) + + + // window.key_event.on(HOTKEY_PLAYER.volume_up.action, hotkeyVolumeUp) + // window.key_event.on(HOTKEY_PLAYER.volume_down.action, hotkeyVolumeDown) + // window.app_event.on('setPlaybackRate', handleSetPlaybackRate) + + // onBeforeUnmount(() => { + // // window.key_event.off(HOTKEY_PLAYER.volume_up.action, hotkeyVolumeUp) + // // window.key_event.off(HOTKEY_PLAYER.volume_down.action, hotkeyVolumeDown) + // window.app_event.off('setPlaybackRate', handleSetPlaybackRate) + // }) +} diff --git a/src/renderer/plugins/player.ts b/src/renderer/plugins/player.ts index bc820116..9c71fc6b 100644 --- a/src/renderer/plugins/player.ts +++ b/src/renderer/plugins/player.ts @@ -2,6 +2,57 @@ let audio: HTMLAudioElement | null = null let audioContext: AudioContext let mediaSource: MediaElementAudioSourceNode let analyser: AnalyserNode +// https://developer.mozilla.org/en-US/docs/Web/API/BaseAudioContext +// https://benzleung.gitbooks.io/web-audio-api-mini-guide/content/chapter5-1.html +export const freqs = [31, 62, 125, 250, 500, 1000, 2000, 4000, 8000, 16000] as const +type Freqs = (typeof freqs)[number] +let biquads: Map<`hz${Freqs}`, BiquadFilterNode> +export const convolutions = [ + { + name: 'telephone', // 电话 + mainGain: 0.0, + sendGain: 3.0, + source: 'filter-telephone.wav', + }, + { + name: 'spreader', // 室内 + mainGain: 1.0, + sendGain: 2.5, + source: 'spreader50-65ms.wav', + }, + { + name: 'feedback_spring', // 山洞 + mainGain: 0.0, + sendGain: 2.4, + source: 'feedback-spring.wav', + }, + { + name: 'church', // 教堂 + mainGain: 1.8, + sendGain: 0.9, + source: 's2_r4_bd.wav', + }, + { + name: 'kitchen', // 厨房 + mainGain: 0.6, + sendGain: 3.0, + source: 'kitchen-true-stereo.wav', + }, + { + name: 'bedroom', // 大厅 + mainGain: 0.6, + sendGain: 2.1, + source: 'living-bedroom-leveled.wav', + }, +] as const +let convolver: ConvolverNode +let convolverSourceGainNode: GainNode +let convolverOutputGainNode: GainNode +let convolverDynamicsCompressor: DynamicsCompressorNode +let gainNode: GainNode +let panner: PannerNode +export const soundR = 0.5 + export const createAudio = () => { if (audio) return @@ -11,20 +62,154 @@ export const createAudio = () => { audio.preload = 'auto' } -export const getAnalyser = (): AnalyserNode | null => { - if (!audio) throw new Error('audio not defined') +const initAnalyser = () => { + analyser = audioContext.createAnalyser() + analyser.fftSize = 256 +} - if (audioContext == null) { - audioContext = new window.AudioContext() - mediaSource = audioContext.createMediaElementSource(audio) - analyser = audioContext.createAnalyser() - analyser.fftSize = 256 - mediaSource.connect(analyser) - analyser.connect(audioContext.destination) +const initBiquadFilter = () => { + biquads = new Map() + let i + + for (const item of freqs) { + const filter = audioContext.createBiquadFilter() + biquads.set(`hz${item}`, filter) + filter.type = 'peaking' + filter.frequency.value = item + filter.Q.value = 1.4 + filter.gain.value = 0 } + + for (i = 1; i < freqs.length; i++) { + (biquads.get(`hz${freqs[i - 1]}`) as BiquadFilterNode).connect(biquads.get(`hz${freqs[i]}`) as BiquadFilterNode) + } +} + +const initConvolver = () => { + convolverSourceGainNode = audioContext.createGain() + convolverOutputGainNode = audioContext.createGain() + convolverDynamicsCompressor = audioContext.createDynamicsCompressor() + convolver = audioContext.createConvolver() + convolver.connect(convolverOutputGainNode) + convolverSourceGainNode.connect(convolverDynamicsCompressor) + convolverOutputGainNode.connect(convolverDynamicsCompressor) +} + +const initPanner = () => { + panner = audioContext.createPanner() +} + +const initGain = () => { + gainNode = audioContext.createGain() +} + +const initAdvancedAudioFeatures = () => { + if (audioContext) return + if (!audio) throw new Error('audio not defined') + audioContext = new window.AudioContext() + mediaSource = audioContext.createMediaElementSource(audio) + + initAnalyser() + mediaSource.connect(analyser) + // analyser.connect(audioContext.destination) + + initBiquadFilter() + analyser.connect(biquads.get(`hz${freqs[0]}`) as BiquadFilterNode) + + initConvolver() + const lastBiquadFilter = (biquads.get(`hz${freqs.at(-1) as Freqs}`) as BiquadFilterNode) + lastBiquadFilter.connect(convolverSourceGainNode) + lastBiquadFilter.connect(convolver) + + initPanner() + convolverDynamicsCompressor.connect(panner) + + initGain() + panner.connect(gainNode) + + gainNode.connect(audioContext.destination) +} + +export const getAudioContext = () => { + initAdvancedAudioFeatures() + return audioContext +} + + +export const getAnalyser = (): AnalyserNode | null => { + initAdvancedAudioFeatures() return analyser } +export const getBiquadFilter = () => { + initAdvancedAudioFeatures() + return biquads +} + +// let isConvolverConnected = false +export const setConvolver = (buffer: AudioBuffer | null, sendGain: number, mainGain: number) => { + initAdvancedAudioFeatures() + convolver.buffer = buffer + if (buffer) { + convolverOutputGainNode.gain.value = sendGain + convolverSourceGainNode.gain.value = mainGain + } else { + convolverOutputGainNode.gain.value = 0 + convolverSourceGainNode.gain.value = 1 + } +} + +let pannerInfo = { + x: 0, + y: 0, + z: 0, + soundR: 0.5, + rad: 0, + speed: 1, + intv: null as NodeJS.Timeout | null, +} +const setPannerXYZ = (nx: number, ny: number, nz: number) => { + pannerInfo.x = nx + pannerInfo.y = ny + pannerInfo.z = nz + // console.log(pannerInfo) + panner.positionX.value = nx * pannerInfo.soundR + panner.positionY.value = ny * pannerInfo.soundR + panner.positionZ.value = nz * pannerInfo.soundR +} +export const setPannerSoundR = (r: number) => { + pannerInfo.soundR = r +} + +export const setPannerSpeed = (speed: number) => { + pannerInfo.speed = speed + if (pannerInfo.intv) startPanner() +} +export const stopPanner = () => { + if (pannerInfo.intv) { + clearInterval(pannerInfo.intv) + pannerInfo.intv = null + pannerInfo.rad = 0 + } + panner.positionX.value = 0 + panner.positionY.value = 0 + panner.positionZ.value = 0 +} + +export const startPanner = () => { + initAdvancedAudioFeatures() + if (pannerInfo.intv) { + clearInterval(pannerInfo.intv) + pannerInfo.intv = null + pannerInfo.rad = 0 + } + pannerInfo.intv = setInterval(() => { + pannerInfo.rad += 1 + if (pannerInfo.rad > 360) pannerInfo.rad -= 360 + setPannerXYZ(Math.sin(pannerInfo.rad * Math.PI / 180), Math.cos(pannerInfo.rad * Math.PI / 180), Math.cos(pannerInfo.rad * Math.PI / 180)) + }, pannerInfo.speed * 10) +} + export const hasInitedAnalyser = (): boolean => audioContext != null export const setResource = (src: string) => { diff --git a/src/static/medias/filters/feedback-spring.wav b/src/static/medias/filters/feedback-spring.wav new file mode 100644 index 00000000..fb40d641 Binary files /dev/null and b/src/static/medias/filters/feedback-spring.wav differ diff --git a/src/static/medias/filters/filter-telephone.wav b/src/static/medias/filters/filter-telephone.wav new file mode 100644 index 00000000..47c50e7e Binary files /dev/null and b/src/static/medias/filters/filter-telephone.wav differ diff --git a/src/static/medias/filters/kitchen-true-stereo.wav b/src/static/medias/filters/kitchen-true-stereo.wav new file mode 100644 index 00000000..32f39002 Binary files /dev/null and b/src/static/medias/filters/kitchen-true-stereo.wav differ diff --git a/src/static/medias/filters/living-bedroom-leveled.wav b/src/static/medias/filters/living-bedroom-leveled.wav new file mode 100644 index 00000000..43c5be01 Binary files /dev/null and b/src/static/medias/filters/living-bedroom-leveled.wav differ diff --git a/src/static/medias/filters/s2_r4_bd.wav b/src/static/medias/filters/s2_r4_bd.wav new file mode 100644 index 00000000..4bb63883 Binary files /dev/null and b/src/static/medias/filters/s2_r4_bd.wav differ diff --git a/src/static/medias/filters/spreader50-65ms.wav b/src/static/medias/filters/spreader50-65ms.wav new file mode 100644 index 00000000..f5b091ad Binary files /dev/null and b/src/static/medias/filters/spreader50-65ms.wav differ