mirror of
https://github.com/th-ch/youtube-music.git
synced 2026-01-10 10:11:46 +00:00
Compare commits
576 Commits
feat/webno
...
v3.6.2
| Author | SHA1 | Date | |
|---|---|---|---|
| 27f4c0393e | |||
| 9bc42f836f | |||
| 11b11ed966 | |||
| 5f79b7e788 | |||
| 7d1d806797 | |||
| 836cedb0f3 | |||
| 70349e13cc | |||
| 6d16b74471 | |||
| c211780c33 | |||
| 2173ba0234 | |||
| 3a4cbc543b | |||
| 2fef7f0246 | |||
| 12d693921e | |||
| d1b4879f51 | |||
| f14939fcd2 | |||
| 4e66b0cedd | |||
| 11fe54d640 | |||
| 446529f738 | |||
| ac6e9deeb9 | |||
| 100873163f | |||
| e141e18bac | |||
| f4da0c2c95 | |||
| 7507bce3cc | |||
| 2b970fade8 | |||
| 35f0e43082 | |||
| ae4410a613 | |||
| 5534174016 | |||
| 15cf6c77c3 | |||
| 18a8fc462d | |||
| d3acb4945a | |||
| 32d3c58b44 | |||
| bd8c2eb390 | |||
| a81fa9c0d1 | |||
| 1d0f7d7a48 | |||
| b6687307df | |||
| 7e07a44f68 | |||
| 5ca66530ee | |||
| 95acbe2b65 | |||
| 534aeb163a | |||
| 6abcbee290 | |||
| 4457a043a4 | |||
| 410a052fea | |||
| e4287085a1 | |||
| b6cefef8fb | |||
| 9d7e2a06bc | |||
| d516fc2153 | |||
| 77bfe8e218 | |||
| 0fcbe38837 | |||
| b85a40f683 | |||
| 8020d61715 | |||
| cb1381bbb3 | |||
| f42f20f770 | |||
| 9fb1dbfde0 | |||
| 4f1ebab45d | |||
| 95644ea513 | |||
| 2fcddc8d2d | |||
| 6505a93645 | |||
| 11c25efd47 | |||
| a97bc8da5a | |||
| 782116b31b | |||
| 708d4b5480 | |||
| 9ba8913da7 | |||
| d07dae2542 | |||
| e7f213c4dc | |||
| 4cbf6c015b | |||
| 8acb93225b | |||
| 8153955ccf | |||
| 1de1cbac65 | |||
| 825aac1dab | |||
| d48aa7ad39 | |||
| 65ad09a02e | |||
| 08aae09446 | |||
| 88f54a389f | |||
| 4c23b1f970 | |||
| a979f1c8ea | |||
| ead448ed98 | |||
| fade340e80 | |||
| 8cc8160f70 | |||
| ee354ff678 | |||
| ca7ccc7b3e | |||
| f6b2766ec2 | |||
| 4a5f811485 | |||
| a092da7ba5 | |||
| b587a16419 | |||
| 4cf4f19ccc | |||
| 5b84c9efce | |||
| 98bbbfd851 | |||
| da2dbcacc4 | |||
| 7b6235694b | |||
| 4ad8e7b9dc | |||
| 51ecfff86b | |||
| 2c21a03201 | |||
| 4c2cb8dac9 | |||
| 9edcd2c32e | |||
| 0829fd2167 | |||
| 494e58296b | |||
| 151da2d786 | |||
| d7f5f28091 | |||
| 358fb3b084 | |||
| af79ba266d | |||
| 45f419f41a | |||
| 5189d6cfee | |||
| 102034b58c | |||
| 50d92bc004 | |||
| f2716e1dc8 | |||
| 9d436ed0a8 | |||
| 31d472e289 | |||
| 7f9a2b3011 | |||
| f54b346dce | |||
| dbff62bc5b | |||
| 87f43e3237 | |||
| 49cdcbdcc2 | |||
| bcff26c85b | |||
| bcfb33b4b1 | |||
| b172d8e509 | |||
| f10d146272 | |||
| 6105821a94 | |||
| 7c983df6f4 | |||
| cbbddefcf8 | |||
| 8d49c67fcb | |||
| c94b22b82c | |||
| cab3cb49f0 | |||
| e42084f008 | |||
| adca273ec3 | |||
| 91dceb3c22 | |||
| 216e76f4a1 | |||
| 178bfa483f | |||
| 10ecf5d2fe | |||
| 7099b81296 | |||
| 1f15376b00 | |||
| 02b7a39753 | |||
| 6edc84a8bd | |||
| 11a0d39064 | |||
| d5a5ed35b6 | |||
| dbb9e95b32 | |||
| d4c8a4320d | |||
| 68d4f38e41 | |||
| 2204784e89 | |||
| c3b995b0a8 | |||
| ed0a344077 | |||
| 199d912823 | |||
| 089eff3152 | |||
| 306ee8dba5 | |||
| a4992bafb2 | |||
| 5b004eedff | |||
| 2a66076d31 | |||
| f48e46d29c | |||
| 20296f5463 | |||
| fe4c89c349 | |||
| 3640527c8c | |||
| 3326582a16 | |||
| 5dcb9fe9ba | |||
| 336fa1e6fd | |||
| 3679a109d6 | |||
| 5290ed3de2 | |||
| fe5195714f | |||
| 8eb846262d | |||
| e9a1c2a91f | |||
| 2d1f78b383 | |||
| 1899064fd3 | |||
| e0280e5fe2 | |||
| d577e0fba6 | |||
| 37577c2f7f | |||
| c880f0a4eb | |||
| 4875955914 | |||
| 5b28c780bd | |||
| 4db2674b15 | |||
| a454a0163f | |||
| 61eb28e780 | |||
| e165e64952 | |||
| f380822e11 | |||
| 6b1995145a | |||
| 9317e99f43 | |||
| 66d05d8683 | |||
| 545a3a4bb6 | |||
| 04a6d16dbe | |||
| 3c36477b1e | |||
| c5c191492e | |||
| b12e2f607c | |||
| 1d77ad6de4 | |||
| 25bd26d7f3 | |||
| d11d0abe73 | |||
| 8a643c465d | |||
| 233673b8d8 | |||
| 5a448fab31 | |||
| 42e8262cda | |||
| f64769b1d3 | |||
| e12998761b | |||
| 2e20fa83b8 | |||
| 5149757af3 | |||
| 655741f108 | |||
| 4e58571ad0 | |||
| 1e4a615b47 | |||
| dedcf0c9ff | |||
| a84a7d236a | |||
| e56b4b21f0 | |||
| 361f9e42bd | |||
| 918736d2ca | |||
| 8f3d5b08ac | |||
| 4ca327d801 | |||
| 8d0aa057ad | |||
| b7ffee089b | |||
| d72b994f66 | |||
| e6dafdb068 | |||
| 14886dd4bd | |||
| c9f2f88bac | |||
| 1eabbc0bbe | |||
| 32a572b35a | |||
| 59a5679cbb | |||
| ac51f798c3 | |||
| 7599cc694a | |||
| 53595654b1 | |||
| 7656c41dbc | |||
| ff0c5b87c9 | |||
| 506c95740a | |||
| 575a42e28a | |||
| dcdc6a825f | |||
| 0a41bb1cd6 | |||
| 72a4736dc9 | |||
| f2b1e6b6bf | |||
| bc0e28ad6d | |||
| 8ebae91c02 | |||
| 954ad90733 | |||
| 5af0643788 | |||
| be633ac1f2 | |||
| 0d047c1fd5 | |||
| e8b1aca629 | |||
| 5b9bacf390 | |||
| ccd16f4a5f | |||
| 02e519dab3 | |||
| 473ea78f12 | |||
| e7f366b770 | |||
| 66816ac42d | |||
| 08b985f2ab | |||
| 747bde2136 | |||
| eabc28b39f | |||
| 3537dc19ee | |||
| 6afeb60557 | |||
| 71115dedee | |||
| 8750b54f76 | |||
| 482a1c5073 | |||
| c8d516c40b | |||
| c1ad168c32 | |||
| 5f5be5d02f | |||
| 61ef56dccc | |||
| a73b5acc75 | |||
| 877573532c | |||
| 7b033b5caf | |||
| 8924ec29d3 | |||
| 23e688aaf8 | |||
| 9b3cbe8e01 | |||
| 67a89e8ed4 | |||
| 464a2b94ea | |||
| 9357a15116 | |||
| ee820bb01c | |||
| 6b81735811 | |||
| 8ce91b143a | |||
| 116dbad9bc | |||
| 977af3d617 | |||
| 6da8defc73 | |||
| 0e93a963e1 | |||
| 1e98b2e75a | |||
| 6f5f13a840 | |||
| 822bcedadf | |||
| 2b6aea82c3 | |||
| 4f4efb407e | |||
| 6159e0e652 | |||
| 3957e06174 | |||
| c78f823b9b | |||
| 1be3bb360e | |||
| ba2afd2652 | |||
| 5e283c9ea5 | |||
| ddb1c56111 | |||
| ebd167f3f2 | |||
| 178a62b9d3 | |||
| f98a2cf766 | |||
| fdbe6f7331 | |||
| 57c2cdc91e | |||
| 0f5074f8ab | |||
| 661396226d | |||
| 36f27fe2e6 | |||
| adf1ce4bc7 | |||
| 43b4b8df5e | |||
| 4a8440c281 | |||
| 32fe9fcffe | |||
| a9896845da | |||
| a59aa07334 | |||
| e07d7395e7 | |||
| 9bb6f32ece | |||
| ccb19a0dc9 | |||
| 64fb6c2597 | |||
| 73c3e355fe | |||
| fc7a504643 | |||
| 764dc0f895 | |||
| 9f33f49ec4 | |||
| 87ae6d29bb | |||
| 093c8e3ca6 | |||
| fec26a010d | |||
| 5d8aaccc55 | |||
| cda03078a9 | |||
| 9c139b96f4 | |||
| 9b2816c156 | |||
| b1b8847134 | |||
| bf9e698288 | |||
| 28e8a1c5dd | |||
| 18e0b1b863 | |||
| 02e2fb6a83 | |||
| 91bee4880e | |||
| 7de7303ebb | |||
| 363d869cff | |||
| 2512af80af | |||
| 887979932c | |||
| eeaaf2f158 | |||
| e91e995b95 | |||
| 49dd2ecac6 | |||
| 06f419abc4 | |||
| 2c29461e61 | |||
| a9b9e74477 | |||
| 30848b7c4a | |||
| 83023c19a6 | |||
| 45931a25b0 | |||
| 98d4ff83b1 | |||
| 35f1d75832 | |||
| cbbba6ec76 | |||
| 35383e4730 | |||
| b7029cfc60 | |||
| d8328e0ad5 | |||
| 7ccb72d399 | |||
| 5108f19ee5 | |||
| 041574570f | |||
| 9505195835 | |||
| b33f5ff94d | |||
| 097f488ba0 | |||
| 521d1d8ee7 | |||
| f38ce093f5 | |||
| 2e63985ed3 | |||
| a22d08e983 | |||
| d1b998aebd | |||
| 7f598b5856 | |||
| 373e27ac5b | |||
| dcd53a9234 | |||
| c59b11b63b | |||
| 4d8fd8718f | |||
| f0c4d1da36 | |||
| 79c669e7c1 | |||
| e8156fc0fe | |||
| 348c70dca4 | |||
| 3439dded3b | |||
| 2ee0101e97 | |||
| 6a037083dd | |||
| 1d1705e471 | |||
| 0f7fe74d40 | |||
| d9f24d2c4e | |||
| 7b6a7377a8 | |||
| bd8468a8c1 | |||
| aec088f95d | |||
| 4b12b43f57 | |||
| f47287de94 | |||
| 58317f4c10 | |||
| c0aae7b2ac | |||
| 76547ad602 | |||
| 8b128273c8 | |||
| 25d1127b21 | |||
| b3ab08b354 | |||
| 2ef8b4f14c | |||
| b39baf6d88 | |||
| 40f0b9b852 | |||
| 3fe8115f32 | |||
| 47d3b34e4b | |||
| d0889bb622 | |||
| d6a7cbfa6f | |||
| c6541b6897 | |||
| 865578037b | |||
| d4176eeb8a | |||
| b88bbbc680 | |||
| 67aaccce86 | |||
| b95b69bf50 | |||
| 894531fd93 | |||
| 8a20566e0f | |||
| 253325a3cf | |||
| ee6716a0eb | |||
| 8fe5450ace | |||
| 1bb36b38bc | |||
| 25cec993bc | |||
| c744619664 | |||
| 451d30517e | |||
| dbb345ba1f | |||
| c60edf9718 | |||
| bd4e3a91c8 | |||
| 0f8b586b75 | |||
| 262c17a5bd | |||
| 542cb916b5 | |||
| 2627ebd675 | |||
| 89ed7d2345 | |||
| 3c4abc1418 | |||
| de224444c2 | |||
| e9ae2d44c9 | |||
| 680f4143f5 | |||
| 23b553ea4b | |||
| e2a91022fd | |||
| d97aa1a8a0 | |||
| ede11307ef | |||
| b74c1a0207 | |||
| 104c1284f6 | |||
| 8af1b36551 | |||
| ce5421ffce | |||
| 98b1fd8787 | |||
| ed5f1ecde3 | |||
| efbd9922fd | |||
| 463bc2c976 | |||
| e71a70d25c | |||
| 4ae9a2820e | |||
| 3ac1cc9204 | |||
| 2938c93803 | |||
| 7e8d31172c | |||
| e0353a88ce | |||
| 635f3334a6 | |||
| 7800e106cb | |||
| e436e6eae0 | |||
| 0c24b70f23 | |||
| 2693a1598a | |||
| 7a87e90edf | |||
| d333fc1075 | |||
| 1f99db3217 | |||
| 4fa9762a50 | |||
| 1e5bea85b3 | |||
| 739518a6fd | |||
| 24b0ae2c6b | |||
| dae6fc9149 | |||
| 25958a7bb1 | |||
| 8b901789dd | |||
| 09a582192f | |||
| 8735107eb0 | |||
| 5b9e947b8f | |||
| 1f1efac466 | |||
| ee9c5a149b | |||
| 79151cb3aa | |||
| 328530ea2c | |||
| 9e809b002d | |||
| 200226f42d | |||
| 5d99a854e2 | |||
| cd4f0ccad7 | |||
| b572623442 | |||
| ef02fdcf45 | |||
| 25d5c16af0 | |||
| 6f49313f03 | |||
| 55c7456c69 | |||
| 78c435b3c4 | |||
| 5e43f38348 | |||
| 24000acda0 | |||
| 24becf0337 | |||
| 8c80922b6b | |||
| 813a089f0d | |||
| 197bead857 | |||
| 5f7a705394 | |||
| 646c0d79a3 | |||
| 5a1313397e | |||
| 4bc70ac2b8 | |||
| dc5b2f96be | |||
| d10b297d75 | |||
| 933b4cc8f0 | |||
| 4557aff9b6 | |||
| 3a42d700fe | |||
| 1a142a8a39 | |||
| 922b04cd54 | |||
| bdfae8ce24 | |||
| 08a537e509 | |||
| 51d8145f13 | |||
| 7e74f33030 | |||
| 0bb8d9bcd9 | |||
| 19a4cb901b | |||
| c497dff69b | |||
| cd0164b665 | |||
| ab35cd3049 | |||
| 13b2ff3a2e | |||
| e00c1b51c7 | |||
| 0a2a289939 | |||
| 919b6ba7cb | |||
| f0683177d8 | |||
| 13450580d0 | |||
| 2375067d19 | |||
| b2fe0f21cb | |||
| 3e0257ba07 | |||
| 4f078284f3 | |||
| e87fa12fdc | |||
| 354c44d717 | |||
| f55faa0a8a | |||
| eaf9d310aa | |||
| bbd10b657d | |||
| 8600b5558f | |||
| 9c7eb5dc26 | |||
| ac63a6a200 | |||
| 3389994ff9 | |||
| adaee80913 | |||
| 4e467d9308 | |||
| a85fc609cb | |||
| 96f69953f2 | |||
| 9095b46a15 | |||
| 4415927465 | |||
| e6b25119cd | |||
| 09e02aeac8 | |||
| f3de17112a | |||
| 91392c0c7e | |||
| 54683a233f | |||
| 8d12eeb033 | |||
| 0ba35890b1 | |||
| 4783ca5942 | |||
| 1517a60215 | |||
| 4ca3c8b7e2 | |||
| 93081c89c8 | |||
| 09255b626b | |||
| 33fe008b5c | |||
| e72ac3d9d0 | |||
| 14a926aa88 | |||
| 99311dba6d | |||
| 5e9f545e4e | |||
| 0cc8fdf564 | |||
| 27e0e7173a | |||
| 2710c62b82 | |||
| a50de65a66 | |||
| c21758f8e6 | |||
| 1a5f6c2a8f | |||
| d521a84f85 | |||
| aa29a0fa65 | |||
| a8469d7d8d | |||
| d09858cbec | |||
| 855f67bb1e | |||
| 8508620e53 | |||
| e9fbfe36cc | |||
| f158a7865a | |||
| 74860edc6e | |||
| 1712b70fb5 | |||
| 4a57cc5ee9 | |||
| 4db0f72864 | |||
| bfe624dc57 | |||
| 994fdaf436 | |||
| 9ac9146d78 | |||
| fbbfc540c2 | |||
| ac3f42d507 | |||
| 993655fdee | |||
| eff2f550c6 | |||
| aef03ab9fd | |||
| f822373c30 | |||
| 19313f9cc9 | |||
| c3b64b097f | |||
| 6668d735a0 | |||
| e2d801168e | |||
| 86f5223350 | |||
| 9ee6940856 | |||
| bffea06343 | |||
| e0ab14b4ea | |||
| 1cb5f628c8 | |||
| 1ac9704cf4 | |||
| 7ebcc51646 | |||
| f4ccde2734 | |||
| e6d7c5cdfc | |||
| 9e3f32a233 | |||
| 8ed813427f | |||
| 2db0d79af6 | |||
| 28ba662d6f | |||
| e041a83121 | |||
| 42185e59d5 | |||
| 975e9719ad | |||
| 31e51a67db | |||
| d5f829d8d0 | |||
| 0dbf0295b8 | |||
| daaf48f453 | |||
| 1d9e021681 | |||
| 6dd36c74e0 | |||
| b933218762 | |||
| 26f8814a97 | |||
| 236ba7536e | |||
| faaf996b16 | |||
| 5a637fd6e7 | |||
| aca1d30d2f | |||
| 5c3eecb3fd |
@ -1 +0,0 @@
|
||||
.eslintrc.js
|
||||
80
.eslintrc.js
80
.eslintrc.js
@ -1,80 +0,0 @@
|
||||
module.exports = {
|
||||
extends: [
|
||||
'eslint:recommended',
|
||||
'plugin:import/recommended',
|
||||
'plugin:import/typescript',
|
||||
'plugin:@typescript-eslint/eslint-recommended',
|
||||
'plugin:@typescript-eslint/recommended',
|
||||
'plugin:@typescript-eslint/recommended-requiring-type-checking',
|
||||
],
|
||||
plugins: ['prettier', '@typescript-eslint', 'import'],
|
||||
parser: '@typescript-eslint/parser',
|
||||
parserOptions: {
|
||||
project: './tsconfig.json',
|
||||
tsconfigRootDir: __dirname,
|
||||
sourceType: 'module',
|
||||
ecmaVersion: 'latest'
|
||||
},
|
||||
rules: {
|
||||
'arrow-parens': ['error', 'always'],
|
||||
'object-curly-spacing': ['error', 'always'],
|
||||
'@typescript-eslint/no-floating-promises': 'off',
|
||||
'@typescript-eslint/no-misused-promises': ['off', { checksVoidReturn: false }],
|
||||
'@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_' }],
|
||||
"@typescript-eslint/no-non-null-assertion": "off",
|
||||
'import/first': 'error',
|
||||
'import/newline-after-import': 'error',
|
||||
'import/no-default-export': 'off',
|
||||
'import/no-duplicates': 'error',
|
||||
'import/no-unresolved': ['error', { ignore: ['^virtual:', '\\?inline$', '\\?raw$', '\\?asset&asarUnpack'] }],
|
||||
'import/order': [
|
||||
'error',
|
||||
{
|
||||
'groups': ['builtin', 'external', ['internal', 'index', 'sibling'], 'parent', 'type'],
|
||||
'newlines-between': 'always-and-inside-groups',
|
||||
'alphabetize': {order: 'ignore', caseInsensitive: false}
|
||||
}
|
||||
],
|
||||
'import/prefer-default-export': 'off',
|
||||
'camelcase': ['error', {properties: 'never'}],
|
||||
'class-methods-use-this': 'off',
|
||||
'lines-around-comment': [
|
||||
'error',
|
||||
{
|
||||
beforeBlockComment: false,
|
||||
afterBlockComment: false,
|
||||
beforeLineComment: false,
|
||||
afterLineComment: false,
|
||||
},
|
||||
],
|
||||
'max-len': 'off',
|
||||
'no-mixed-operators': 'error',
|
||||
'no-multi-spaces': ['error', {ignoreEOLComments: true}],
|
||||
'no-tabs': 'error',
|
||||
'no-void': 'error',
|
||||
'no-empty': 'off',
|
||||
'prefer-promise-reject-errors': 'off',
|
||||
'quotes': ['error', 'single', {
|
||||
avoidEscape: true,
|
||||
allowTemplateLiterals: false,
|
||||
}],
|
||||
'quote-props': ['error', 'consistent'],
|
||||
'semi': ['error', 'always'],
|
||||
},
|
||||
env: {
|
||||
browser: true,
|
||||
node: true,
|
||||
es6: true,
|
||||
},
|
||||
ignorePatterns: ['dist', 'node_modules'],
|
||||
root: true,
|
||||
settings: {
|
||||
'import/parsers': {
|
||||
'@typescript-eslint/parser': ['.ts']
|
||||
},
|
||||
'import/resolver': {
|
||||
typescript: {},
|
||||
exports: {},
|
||||
},
|
||||
},
|
||||
};
|
||||
15
.github/workflows/build.yml
vendored
15
.github/workflows/build.yml
vendored
@ -21,9 +21,9 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Install pnpm
|
||||
uses: pnpm/action-setup@v2
|
||||
uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: 8
|
||||
version: 9
|
||||
run_install: false
|
||||
|
||||
- name: Setup NodeJS
|
||||
@ -61,6 +61,13 @@ jobs:
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
sudo snap install snapcraft --classic
|
||||
sudo apt update
|
||||
sudo apt install -y flatpak flatpak-builder
|
||||
sudo flatpak remote-add --if-not-exists --system flathub https://flathub.org/repo/flathub.flatpakrepo
|
||||
sudo flatpak install -y flathub org.freedesktop.Platform/x86_64/20.08
|
||||
sudo flatpak install -y flathub org.freedesktop.Sdk/x86_64/20.08
|
||||
sudo flatpak install -y flathub org.electronjs.Electron2.BaseApp/x86_64/20.08
|
||||
pnpm release:linux
|
||||
|
||||
- name: Build and release on Windows
|
||||
@ -89,9 +96,9 @@ jobs:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Install pnpm
|
||||
uses: pnpm/action-setup@v2
|
||||
uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: 8
|
||||
version: 9
|
||||
run_install: false
|
||||
|
||||
- name: Setup NodeJS
|
||||
|
||||
16
README.md
16
README.md
@ -4,7 +4,7 @@
|
||||
|
||||
[](https://github.com/th-ch/youtube-music/releases/)
|
||||
[](https://github.com/th-ch/youtube-music/blob/master/LICENSE)
|
||||
[](https://github.com/th-ch/youtube-music/blob/master/.eslintrc.js)
|
||||
[](https://github.com/th-ch/youtube-music/blob/master/eslint.config.mjs)
|
||||
[](https://GitHub.com/th-ch/youtube-music/releases/)
|
||||
[](https://GitHub.com/th-ch/youtube-music/releases/)
|
||||
[](https://aur.archlinux.org/packages/youtube-music-bin)
|
||||
@ -21,7 +21,7 @@
|
||||
</a>
|
||||
</div>
|
||||
|
||||
Read this in other languages: [🇰🇷](./docs/readme/README-ko.md), [🇮🇸](./docs/readme/README-is.md)
|
||||
Read this in other languages: [🇰🇷](./docs/readme/README-ko.md), [🇮🇸](./docs/readme/README-is.md), [🇨🇱 🇪🇸](./docs/readme/README-es.md), [🇷🇺](./docs/readme/README-ru.md)
|
||||
|
||||
**Electron wrapper around YouTube Music featuring:**
|
||||
|
||||
@ -141,6 +141,8 @@ Read this in other languages: [🇰🇷](./docs/readme/README-ko.md), [🇮🇸]
|
||||
- [**SponsorBlock**](https://github.com/ajayyy/SponsorBlock): Automatically Skips non-music parts like intro/outro or
|
||||
parts of music videos where the song isn't playing
|
||||
|
||||
- **Synced Lyrics**: Provides synced lyrics to songs, using providers like [LRClib](https://lrclib.net).
|
||||
|
||||
- **Taskbar Media Control**: Control playback from
|
||||
your [Windows taskbar](https://user-images.githubusercontent.com/78568641/111916130-24a35e80-8a82-11eb-80c8-5021c1aa27f4.png)
|
||||
|
||||
@ -159,6 +161,7 @@ Read this in other languages: [🇰🇷](./docs/readme/README-ko.md), [🇮🇸]
|
||||
|
||||
- **Visualizer**: Different music visualizers
|
||||
|
||||
|
||||
## Translation
|
||||
|
||||
You can help with translation on [Hosted Weblate](https://hosted.weblate.org/projects/youtube-music/).
|
||||
@ -178,7 +181,7 @@ latest version.
|
||||
Install the [`youtube-music-bin`](https://aur.archlinux.org/packages/youtube-music-bin) package from the AUR. For AUR installation instructions, take a look at
|
||||
this [wiki page](https://wiki.archlinux.org/index.php/Arch_User_Repository#Installing_packages).
|
||||
|
||||
### MacOS
|
||||
### macOS
|
||||
|
||||
You can install the app using Homebrew (see the [cask definition](https://github.com/th-ch/homebrew-youtube-music)):
|
||||
|
||||
@ -365,8 +368,11 @@ export default createPlugin({
|
||||
4. Run `pnpm build:OS`
|
||||
|
||||
- `pnpm dist:win` - Windows
|
||||
- `pnpm dist:linux` - Linux
|
||||
- `pnpm dist:mac` - MacOS
|
||||
- `pnpm dist:linux` - Linux (amd64)
|
||||
- `pnpm dist:linux:deb-arm64` - Linux (arm64 for Debian)
|
||||
- `pnpm dist:linux:rpm-arm64` - Linux (arm64 for Fedora)
|
||||
- `pnpm dist:mac` - macOS (amd64)
|
||||
- `pnpm dist:mac:arm64` - macOS (arm64)
|
||||
|
||||
Builds the app for macOS, Linux, and Windows,
|
||||
using [electron-builder](https://github.com/electron-userland/electron-builder).
|
||||
|
||||
388
changelog.md
388
changelog.md
@ -2,8 +2,396 @@
|
||||
|
||||
All notable changes to this project will be documented in this file. Dates are displayed in UTC.
|
||||
|
||||
#### [v3.6.1](https://github.com/th-ch/youtube-music/compare/v3.6.0...v3.6.1)
|
||||
|
||||
- fix(api-server): Various fixes and improvements [`#2496`](https://github.com/th-ch/youtube-music/pull/2496)
|
||||
- fix(deps): update dependency electron-debug to v4.1.0 [`#2499`](https://github.com/th-ch/youtube-music/pull/2499)
|
||||
- fix(renderer): fix force like buttons display logic [`#2493`](https://github.com/th-ch/youtube-music/pull/2493)
|
||||
- fix(deps): update dependency i18next to v23.16.0 [`#2492`](https://github.com/th-ch/youtube-music/pull/2492)
|
||||
- fix(downloader): fix #2371 [`#2371`](https://github.com/th-ch/youtube-music/issues/2371)
|
||||
- fix(ytm-bugs): incorrect video ratio [`#2459`](https://github.com/th-ch/youtube-music/issues/2459)
|
||||
- fix(api-server): fix init/authentication error [`#2497`](https://github.com/th-ch/youtube-music/issues/2497)
|
||||
- fix: RSS feed CORS issue [`#1620`](https://github.com/th-ch/youtube-music/issues/1620)
|
||||
- chore(flatpak-builder): Add more details when failing [`d3acb49`](https://github.com/th-ch/youtube-music/commit/d3acb4945a8dcde6598c53d8207bbf16eda8c739)
|
||||
- chore(i18n): Translated using Weblate (Filipino) [`e428708`](https://github.com/th-ch/youtube-music/commit/e4287085a11f30d141148ab0432cc684819fd0d0)
|
||||
- Bump version to 3.6.1 [`b668730`](https://github.com/th-ch/youtube-music/commit/b6687307dfe7ef765517019093c8db3c2ad14417)
|
||||
|
||||
#### [v3.6.0](https://github.com/th-ch/youtube-music/compare/v3.5.3...v3.6.0)
|
||||
|
||||
> 13 October 2024
|
||||
|
||||
- feat(api-server): remote control api [`#1909`](https://github.com/th-ch/youtube-music/pull/1909)
|
||||
- chore(deps): update playwright monorepo to v1.48.0 [`#2489`](https://github.com/th-ch/youtube-music/pull/2489)
|
||||
- fix(`synced-lyrics`): Fix 2 issues [`#2441`](https://github.com/th-ch/youtube-music/pull/2441)
|
||||
- chore(deps): update dependency typescript to v5.6.3 [`#2486`](https://github.com/th-ch/youtube-music/pull/2486)
|
||||
- chore(deps): update dependency electron to v32.2.0 [`#2487`](https://github.com/th-ch/youtube-music/pull/2487)
|
||||
- chore(deps): update dependency del-cli to v6 [`#2475`](https://github.com/th-ch/youtube-music/pull/2475)
|
||||
- chore(deps): update dependency typescript-eslint to v8.8.1 [`#2477`](https://github.com/th-ch/youtube-music/pull/2477)
|
||||
- fix(deps): update dependency solid-js to v1.9.2 [`#2480`](https://github.com/th-ch/youtube-music/pull/2480)
|
||||
- Revert "chore(deps): update dependency electron-builder to v25" [`#2488`](https://github.com/th-ch/youtube-music/pull/2488)
|
||||
- chore(deps): update dependency electron-builder to v25 [`#2406`](https://github.com/th-ch/youtube-music/pull/2406)
|
||||
- fix(deps): update dependency deepmerge-ts to v7.1.3 [`#2481`](https://github.com/th-ch/youtube-music/pull/2481)
|
||||
- fix(deps): update dependency ts-morph to v24 [`#2474`](https://github.com/th-ch/youtube-music/pull/2474)
|
||||
- fix(deps): update dependency i18next to v23.15.2 [`#2471`](https://github.com/th-ch/youtube-music/pull/2471)
|
||||
- chore(deps): update eslint monorepo to v9.12.0 [`#2470`](https://github.com/th-ch/youtube-music/pull/2470)
|
||||
- chore(deps): update dependency @stylistic/eslint-plugin-js to v2.9.0 [`#2469`](https://github.com/th-ch/youtube-music/pull/2469)
|
||||
- chore(deps): bump micromatch from 4.0.5 to 4.0.8 [`#2465`](https://github.com/th-ch/youtube-music/pull/2465)
|
||||
- chore(deps): bump braces from 3.0.2 to 3.0.3 [`#2466`](https://github.com/th-ch/youtube-music/pull/2466)
|
||||
- fix(deps): update dependency electron-updater to v6.3.9 [`#2468`](https://github.com/th-ch/youtube-music/pull/2468)
|
||||
- fix(deps): update dependency deepmerge-ts to v7.1.1 [`#2467`](https://github.com/th-ch/youtube-music/pull/2467)
|
||||
- chore(deps): update dependency typescript-eslint to v8.8.0 [`#2457`](https://github.com/th-ch/youtube-music/pull/2457)
|
||||
- chore(deps): update dependency @babel/runtime to v7.25.7 [`#2462`](https://github.com/th-ch/youtube-music/pull/2462)
|
||||
- chore(deps): update dependency rollup to v4.24.0 [`#2458`](https://github.com/th-ch/youtube-music/pull/2458)
|
||||
- chore(deps): update dependency eslint-plugin-import to v2.31.0 [`#2464`](https://github.com/th-ch/youtube-music/pull/2464)
|
||||
- chore(deps): update dependency rollup to v4.22.5 [`#2448`](https://github.com/th-ch/youtube-music/pull/2448)
|
||||
- chore(deps): update dependency typescript-eslint to v8.7.0 [`#2450`](https://github.com/th-ch/youtube-music/pull/2450)
|
||||
- fix(deps): update dependency solid-js to v1.9.1 [`#2451`](https://github.com/th-ch/youtube-music/pull/2451)
|
||||
- chore(deps): update dependency vite to v5.4.8 [`#2449`](https://github.com/th-ch/youtube-music/pull/2449)
|
||||
- chore(deps): update dependency discord-api-types to v0.37.101 [`#2440`](https://github.com/th-ch/youtube-music/pull/2440)
|
||||
- chore(deps): update dependency esbuild to v0.24.0 [`#2439`](https://github.com/th-ch/youtube-music/pull/2439)
|
||||
- chore(deps): update eslint monorepo to v9.11.1 [`#2442`](https://github.com/th-ch/youtube-music/pull/2442)
|
||||
- chore(deps): update dependency @types/howler to v2.2.12 [`#2443`](https://github.com/th-ch/youtube-music/pull/2443)
|
||||
- chore(deps): update dependency vite to v5.4.7 [`#2434`](https://github.com/th-ch/youtube-music/pull/2434)
|
||||
- chore(deps): update playwright monorepo to v1.47.2 [`#2436`](https://github.com/th-ch/youtube-music/pull/2436)
|
||||
- chore(deps): update eslint monorepo to v9.11.0 [`#2437`](https://github.com/th-ch/youtube-music/pull/2437)
|
||||
- fix(deps): update dependency youtubei.js to v10.5.0 [`#2431`](https://github.com/th-ch/youtube-music/pull/2431)
|
||||
- chore(deps): update dependency rollup to v4.22.4 [`#2430`](https://github.com/th-ch/youtube-music/pull/2430)
|
||||
- chore(deps): update dependency electron to v32.1.2 [`#2433`](https://github.com/th-ch/youtube-music/pull/2433)
|
||||
- feat: ESLint Flat Config (v9 support #2229) [`#2426`](https://github.com/th-ch/youtube-music/pull/2426)
|
||||
- fix(taskbar-mediacontrol): fix icon color [`#2485`](https://github.com/th-ch/youtube-music/issues/2485)
|
||||
- chore(eslint): apply eslint-plugin-prettier [`#2438`](https://github.com/th-ch/youtube-music/issues/2438)
|
||||
- fix: apply fix from eslint [`cb1381b`](https://github.com/th-ch/youtube-music/commit/cb1381bbb394e2bbb404f44817ef96411dabc8a9)
|
||||
- chore(i18n): Translated using Weblate (Portuguese (Brazil)) [`bcff26c`](https://github.com/th-ch/youtube-music/commit/bcff26c85b18258806f3960309776bc860c3a54e)
|
||||
- chore(i18n): Translated using Weblate (Persian) [`ead448e`](https://github.com/th-ch/youtube-music/commit/ead448ed98095339557903eb0f84c4a6d0f32058)
|
||||
|
||||
#### [v3.5.3](https://github.com/th-ch/youtube-music/compare/v3.5.2...v3.5.3)
|
||||
|
||||
> 17 September 2024
|
||||
|
||||
- fix: fix `trustedHTML` issue [`#2339`](https://github.com/th-ch/youtube-music/issues/2339)
|
||||
- chore(deps): update dependency rollup to v4.21.3 [`6edc84a`](https://github.com/th-ch/youtube-music/commit/6edc84a8bd6c7e009041117ba0d2004783eb3a47)
|
||||
- chore(deps): update typescript-eslint monorepo to v8.6.0 [`d4c8a43`](https://github.com/th-ch/youtube-music/commit/d4c8a4320d733f7bddc4dcd1de93644790e71d66)
|
||||
- chore(deps): update dependency eslint to v8.57.1 [`02b7a39`](https://github.com/th-ch/youtube-music/commit/02b7a39753528cfd8c0d107d6d2ec6ef78c5afe7)
|
||||
|
||||
#### [v3.5.2](https://github.com/th-ch/youtube-music/compare/v3.5.1...v3.5.2)
|
||||
|
||||
> 7 September 2024
|
||||
|
||||
- chore(deps): update typescript-eslint monorepo to v8.4.0 [`#2401`](https://github.com/th-ch/youtube-music/pull/2401)
|
||||
- chore(deps): update dependency @total-typescript/ts-reset to v0.6.1 [`#2396`](https://github.com/th-ch/youtube-music/pull/2396)
|
||||
- chore(deps): update dependency electron to v31.5.0 [`#2397`](https://github.com/th-ch/youtube-music/pull/2397)
|
||||
- chore(deps): update dependency eslint-import-resolver-typescript to v3.6.3 [`#2376`](https://github.com/th-ch/youtube-music/pull/2376)
|
||||
- chore(deps): update dependency discord-api-types to v0.37.100 [`#2394`](https://github.com/th-ch/youtube-music/pull/2394)
|
||||
- fix(deps): update dependency electron-updater to v6.3.4 [`#2395`](https://github.com/th-ch/youtube-music/pull/2395)
|
||||
- chore(deps): update dependency @babel/runtime to v7.25.6 [`#2388`](https://github.com/th-ch/youtube-music/pull/2388)
|
||||
- chore(deps): update dependency vite-plugin-inspect to v0.8.7 [`#2389`](https://github.com/th-ch/youtube-music/pull/2389)
|
||||
- chore(deps): update dependency discord-api-types to v0.37.99 [`#2374`](https://github.com/th-ch/youtube-music/pull/2374)
|
||||
- chore(deps): update dependency vite to v5.4.3 [`#2377`](https://github.com/th-ch/youtube-music/pull/2377)
|
||||
- fix: incorrect regex when splitting artistName [`#2378`](https://github.com/th-ch/youtube-music/pull/2378)
|
||||
- chore(deps): update dependency @babel/runtime to v7.25.4 [`#2373`](https://github.com/th-ch/youtube-music/pull/2373)
|
||||
- synced-lyrics: make the lyrics search more reliable [`#2343`](https://github.com/th-ch/youtube-music/pull/2343)
|
||||
- fix(deps): update dependency solid-js to v1.8.22 [`#2354`](https://github.com/th-ch/youtube-music/pull/2354)
|
||||
- chore(deps): update typescript-eslint monorepo to v8.3.0 [`#2350`](https://github.com/th-ch/youtube-music/pull/2350)
|
||||
- fix(deps): update dependency electron-debug to v4.0.1 [`#2349`](https://github.com/th-ch/youtube-music/pull/2349)
|
||||
- chore(deps): update dependency electron to v31.4.0 [`#2356`](https://github.com/th-ch/youtube-music/pull/2356)
|
||||
- fix: hide native-controls on linux when in-app-menu is used [`#2366`](https://github.com/th-ch/youtube-music/pull/2366)
|
||||
- fix: detect the upgrade btn using the icon [`#2364`](https://github.com/th-ch/youtube-music/pull/2364)
|
||||
- fix: exclude build-id files from rpm [`#2361`](https://github.com/th-ch/youtube-music/pull/2361)
|
||||
- fix(deps): update dependency i18next to v23.12.3 [`#2352`](https://github.com/th-ch/youtube-music/pull/2352)
|
||||
- fix(deps): update dependency @floating-ui/dom to v1.6.10 [`#2340`](https://github.com/th-ch/youtube-music/pull/2340)
|
||||
- fix(deps): update dependency electron-updater to v6.3.3 [`#2347`](https://github.com/th-ch/youtube-music/pull/2347)
|
||||
- fix(deps): update dependency solid-js to v1.8.20 [`#2345`](https://github.com/th-ch/youtube-music/pull/2345)
|
||||
- chore(deps): update dependency vite to v5.4.0 [`#2342`](https://github.com/th-ch/youtube-music/pull/2342)
|
||||
- chore(deps): update typescript-eslint monorepo to v8.0.1 [`#2335`](https://github.com/th-ch/youtube-music/pull/2335)
|
||||
- fix(deps): update dependency @floating-ui/dom to v1.6.9 [`#2337`](https://github.com/th-ch/youtube-music/pull/2337)
|
||||
- chore(deps): update playwright monorepo to v1.46.0 [`#2336`](https://github.com/th-ch/youtube-music/pull/2336)
|
||||
- chore(README): Translation README to Russian and adding Synced Lyrics to main README [`#2338`](https://github.com/th-ch/youtube-music/pull/2338)
|
||||
- chore(deps): update dependency rollup to v4.20.0 [`#2326`](https://github.com/th-ch/youtube-music/pull/2326)
|
||||
- fix(synced-lyric): fix timestamp [`#2323`](https://github.com/th-ch/youtube-music/issues/2323) [`#2379`](https://github.com/th-ch/youtube-music/issues/2379)
|
||||
- Revert "fix(MPRIS): Prevents player to start with invalid MPRIS interface (#1996)" [`#2225`](https://github.com/th-ch/youtube-music/issues/2225)
|
||||
- fix(adblocker/inplayer): fix Response.prototype.json [`#2310`](https://github.com/th-ch/youtube-music/issues/2310)
|
||||
- chore(deps): update dependency eslint-plugin-import to v2.30.0 [`f48e46d`](https://github.com/th-ch/youtube-music/commit/f48e46d29cf09c76c5172fd56d2d0f705616e4e3)
|
||||
- Revert "chore(deps): update dependency electron-builder to v25" [`089eff3`](https://github.com/th-ch/youtube-music/commit/089eff3152903c8b55ad3e5571b944062a647e27)
|
||||
- chore(deps): update dependency electron-builder to v25 [`fe4c89c`](https://github.com/th-ch/youtube-music/commit/fe4c89c349bb9f4f54d95c2018943095ccfdab0c)
|
||||
|
||||
#### [v3.5.1](https://github.com/th-ch/youtube-music/compare/v3.5.0...v3.5.1)
|
||||
|
||||
> 1 August 2024
|
||||
|
||||
- fix(deps): update dependency youtubei.js to v10.3.0 [`#2306`](https://github.com/th-ch/youtube-music/pull/2306)
|
||||
- fix: Window gets stuck offscreen in some instances [`#2303`](https://github.com/th-ch/youtube-music/pull/2303)
|
||||
- fix: Incorrect window size on multi-monitor scaled displays [`#2302`](https://github.com/th-ch/youtube-music/pull/2302)
|
||||
- chore(deps): update dependency rollup to v4.19.2 [`#2304`](https://github.com/th-ch/youtube-music/pull/2304)
|
||||
- chore(deps): update typescript-eslint monorepo to v8 (major) [`#2297`](https://github.com/th-ch/youtube-music/pull/2297)
|
||||
- fix(ambient-mode): fix ambient-mode not working for videos after restart [`#2294`](https://github.com/th-ch/youtube-music/pull/2294)
|
||||
- fix(deps): update dependency @xhayper/discord-rpc to v1.2.0 [`#2291`](https://github.com/th-ch/youtube-music/pull/2291)
|
||||
- fix(synced-lyrics): fix lyric load [`#2295`](https://github.com/th-ch/youtube-music/issues/2295)
|
||||
- fix(ambient-mode): fix ambient-mode not working for videos after restart (#2294) [`#1641`](https://github.com/th-ch/youtube-music/issues/1641)
|
||||
- fix(synced-lyrics): fix i18n [`8750b54`](https://github.com/th-ch/youtube-music/commit/8750b54f766c735ff039c6be454427f17d4737e2)
|
||||
- ts-fix: disambiguate ElectronStore typings [`8775735`](https://github.com/th-ch/youtube-music/commit/877573532c1b68af861a3fdc44d093f3097d36ab)
|
||||
- chore(i18n): Translated using Weblate (Hungarian) [`3537dc1`](https://github.com/th-ch/youtube-music/commit/3537dc19eecce7f7deb2478942f70d3c7b72148d)
|
||||
|
||||
#### [v3.5.0](https://github.com/th-ch/youtube-music/compare/v3.4.1...v3.5.0)
|
||||
|
||||
> 31 July 2024
|
||||
|
||||
- plugin: Synced Lyrics [`#2207`](https://github.com/th-ch/youtube-music/pull/2207)
|
||||
- chore(deps): update dependency electron to v31.3.1 [`#2290`](https://github.com/th-ch/youtube-music/pull/2290)
|
||||
- chore(deps): update typescript-eslint monorepo to v7.18.0 [`#2292`](https://github.com/th-ch/youtube-music/pull/2292)
|
||||
- fix(deps): update dependency youtubei.js to v10.2.0 [`#2285`](https://github.com/th-ch/youtube-music/pull/2285)
|
||||
- chore(deps): update dependency electron to v31.3.0 [`#2282`](https://github.com/th-ch/youtube-music/pull/2282)
|
||||
- chore(deps): update typescript-eslint monorepo to v7.17.0 [`#2283`](https://github.com/th-ch/youtube-music/pull/2283)
|
||||
- fix(deps): update dependency solid-js to v1.8.19 [`#2280`](https://github.com/th-ch/youtube-music/pull/2280)
|
||||
- fix(deps): update dependency @xhayper/discord-rpc to v1.1.4 [`#2279`](https://github.com/th-ch/youtube-music/pull/2279)
|
||||
- chore(deps): update dependency @babel/runtime to v7.25.0 [`#2281`](https://github.com/th-ch/youtube-music/pull/2281)
|
||||
- fix(deps): update dependency @floating-ui/dom to v1.6.8 [`#2278`](https://github.com/th-ch/youtube-music/pull/2278)
|
||||
- Fix: Incorrect window size on scaled displays [`#2258`](https://github.com/th-ch/youtube-music/pull/2258)
|
||||
- chore(deps): update dependency vite-plugin-resolve to v2.5.2 [`#2276`](https://github.com/th-ch/youtube-music/pull/2276)
|
||||
- chore(deps): update playwright monorepo to v1.45.3 [`#2277`](https://github.com/th-ch/youtube-music/pull/2277)
|
||||
- fix(deps): update dependency deepmerge-ts to v7.1.0 [`#2263`](https://github.com/th-ch/youtube-music/pull/2263)
|
||||
- chore(deps): update dependency typescript to v5.5.4 [`#2274`](https://github.com/th-ch/youtube-music/pull/2274)
|
||||
- chore(deps): update dependency vite to v5.3.5 [`#2275`](https://github.com/th-ch/youtube-music/pull/2275)
|
||||
- fix(deps): update dependency i18next to v23.12.2 [`#2260`](https://github.com/th-ch/youtube-music/pull/2260)
|
||||
- chore(deps): update dependency discord-api-types to v0.37.93 [`#2273`](https://github.com/th-ch/youtube-music/pull/2273)
|
||||
- chore(deps): update dependency rollup to v4.19.1 [`#2261`](https://github.com/th-ch/youtube-music/pull/2261)
|
||||
- fix(deps): update dependency custom-electron-prompt to v1.5.8 [`#2262`](https://github.com/th-ch/youtube-music/pull/2262)
|
||||
- feat(adblocker): add new option AdSpeedup [`#2235`](https://github.com/th-ch/youtube-music/pull/2235)
|
||||
- fix: disable multi-plane format for software video [`#2254`](https://github.com/th-ch/youtube-music/pull/2254)
|
||||
- chore(deps): update dependency eslint-plugin-prettier to v5.2.1 [`#2253`](https://github.com/th-ch/youtube-music/pull/2253)
|
||||
- chore(deps): update dependency vite to v5.3.4 [`#2243`](https://github.com/th-ch/youtube-music/pull/2243)
|
||||
- chore(deps): update typescript-eslint monorepo to v7.16.1 [`#2239`](https://github.com/th-ch/youtube-music/pull/2239)
|
||||
- chore(deps): update playwright monorepo to v1.45.2 [`#2244`](https://github.com/th-ch/youtube-music/pull/2244)
|
||||
- chore(deps): update dependency vite-plugin-inspect to v0.8.5 [`#2252`](https://github.com/th-ch/youtube-music/pull/2252)
|
||||
- fix(deps): update dependency semver to v7.6.3 [`#2250`](https://github.com/th-ch/youtube-music/pull/2250)
|
||||
- chore(deps): update dependency electron to v31.2.1 [`#2241`](https://github.com/th-ch/youtube-music/pull/2241)
|
||||
- chore(i18n): Translated using Weblate (Catalan) [`4a8440c`](https://github.com/th-ch/youtube-music/commit/4a8440c281c341977ab3687982cec8cbc5af6cf7)
|
||||
- Update changelog for v3.4.1 [`18e0b1b`](https://github.com/th-ch/youtube-music/commit/18e0b1b86341b13f1cbc713bfbd7b5d7a45ee392)
|
||||
- fix(synced-lyrics): fix type error [`9357a15`](https://github.com/th-ch/youtube-music/commit/9357a15116a8526d22ba6142c0a02f31688743f2)
|
||||
|
||||
#### [v3.4.1](https://github.com/th-ch/youtube-music/compare/v3.4.0...v3.4.1)
|
||||
|
||||
> 15 July 2024
|
||||
|
||||
- fix(mpris): fix mpris position [`#2225`](https://github.com/th-ch/youtube-music/issues/2225)
|
||||
- fix(deb): fix depends [`#1983`](https://github.com/th-ch/youtube-music/issues/1983)
|
||||
- fix: fix touchbar icon [`#2183`](https://github.com/th-ch/youtube-music/issues/2183)
|
||||
- fix: fix "Starting page" [`#1822`](https://github.com/th-ch/youtube-music/issues/1822)
|
||||
- fix: fix album actions [`#2202`](https://github.com/th-ch/youtube-music/issues/2202)
|
||||
- fix: fix playback slider [`#2045`](https://github.com/th-ch/youtube-music/issues/2045)
|
||||
- chore(i18n): Translated using Weblate (Spanish) [`91bee48`](https://github.com/th-ch/youtube-music/commit/91bee4880ed2c6fdd887814a2620877d89bea311)
|
||||
- Bump version to 3.4.1 [`02e2fb6`](https://github.com/th-ch/youtube-music/commit/02e2fb6a83844f439f760e72cdcb935b86000df2)
|
||||
|
||||
#### [v3.4.0](https://github.com/th-ch/youtube-music/compare/v3.3.12...v3.4.0)
|
||||
|
||||
> 14 July 2024
|
||||
|
||||
- fix(deps): update dependency i18next to v23.12.1 [`#2230`](https://github.com/th-ch/youtube-music/pull/2230)
|
||||
- feat(downloader): New option to download on finish [`#1964`](https://github.com/th-ch/youtube-music/pull/1964)
|
||||
- chore(deps): update typescript-eslint monorepo to v8.0.0-alpha.42 [`#2228`](https://github.com/th-ch/youtube-music/pull/2228)
|
||||
- chore(deps): update dependency eslint to v9.7.0 [`#2226`](https://github.com/th-ch/youtube-music/pull/2226)
|
||||
- chore(deps): update dependency @babel/runtime to v7.24.8 [`#2221`](https://github.com/th-ch/youtube-music/pull/2221)
|
||||
- chore(deps): update dependency node-gyp to v10.2.0 [`#2216`](https://github.com/th-ch/youtube-music/pull/2216)
|
||||
- chore(deps): update dependency ws to v8.18.0 [`#2217`](https://github.com/th-ch/youtube-music/pull/2217)
|
||||
- chore(deps): update dependency glob to v11 [`#2219`](https://github.com/th-ch/youtube-music/pull/2219)
|
||||
- chore(deps): update dependency esbuild to v0.23.0 [`#2215`](https://github.com/th-ch/youtube-music/pull/2215)
|
||||
- chore(deps): update dependency electron to v31.2.0 [`#2214`](https://github.com/th-ch/youtube-music/pull/2214)
|
||||
- fix(deps): update dependency youtubei.js to v10.1.0 [`#2218`](https://github.com/th-ch/youtube-music/pull/2218)
|
||||
- chore(deps): update playwright monorepo to v1.45.1 [`#2212`](https://github.com/th-ch/youtube-music/pull/2212)
|
||||
- chore(deps): update typescript-eslint monorepo to v8.0.0-alpha.41 [`#2213`](https://github.com/th-ch/youtube-music/pull/2213)
|
||||
- chore(deps): update dependency rollup to v4.18.1 [`#2210`](https://github.com/th-ch/youtube-music/pull/2210)
|
||||
- chore(deps): update dependency eslint to v9.6.0 [`#2192`](https://github.com/th-ch/youtube-music/pull/2192)
|
||||
- chore(deps): update dependency vite to v5.3.3 [`#2211`](https://github.com/th-ch/youtube-music/pull/2211)
|
||||
- chore(deps): update dependency glob to v10.4.5 [`#2205`](https://github.com/th-ch/youtube-music/pull/2205)
|
||||
- chore(deps): update dependency discord-api-types to v0.37.92 [`#2204`](https://github.com/th-ch/youtube-music/pull/2204)
|
||||
- fix(deps): update dependency solid-js to v1.8.18 [`#2189`](https://github.com/th-ch/youtube-music/pull/2189)
|
||||
- chore(deps): update dependency typescript to v5.5.3 [`#2206`](https://github.com/th-ch/youtube-music/pull/2206)
|
||||
- chore(deps): update dependency electron to v31.1.0 [`#2190`](https://github.com/th-ch/youtube-music/pull/2190)
|
||||
- chore(deps): update typescript-eslint monorepo to v8.0.0-alpha.40 [`#2193`](https://github.com/th-ch/youtube-music/pull/2193)
|
||||
- fix(deps): update dependency @floating-ui/dom to v1.6.7 [`#2196`](https://github.com/th-ch/youtube-music/pull/2196)
|
||||
- chore(deps): update dependency vite to v5.3.2 [`#2188`](https://github.com/th-ch/youtube-music/pull/2188)
|
||||
- chore(deps): update dependency discord-api-types to v0.37.91 [`#2187`](https://github.com/th-ch/youtube-music/pull/2187)
|
||||
- chore(deps): update typescript-eslint monorepo to v8.0.0-alpha.34 [`#2184`](https://github.com/th-ch/youtube-music/pull/2184)
|
||||
- fix(deps): update dependency @floating-ui/dom to v1.6.6 [`#2182`](https://github.com/th-ch/youtube-music/pull/2182)
|
||||
- chore(deps): update playwright monorepo to v1.45.0 [`#2181`](https://github.com/th-ch/youtube-music/pull/2181)
|
||||
- fix(deps): update dependency ts-morph to v23 [`#2180`](https://github.com/th-ch/youtube-music/pull/2180)
|
||||
- chore(deps): update dependency electron-vite to v2.3.0 [`#2178`](https://github.com/th-ch/youtube-music/pull/2178)
|
||||
- fix(deps): update dependency conf to v13.0.1 [`#2175`](https://github.com/th-ch/youtube-music/pull/2175)
|
||||
- chore(deps): update dependency glob to v10.4.2 [`#2168`](https://github.com/th-ch/youtube-music/pull/2168)
|
||||
- chore(deps): update dependency discord-api-types to v0.37.90 [`#2167`](https://github.com/th-ch/youtube-music/pull/2167)
|
||||
- chore(deps): update dependency typescript to v5.5.2 [`#2173`](https://github.com/th-ch/youtube-music/pull/2173)
|
||||
- chore(deps): update dependency electron to v31.0.2 [`#2170`](https://github.com/th-ch/youtube-music/pull/2170)
|
||||
- chore(deps): update dependency ws to v8.17.1 [`#2164`](https://github.com/th-ch/youtube-music/pull/2164)
|
||||
- chore(deps): update dependency eslint to v9.5.0 [`#2162`](https://github.com/th-ch/youtube-music/pull/2162)
|
||||
- fix(deps): update dependency youtubei.js to v10 [`#2136`](https://github.com/th-ch/youtube-music/pull/2136)
|
||||
- chore(deps): update dependency discord-api-types to v0.37.89 [`#2153`](https://github.com/th-ch/youtube-music/pull/2153)
|
||||
- chore(deps): update dependency vite to v5.3.1 [`#2154`](https://github.com/th-ch/youtube-music/pull/2154)
|
||||
- fix(deps): update dependency electron-store to v10 [`#2157`](https://github.com/th-ch/youtube-music/pull/2157)
|
||||
- fix(deps): update dependency conf to v13 [`#2156`](https://github.com/th-ch/youtube-music/pull/2156)
|
||||
- chore(deps): update dependency electron to v31.0.1 [`#2148`](https://github.com/th-ch/youtube-music/pull/2148)
|
||||
- chore(deps): update dependency discord-api-types to v0.37.88 [`#2138`](https://github.com/th-ch/youtube-music/pull/2138)
|
||||
- chore(deps): update typescript-eslint monorepo to v8.0.0-alpha.30 [`#2139`](https://github.com/th-ch/youtube-music/pull/2139)
|
||||
- chore(deps): update dependency electron to v31 [`#2141`](https://github.com/th-ch/youtube-music/pull/2141)
|
||||
- chore(deps): update dependency esbuild to v0.21.5 [`#2135`](https://github.com/th-ch/youtube-music/pull/2135)
|
||||
- chore(deps): update typescript-eslint monorepo to v8.0.0-alpha.29 [`#2132`](https://github.com/th-ch/youtube-music/pull/2132)
|
||||
- fix: rollback eslint version to v8 [`45931a2`](https://github.com/th-ch/youtube-music/commit/45931a25b08ab8a406f9e102486585311fd14bf9)
|
||||
- chore(i18n): Translated using Weblate (Filipino) [`8a20566`](https://github.com/th-ch/youtube-music/commit/8a20566e0f2736f72d46282188ada69df1d7076a)
|
||||
- chore(i18n): Translated using Weblate (Slovenian) [`40f0b9b`](https://github.com/th-ch/youtube-music/commit/40f0b9b852dcd9146e1c1e6c741b5baaf55ac079)
|
||||
|
||||
#### [v3.3.12](https://github.com/th-ch/youtube-music/compare/v3.3.11...v3.3.12)
|
||||
|
||||
> 8 June 2024
|
||||
|
||||
- hotfix: Revert "chore(deps): update dependencies `@cliqz/adblocker-electron`, `@cliqz/adblocker-electron-preload`" [`3c4abc1`](https://github.com/th-ch/youtube-music/commit/3c4abc14187e51f7e47c1ae71b3513f6d8c9912a)
|
||||
- Update changelog for v3.3.11 [`de22444`](https://github.com/th-ch/youtube-music/commit/de224444c2a6d9030aa22a3b263ceacbc4b41914)
|
||||
- Bump version to 3.3.12 [`89ed7d2`](https://github.com/th-ch/youtube-music/commit/89ed7d2345001fea59514944f4c1d56d2b7bd888)
|
||||
|
||||
#### [v3.3.11](https://github.com/th-ch/youtube-music/compare/v3.3.10...v3.3.11)
|
||||
|
||||
> 8 June 2024
|
||||
|
||||
- Revert "fix(deps): update dependency @cliqz/adblocker-electron to v1.27.10" [`#2129`](https://github.com/th-ch/youtube-music/pull/2129)
|
||||
- chore(deps): update dependency vite to v5.2.13 [`#2127`](https://github.com/th-ch/youtube-music/pull/2127)
|
||||
- chore(deps): update dependency electron to v30.1.0 [`#2126`](https://github.com/th-ch/youtube-music/pull/2126)
|
||||
- fix(deps): update dependency deepmerge-ts to v7.0.3 [`#2125`](https://github.com/th-ch/youtube-music/pull/2125)
|
||||
- chore(deps): update dependency @babel/runtime to v7.24.7 [`#2124`](https://github.com/th-ch/youtube-music/pull/2124)
|
||||
- chore(deps): update typescript-eslint monorepo to v8.0.0-alpha.28 [`#2121`](https://github.com/th-ch/youtube-music/pull/2121)
|
||||
- fix(deps): update dependency electron-updater to v6.2.1 [`#2120`](https://github.com/th-ch/youtube-music/pull/2120)
|
||||
- chore(deps): update dependency discord-api-types to v0.37.87 [`#2119`](https://github.com/th-ch/youtube-music/pull/2119)
|
||||
- fix(deps): update dependency deepmerge-ts to v7.0.2 [`#2118`](https://github.com/th-ch/youtube-music/pull/2118)
|
||||
- chore(deps): update typescript-eslint monorepo to v8.0.0-alpha.25 [`#2114`](https://github.com/th-ch/youtube-music/pull/2114)
|
||||
- fix(menu): fix menubar items doesn't rendered [`#2113`](https://github.com/th-ch/youtube-music/issues/2113)
|
||||
- chore(i18n): Translated using Weblate (Nepali) [`4ae9a28`](https://github.com/th-ch/youtube-music/commit/4ae9a2820e9d453635094956264dd8b42c4997f7)
|
||||
- chore(i18n): Translated using Weblate (Nepali) [`7e8d311`](https://github.com/th-ch/youtube-music/commit/7e8d31172ceb175ba07f307d248fc1246265a4c0)
|
||||
- fix(deps): update dependency @cliqz/adblocker-electron to v1.27.10 [`d97aa1a`](https://github.com/th-ch/youtube-music/commit/d97aa1a8a003f15eea63c8cb2dabd0f215e885f1)
|
||||
|
||||
#### [v3.3.10](https://github.com/th-ch/youtube-music/compare/v3.3.9...v3.3.10)
|
||||
|
||||
> 2 June 2024
|
||||
|
||||
- fix(adblocker): fix blank screen [`#2103`](https://github.com/th-ch/youtube-music/issues/2103) [`#2105`](https://github.com/th-ch/youtube-music/issues/2105)
|
||||
- chore(i18n): Translated using Weblate (Hungarian) [`25958a7`](https://github.com/th-ch/youtube-music/commit/25958a7bb1fea20e59676e7821f3dd8819602b68)
|
||||
- fix(deps): bump deps [`4fa9762`](https://github.com/th-ch/youtube-music/commit/4fa9762a506544ce453894ce2df13033225e6c7d)
|
||||
- fix(deps): bump `@typescript-eslint/eslint-plugin` version to 8.0.0-alpha.24 [`1e5bea8`](https://github.com/th-ch/youtube-music/commit/1e5bea85b31da5de868d9eff8758e5d2d888c2c8)
|
||||
|
||||
#### [v3.3.9](https://github.com/th-ch/youtube-music/compare/v3.3.8...v3.3.9)
|
||||
|
||||
> 1 June 2024
|
||||
|
||||
- chore(deps): update dependency eslint to v9.4.0 [`#2106`](https://github.com/th-ch/youtube-music/pull/2106)
|
||||
- fix(adblocker): fix In-Player adblocker [`#1817`](https://github.com/th-ch/youtube-music/issues/1817)
|
||||
- feat(adblocker): improve In-Player adblocker [`5b9e947`](https://github.com/th-ch/youtube-music/commit/5b9e947b8feebb57d9a2122ae7b7ab2ff7c37c06)
|
||||
- chore(i18n): Translated using Weblate (French) [`9e809b0`](https://github.com/th-ch/youtube-music/commit/9e809b002d10f6ec0202a7d56d3d0b73f8093012)
|
||||
- chore(i18n): Translated using Weblate (Malay) [`79151cb`](https://github.com/th-ch/youtube-music/commit/79151cb3aa6c087b8d8bb500322f505797b822bd)
|
||||
|
||||
#### [v3.3.8](https://github.com/th-ch/youtube-music/compare/v3.3.7...v3.3.8)
|
||||
|
||||
> 1 June 2024
|
||||
|
||||
- fix(adblocker): fix blank screen [`#1942`](https://github.com/th-ch/youtube-music/issues/1942) [`#2100`](https://github.com/th-ch/youtube-music/issues/2100) [`#2103`](https://github.com/th-ch/youtube-music/issues/2103)
|
||||
- Update changelog for v3.3.7 [`b572623`](https://github.com/th-ch/youtube-music/commit/b572623442fc8b45b593dc0c91623fbf814115b4)
|
||||
- Bump version to 3.3.8 [`5d99a85`](https://github.com/th-ch/youtube-music/commit/5d99a854e2f29bdb6682beeffa4e6b9b8be0f60f)
|
||||
|
||||
#### [v3.3.7](https://github.com/th-ch/youtube-music/compare/v3.3.6...v3.3.7)
|
||||
|
||||
> 1 June 2024
|
||||
|
||||
- chore(deps): update dependency electron to v30.0.9 [`#2098`](https://github.com/th-ch/youtube-music/pull/2098)
|
||||
- Revert "fix(deps): update dependency @cliqz/adblocker-electron to v1.27.6" [`#2101`](https://github.com/th-ch/youtube-music/pull/2101)
|
||||
- fix(deps): update dependency @cliqz/adblocker-electron to v1.27.6 [`#2096`](https://github.com/th-ch/youtube-music/pull/2096)
|
||||
- chore(deps): update dependency discord-api-types to v0.37.86 [`#2092`](https://github.com/th-ch/youtube-music/pull/2092)
|
||||
- chore(deps): update dependency vite to v5.2.12 [`#2094`](https://github.com/th-ch/youtube-music/pull/2094)
|
||||
- chore(deps): update dependency @typescript-eslint/eslint-plugin to v7.11.0 [`#2093`](https://github.com/th-ch/youtube-music/pull/2093)
|
||||
- chore(docs): Added README-es.md and linked to README.md [`#2090`](https://github.com/th-ch/youtube-music/pull/2090)
|
||||
- fix(deps): update dependency deepmerge-ts to v7 [`#2085`](https://github.com/th-ch/youtube-music/pull/2085)
|
||||
- chore(deps): update dependency builtin-modules to v4 [`#2084`](https://github.com/th-ch/youtube-music/pull/2084)
|
||||
- fix(deps): update dependency electron-debug to v4 [`#2086`](https://github.com/th-ch/youtube-music/pull/2086)
|
||||
- fix(deps): update dependency electron-store to v9 [`#2087`](https://github.com/th-ch/youtube-music/pull/2087)
|
||||
- fix(deps): update dependency conf to v12 [`#1463`](https://github.com/th-ch/youtube-music/pull/1463)
|
||||
- fix(deps): update dependency youtubei.js to v9.4.0 [`#2083`](https://github.com/th-ch/youtube-music/pull/2083)
|
||||
- chore(deps): update playwright monorepo to v1.44.1 [`#2082`](https://github.com/th-ch/youtube-music/pull/2082)
|
||||
- chore(deps): update dependency ws to v8.17.0 [`#2081`](https://github.com/th-ch/youtube-music/pull/2081)
|
||||
- chore(deps): update dependency glob to v10.4.1 [`#2080`](https://github.com/th-ch/youtube-music/pull/2080)
|
||||
- chore(deps): update dependency eslint to v9.3.0 [`#2079`](https://github.com/th-ch/youtube-music/pull/2079)
|
||||
- fix(deps): update dependency peerjs to v1.5.4 [`#2075`](https://github.com/th-ch/youtube-music/pull/2075)
|
||||
- chore(deps): update dependency esbuild to v0.21.4 [`#2078`](https://github.com/th-ch/youtube-music/pull/2078)
|
||||
- fix(deps): update dependency semver to v7.6.2 [`#2076`](https://github.com/th-ch/youtube-music/pull/2076)
|
||||
- chore(deps): update dependency electron-vite to v2.2.0 [`#2077`](https://github.com/th-ch/youtube-music/pull/2077)
|
||||
- fix(deps): update dependency i18next to v23.11.5 [`#2074`](https://github.com/th-ch/youtube-music/pull/2074)
|
||||
- fix(deps): update dependency @cliqz/adblocker-electron to v1.27.3 [`#2071`](https://github.com/th-ch/youtube-music/pull/2071)
|
||||
- chore(deps): update dependency vite to v5.2.11 [`#2070`](https://github.com/th-ch/youtube-music/pull/2070)
|
||||
- fix(deps): update dependency @floating-ui/dom to v1.6.5 [`#2073`](https://github.com/th-ch/youtube-music/pull/2073)
|
||||
- fix(deps): update dependency @cliqz/adblocker-electron-preload to v1.27.3 [`#2072`](https://github.com/th-ch/youtube-music/pull/2072)
|
||||
- chore(deps): update pnpm to v9 [`#1980`](https://github.com/th-ch/youtube-music/pull/1980)
|
||||
- chore(deps): update dependency electron to v30.0.8 [`#2068`](https://github.com/th-ch/youtube-music/pull/2068)
|
||||
- chore(deps-dev): bump ejs from 3.1.9 to 3.1.10 [`#2023`](https://github.com/th-ch/youtube-music/pull/2023)
|
||||
- chore(deps): update dependency utf-8-validate to v6.0.4 [`#2069`](https://github.com/th-ch/youtube-music/pull/2069)
|
||||
- fix(MPRIS): Prevents player to start with invalid MPRIS interface [`#1996`](https://github.com/th-ch/youtube-music/pull/1996)
|
||||
- fix(deps): update dependency solid-js to v1.8.17 [`#2002`](https://github.com/th-ch/youtube-music/pull/2002)
|
||||
- chore(deps): update dependency @typescript-eslint/eslint-plugin to v7.10.0 [`#2000`](https://github.com/th-ch/youtube-music/pull/2000)
|
||||
- chore(deps): update dependency discord-api-types to v0.37.85 [`#1998`](https://github.com/th-ch/youtube-music/pull/1998)
|
||||
- fix(deps): update dependency serve to v14.2.3 [`#1997`](https://github.com/th-ch/youtube-music/pull/1997)
|
||||
- chore(deps): update dependency rollup to v4.18.0 [`#1990`](https://github.com/th-ch/youtube-music/pull/1990)
|
||||
- feat: Enable arm64 for deb and rpm [`#2033`](https://github.com/th-ch/youtube-music/pull/2033)
|
||||
- chore (README-is.md): Replace viðbót with tengiforrit [`#2004`](https://github.com/th-ch/youtube-music/pull/2004)
|
||||
- chore(docs): readme file translated to french [`#2049`](https://github.com/th-ch/youtube-music/pull/2049)
|
||||
- chore(deps): update dependency @babel/runtime to v7.24.6 [`#2039`](https://github.com/th-ch/youtube-music/pull/2039)
|
||||
- Fix substract `margin-top` in fullscreen mode [`#2015`](https://github.com/th-ch/youtube-music/pull/2015)
|
||||
- chore(deps): update pnpm to v8.15.7 [`#1970`](https://github.com/th-ch/youtube-music/pull/1970)
|
||||
- fix(renderer): fix macos traffic lights gap [`#2035`](https://github.com/th-ch/youtube-music/issues/2035)
|
||||
- Fix substract `margin-top` in fullscreen mode [`#2013`](https://github.com/th-ch/youtube-music/issues/2013)
|
||||
- chore(i18n): Translated using Weblate (Hungarian) [`f3de171`](https://github.com/th-ch/youtube-music/commit/f3de17112af787437362f31b5c4e2d4149ba1436)
|
||||
- feat(menu): add theme list in menu [`933b4cc`](https://github.com/th-ch/youtube-music/commit/933b4cc8f062b3442afd4516a40eb2938db98fc6)
|
||||
- chore(i18n): Translated using Weblate (Filipino) [`91392c0`](https://github.com/th-ch/youtube-music/commit/91392c0c7efaf3b33da4be4aaa7946af7108d676)
|
||||
|
||||
#### [v3.3.6](https://github.com/th-ch/youtube-music/compare/v3.3.5...v3.3.6)
|
||||
|
||||
> 13 April 2024
|
||||
|
||||
- fix: add AdGuard as blocklist sources [`#1966`](https://github.com/th-ch/youtube-music/pull/1966)
|
||||
- chore(deps): update dependency rollup to v4.14.2 [`#1968`](https://github.com/th-ch/youtube-music/pull/1968)
|
||||
- fix(deps): update dependency youtubei.js to v9.3.0 [`#1967`](https://github.com/th-ch/youtube-music/pull/1967)
|
||||
- chore(deps): update playwright monorepo to v1.43.1 [`#1969`](https://github.com/th-ch/youtube-music/pull/1969)
|
||||
- chore(deps): update dependency electron to v29.3.0 [`#1961`](https://github.com/th-ch/youtube-music/pull/1961)
|
||||
- fix(mpris): use global regex to replace minus in the video ID [`#1963`](https://github.com/th-ch/youtube-music/pull/1963)
|
||||
- fix(deps): update dependency @cliqz/adblocker-electron-preload to v1.27.1 [`#1954`](https://github.com/th-ch/youtube-music/pull/1954)
|
||||
- chore(deps): update dependency typescript to v5.4.5 [`#1958`](https://github.com/th-ch/youtube-music/pull/1958)
|
||||
- fix(deps): update dependency youtubei.js to v9.2.1 [`#1957`](https://github.com/th-ch/youtube-music/pull/1957)
|
||||
- fix(deps): update dependency i18next to v23.11.1 [`#1956`](https://github.com/th-ch/youtube-music/pull/1956)
|
||||
- fix(deps): update dependency @cliqz/adblocker-electron to v1.27.1 [`#1953`](https://github.com/th-ch/youtube-music/pull/1953)
|
||||
- chore(deps): update dependency @typescript-eslint/eslint-plugin to v7.6.0 [`#1947`](https://github.com/th-ch/youtube-music/pull/1947)
|
||||
- fix(deps): update dependency i18next to v23.11.0 [`#1946`](https://github.com/th-ch/youtube-music/pull/1946)
|
||||
- chore(deps): update dependency node-gyp to v10.1.0 [`#1941`](https://github.com/th-ch/youtube-music/pull/1941)
|
||||
- chore(deps): update dependency eslint to v9 [`#1940`](https://github.com/th-ch/youtube-music/pull/1940)
|
||||
- chore(deps): update dependency rollup to v4.14.1 [`#1944`](https://github.com/th-ch/youtube-music/pull/1944)
|
||||
- chore(deps): update dependency node-gyp to v10.1.0 [`#1937`](https://github.com/th-ch/youtube-music/pull/1937)
|
||||
- chore(deps): update dependency typescript to v5.4.4 [`#1936`](https://github.com/th-ch/youtube-music/pull/1936)
|
||||
- chore(deps): update playwright monorepo to v1.43.0 [`#1938`](https://github.com/th-ch/youtube-music/pull/1938)
|
||||
- chore(deps): bump undici from 5.28.3 to 5.28.4 [`#1935`](https://github.com/th-ch/youtube-music/pull/1935)
|
||||
- chore(deps): update dependency vite to v5.2.8 [`#1930`](https://github.com/th-ch/youtube-music/pull/1930)
|
||||
- chore(deps): update dependency discord-api-types to v0.37.79 [`#1933`](https://github.com/th-ch/youtube-music/pull/1933)
|
||||
- chore(deps): update dependency node-gyp to v10.1.0 [`#1910`](https://github.com/th-ch/youtube-music/pull/1910)
|
||||
- chore(deps): update dependency node-gyp to v10.1.0 [`#1908`](https://github.com/th-ch/youtube-music/pull/1908)
|
||||
- fix(deps): update dependency @cliqz/adblocker-electron to v1.27.0 [`#1906`](https://github.com/th-ch/youtube-music/pull/1906)
|
||||
- fix(deps): update dependency @cliqz/adblocker-electron-preload to v1.27.0 [`#1907`](https://github.com/th-ch/youtube-music/pull/1907)
|
||||
- chore(deps): update dependency rollup to v4.13.2 [`#1901`](https://github.com/th-ch/youtube-music/pull/1901)
|
||||
- chore(deps): update dependency glob to v10.3.12 [`#1900`](https://github.com/th-ch/youtube-music/pull/1900)
|
||||
- chore(deps): update dependency vite to v5.2.7 [`#1905`](https://github.com/th-ch/youtube-music/pull/1905)
|
||||
- fix(deps): update dependency node-html-parser to v6.1.13 [`#1903`](https://github.com/th-ch/youtube-music/pull/1903)
|
||||
- chore(deps): update dependency discord-api-types to v0.37.77 [`#1899`](https://github.com/th-ch/youtube-music/pull/1899)
|
||||
- chore(deps): update dependency electron to v29.1.6 [`#1898`](https://github.com/th-ch/youtube-music/pull/1898)
|
||||
- Improve video title filters [`#1667`](https://github.com/th-ch/youtube-music/pull/1667)
|
||||
- chore(deps): update dependency rollup to v4.13.1 [`#1896`](https://github.com/th-ch/youtube-music/pull/1896)
|
||||
- chore(deps): update dependency node-gyp to v10.1.0 [`#1890`](https://github.com/th-ch/youtube-music/pull/1890)
|
||||
- chore(deps): update dependency node-gyp to v10.1.0 [`#1889`](https://github.com/th-ch/youtube-music/pull/1889)
|
||||
- fix: fix `switch-repeat` [`#1810`](https://github.com/th-ch/youtube-music/issues/1810)
|
||||
- i18n Translation to Dutch/nl [`0dbf029`](https://github.com/th-ch/youtube-music/commit/0dbf0295b805f9883522ee00983b338060fbddbe)
|
||||
- fix: rollback electron-builder version to 24.9.4 [`4a57cc5`](https://github.com/th-ch/youtube-music/commit/4a57cc5ee9ab2ad6835cff75b8b3aead75d9e564)
|
||||
- chore: update electron-builder to 25.0.0-alpha.6 [`aef03ab`](https://github.com/th-ch/youtube-music/commit/aef03ab9fd440fe19c41e315cffab27e976c723d)
|
||||
|
||||
#### [v3.3.5](https://github.com/th-ch/youtube-music/compare/v3.3.4...v3.3.5)
|
||||
|
||||
> 26 March 2024
|
||||
|
||||
- chore(deps): update dependency node-gyp to v10.1.0 [`#1885`](https://github.com/th-ch/youtube-music/pull/1885)
|
||||
- chore(deps): update dependency @typescript-eslint/eslint-plugin to v7.4.0 [`#1886`](https://github.com/th-ch/youtube-music/pull/1886)
|
||||
- chore(deps): update dependency vite to v5.2.6 [`#1883`](https://github.com/th-ch/youtube-music/pull/1883)
|
||||
|
||||
390
docs/readme/README-es.md
Normal file
390
docs/readme/README-es.md
Normal file
@ -0,0 +1,390 @@
|
||||
<div align="center">
|
||||
|
||||
# YouTube Music
|
||||
|
||||
[](https://github.com/th-ch/youtube-music/releases/)
|
||||
[](https://github.com/th-ch/youtube-music/blob/master/LICENSE)
|
||||
[](https://github.com/th-ch/youtube-music/blob/master/.eslintrc.js)
|
||||
[](https://GitHub.com/th-ch/youtube-music/releases/)
|
||||
[](https://GitHub.com/th-ch/youtube-music/releases/)
|
||||
[](https://aur.archlinux.org/packages/youtube-music-bin)
|
||||
[](https://snyk.io/test/github/th-ch/youtube-music)
|
||||
|
||||
</div>
|
||||
|
||||

|
||||
|
||||
|
||||
<div align="center">
|
||||
<a href="https://github.com/th-ch/youtube-music/releases/latest">
|
||||
<img src="/web/youtube-music.svg" width="400" height="100" alt="YouTube Music SVG">
|
||||
</a>
|
||||
</div>
|
||||
|
||||
**Electron wrapper de YouTube Music con las siguientes características:**
|
||||
|
||||
- Apariencia y sensación nativa, tiene como objetivo mantener la interfaz original
|
||||
- Framework para plugins personalizados: cambia YouTube Music según tus necesidades (estilo, contenido, funciones), habilita/deshabilita plugins con un solo clic
|
||||
|
||||
## Imagen de demostración
|
||||
|
||||
| Pantalla del reproductor (color del álbum como tema y luz ambiental) |
|
||||
|:---------------------------------------------------------------------------------------------------------:|
|
||||
||
|
||||
|
||||
## Contenido
|
||||
|
||||
- [Características](#características)
|
||||
- [Plugins disponibles](#plugins-disponibles)
|
||||
- [Traducción](#traducción)
|
||||
- [Descarga](#descarga)
|
||||
- [Arch Linux](#arch-linux)
|
||||
- [macOS](#macos)
|
||||
- [Windows](#windows)
|
||||
- [Cómo instalar sin conexión a internet? (en Windows)](#cómo-instalar-sin-conexión-a-internet-en-windows)
|
||||
- [Temas](#temas)
|
||||
- [Dev](#dev)
|
||||
- [Crea tus propios plugins](#crea-tus-propios-plugins)
|
||||
- [Creación de un plugin](#creación-de-un-plugin)
|
||||
- [Casos de uso comunes](#casos-de-uso-comunes)
|
||||
- [Compilar](#compilar)
|
||||
- [Vista previa de producción](#vista-previa-de-producción)
|
||||
- [Tests](#tests)
|
||||
- [Licencia](#licencia)
|
||||
- [Preguntas frecuentes](#preguntas-frecuentes)
|
||||
|
||||
## Características:
|
||||
|
||||
- **Confirmación automática al pausar** (Siempre habilitado): desactiva
|
||||
el mensaje emergente ["¿Continuar reproduciendo?"](https://user-images.githubusercontent.com/61631665/129977894-01c60740-7ec6-4bf0-9a2c-25da24491b0e.png)
|
||||
que pausa la música después de cierto tiempo
|
||||
|
||||
- Y más ...
|
||||
|
||||
## Plugins disponibles:
|
||||
|
||||
- **Bloqueador de Anuncios**: Bloquea todos los anuncios y rastreadores de forma predeterminada
|
||||
|
||||
- **Acciones de Álbum**: Agrega botones de deshacer No me gusta, No me gusta, Me gusta, y Deshacer me gusta a todas las canciones de una lista de reproducción o álbum
|
||||
|
||||
- **Tema de Color del Álbum**: Aplica un tema dinámico y efectos visuales basados en la paleta de colores del álbum
|
||||
|
||||
- **Modo Ambiente**: Aplica un efecto de iluminación proyectando colores suaves del video en el fondo de tu pantalla
|
||||
|
||||
- **Compresor de Audio**: Aplica compresión al audio (reduce el volumen de las partes más fuertes de la señal y aumenta el
|
||||
volumen de las partes más suaves)
|
||||
|
||||
- **Barra de Navegación Difuminada**: hace que la barra de navegación sea transparente y borrosa
|
||||
|
||||
- **Omitir Restricciones de Edades**: omite la verificación de edad de YouTube
|
||||
|
||||
- **Selector de Subtítulos**: Habilita los subtítulos
|
||||
|
||||
- **Barra Lateral Compacta**: Siempre muestra la barra lateral en modo compacto
|
||||
|
||||
- **Crossfade**: Transición suave entre canciones
|
||||
|
||||
- **Desactivar Reproducción Automática**: Hace que cada canción comience en modo "pausado"
|
||||
|
||||
- **[Discord](https://discord.com/) Rich Presence**: Muestra a tus amigos lo que estás escuchando
|
||||
con [Rich Presence](https://user-images.githubusercontent.com/28219076/104362104-a7a0b980-5513-11eb-9744-bb89eabe0016.png)
|
||||
|
||||
- **Descargador**: Descarga
|
||||
MP3 [directamente desde la interfaz](https://user-images.githubusercontent.com/61631665/129977677-83a7d067-c192-45e1-98ae-b5a4927393be.png) [(youtube-dl)](https://github.com/ytdl-org/youtube-dl)
|
||||
|
||||
- **Volumen Exponencial**: Hace que el control de volumen
|
||||
sea [exponencial](https://greasyfork.org/en/scripts/397686-youtube-music-fix-volume-ratio/) para facilitar la
|
||||
selección de volúmenes más bajos
|
||||
|
||||
- **Menú en la Aplicación**: [da a las barras un aspecto elegante y oscuro](https://user-images.githubusercontent.com/78568641/112215894-923dbf00-8c29-11eb-95c3-3ce15db27eca.png)
|
||||
|
||||
> (consulta [esta publicación](https://github.com/th-ch/youtube-music/issues/410#issuecomment-952060709) si tienes problemas
|
||||
para acceder al menú después de habilitar este plugin y la opción hide-menu)
|
||||
|
||||
- **Scrobbler**: Agrega soporte para scrobbling en [Last.fm](https://www.last.fm/) y [ListenBrainz](https://listenbrainz.org/)
|
||||
|
||||
- **Lumia Stream**: Agrega soporte para [Lumia Stream](https://lumiastream.com/)
|
||||
|
||||
- **Letras Genius**: Agrega soporte de letras para la mayoría de las canciones
|
||||
|
||||
- **Music Together**: Comparte una lista de reproducción con otros. Cuando el anfitrión reproduce una canción, todos los demás escucharán la misma canción
|
||||
|
||||
- **Navegación**: Flechas de siguiente/anterior integradas directamente en la interfaz, como en tu navegador favorito
|
||||
|
||||
- **Sin Inicio de Sesión de Google**: Elimina los botones y enlaces de inicio de sesión de Google de la interfaz
|
||||
|
||||
- **Notificaciones**: Muestra una notificación cuando comienza una canción
|
||||
a reproducirse ([notificaciones interactivas](https://user-images.githubusercontent.com/78568641/114102651-63ce0e00-98d0-11eb-9dfe-c5a02bb54f9c.png)
|
||||
están disponibles en Windows)
|
||||
|
||||
- **Picture-in-picture**: permite cambiar la aplicación al modo picture-in-picture
|
||||
|
||||
- **Velocidad de Reproducción**: Escucha rápido, escucha
|
||||
lento! [Agrega un deslizador que controla la velocidad de reproducción de las canciones](https://user-images.githubusercontent.com/61631665/129976003-e55db5ba-bf42-448c-a059-26a009775e68.png)
|
||||
|
||||
- **Volumen Preciso**: Controla el volumen de forma precisa utilizando la rueda del mouse/atajos de teclado, con un HUD personalizado y pasos de volumen personalizables
|
||||
|
||||
- **Atajos (& MPRIS)**: Permite configurar atajos globales para la reproducción (reproducir/pausar/siguiente/anterior) +
|
||||
desactivar [osd multimedia](https://user-images.githubusercontent.com/84923831/128601225-afa38c1f-dea8-4209-9f72-0f84c1dd8b54.png)
|
||||
al anular las teclas multimedia + habilitar Ctrl/CMD + F para buscar + habilitar el soporte mpris de Linux para
|
||||
teclas multimedia + [atajos personalizados](https://github.com/Araxeus/youtube-music/blob/1e591d6a3df98449bcda6e63baab249b28026148/providers/song-controls.js#L13-L50)
|
||||
para [usuarios avanzados](https://github.com/th-ch/youtube-music/issues/106#issuecomment-952156902)
|
||||
|
||||
- **Saltar Canción no Gustada**: Salta las canciones que no te gustan
|
||||
|
||||
- **Saltar Silencios**: Salta automáticamente las secciones de silencio
|
||||
|
||||
- [**SponsorBlock**](https://github.com/ajayyy/SponsorBlock): Salta automáticamente las partes que no son de música, como la introducción/final o
|
||||
partes de videos musicales donde no se reproduce la canción
|
||||
|
||||
- **Control Multimedia en la Barra de Tareas**: Controla la reproducción desde
|
||||
la [barra de tareas de Windows](https://user-images.githubusercontent.com/78568641/111916130-24a35e80-8a82-11eb-80c8-5021c1aa27f4.png)
|
||||
|
||||
- **TouchBar**: Diseño personalizado de TouchBar para macOS
|
||||
|
||||
- **Tuna OBS**: Integración con el complemento [Tuna](https://obsproject.com/forum/resources/tuna.843/) de [OBS](https://obsproject.com/)
|
||||
|
||||
- **Cambiador de Calidad de Video**: Permite cambiar la calidad del video con
|
||||
un [botón](https://user-images.githubusercontent.com/78568641/138574366-70324a5e-2d64-4f6a-acdd-dc2a2b9cecc5.png) en
|
||||
la superposición de video
|
||||
|
||||
- **Alternar Video**: Agrega
|
||||
un [botón](https://user-images.githubusercontent.com/28893833/173663950-63e6610e-a532-49b7-9afa-54cb57ddfc15.png) para
|
||||
alternar entre el modo de video/canción. también puede eliminar opcionalmente toda la pestaña de video
|
||||
|
||||
- **Visualizador**: Diferentes visualizadores de música
|
||||
|
||||
## Traducción
|
||||
|
||||
Puedes ayudar con la traducción en [Hosted Weblate](https://hosted.weblate.org/projects/youtube-music/).
|
||||
|
||||
<a href="https://hosted.weblate.org/engage/youtube-music/">
|
||||
<img src="https://hosted.weblate.org/widget/youtube-music/i18n/multi-auto.svg" alt="estado de traducción" />
|
||||
<img src="https://hosted.weblate.org/widget/youtube-music/i18n/287x66-black.png" alt="estado de traducción 2" />
|
||||
</a>
|
||||
|
||||
## Descarga
|
||||
|
||||
Puedes consultar la [última versión](https://github.com/th-ch/youtube-music/releases/latest) para encontrar rápidamente la versión más reciente.
|
||||
|
||||
### Arch Linux
|
||||
|
||||
Instala el paquete [`youtube-music-bin`](https://aur.archlinux.org/packages/youtube-music-bin) desde AUR. Para obtener instrucciones de instalación de AUR, consulta esta [página del wiki](https://wiki.archlinux.org/index.php/Arch_User_Repository#Installing_packages).
|
||||
|
||||
### macOS
|
||||
|
||||
Puedes instalar la aplicación usando Homebrew (consulta la [definición de cask](https://github.com/th-ch/homebrew-youtube-music)):
|
||||
|
||||
```bash
|
||||
brew install th-ch/youtube-music/youtube-music
|
||||
```
|
||||
|
||||
Si instalas la aplicación manualmente y obtienes un error "está dañado y no se puede abrir" al iniciar la aplicación, ejecuta lo siguiente en la Terminal:
|
||||
|
||||
```bash
|
||||
xattr -cr /Applications/YouTube\ Music.app
|
||||
```
|
||||
|
||||
### Windows
|
||||
|
||||
Puedes usar el [administrador de paquetes Scoop](https://scoop.sh) para instalar el paquete `youtube-music` desde
|
||||
el [`extras` bucket](https://github.com/ScoopInstaller/Extras).
|
||||
|
||||
```bash
|
||||
scoop bucket add extras
|
||||
scoop install extras/youtube-music
|
||||
```
|
||||
|
||||
Alternativamente, puedes usar [Winget](https://learn.microsoft.com/en-us/windows/package-manager/winget/), el administrador de paquetes CLI oficial de Windows 11 para instalar el paquete `th-ch.YouTubeMusic`.
|
||||
|
||||
*Nota: Microsoft Defender SmartScreen podría bloquear la instalación ya que proviene de un "editor desconocido". Esto también esválido para la instalación manual al intentar ejecutar el ejecutable (.exe) después de una descarga manual aquí en GitHub (mismo archivo).*
|
||||
|
||||
```bash
|
||||
winget install th-ch.YouTubeMusic
|
||||
```
|
||||
|
||||
#### Cómo instalar sin conexión a Internet? (en Windows)
|
||||
|
||||
- Descarga el archivo `*.nsis.7z` para _la arquitectura de tu dispositivo_ en la [página de lanzamientos](https://github.com/th-ch/youtube-music/releases/latest).
|
||||
- `x64` para Windows de 64 bits
|
||||
- `ia32` para Windows de 32 bits
|
||||
- `arm64` para Windows ARM64
|
||||
- Descarga el instalador en la página de lanzamientos. (`*-Setup.exe`)
|
||||
- Colócalos en el **mismo directorio**.
|
||||
- Ejecuta el instalador.
|
||||
|
||||
## Temas
|
||||
|
||||
Puedes cargar archivos CSS para cambiar la apariencia de la aplicación (Opciones > Ajustes visuales > Tema).
|
||||
|
||||
Algunos temas predefinidos están disponibles en https://github.com/kerichdev/themes-for-ytmdesktop-player.
|
||||
|
||||
## Dev
|
||||
|
||||
```bash
|
||||
git clone https://github.com/th-ch/youtube-music
|
||||
cd youtube-music
|
||||
pnpm install --frozen-lockfile
|
||||
pnpm dev
|
||||
```
|
||||
|
||||
## Crea tus propios plugins
|
||||
|
||||
Usando plugins, puedes:
|
||||
|
||||
- manipular la aplicación - se pasa el `BrowserWindow` de electron al controlador del plugin
|
||||
- cambiar la interfaz manipulando el HTML/CSS
|
||||
|
||||
### Creación de un plugin
|
||||
|
||||
Crea una carpeta en `src/plugins/NOMBRE-DEL-PLUGIN`:
|
||||
|
||||
- `index.ts`: el archivo principal del plugin
|
||||
```typescript
|
||||
import style from './style.css?inline'; // importar estilo como inline
|
||||
|
||||
import { createPlugin } from '@/utils';
|
||||
|
||||
export default createPlugin({
|
||||
name: "Plugin Label",
|
||||
restartNeeded: true, // si el valor es true, ytmusic muestra el diálogo de reinicio
|
||||
config: {
|
||||
enabled: false,
|
||||
}, // tu configuración personalizada
|
||||
stylesheets: [style], // tu estilo personalizado,
|
||||
menu: async ({ getConfig, setConfig }) => {
|
||||
// Todos los métodos *Config están envueltos en Promise<T>
|
||||
const config = await getConfig();
|
||||
return [
|
||||
{
|
||||
label: "menu",
|
||||
submenu: [1, 2, 3].map((value) => ({
|
||||
label: `value ${value}`,
|
||||
type: "radio",
|
||||
checked: config.value === value,
|
||||
click() {
|
||||
setConfig({ value });
|
||||
},
|
||||
})),
|
||||
},
|
||||
];
|
||||
},
|
||||
backend: {
|
||||
start({ window, ipc }) {
|
||||
window.maximize();
|
||||
|
||||
// puedes comunicarte con el plugin de renderizado
|
||||
ipc.handle("some-event", () => {
|
||||
return "hello";
|
||||
});
|
||||
},
|
||||
// se activa cuando cambia la configuración
|
||||
onConfigChange(newConfig) { /* ... */ },
|
||||
// se activa cuando se desactiva el plugin
|
||||
stop(context) { /* ... */ },
|
||||
},
|
||||
renderer: {
|
||||
async start(context) {
|
||||
console.log(await context.ipc.invoke("some-event"));
|
||||
},
|
||||
// Solo disponible en el plugin de renderizado
|
||||
onPlayerApiReady(api: YoutubePlayer, context: RendererContext) {
|
||||
// establecer la configuración del plugin fácilmente
|
||||
context.setConfig({ myConfig: api.getVolume() });
|
||||
},
|
||||
onConfigChange(newConfig) { /* ... */ },
|
||||
stop(_context) { /* ... */ },
|
||||
},
|
||||
preload: {
|
||||
async start({ getConfig }) {
|
||||
const config = await getConfig();
|
||||
},
|
||||
onConfigChange(newConfig) {},
|
||||
stop(_context) {},
|
||||
},
|
||||
});
|
||||
|
||||
```
|
||||
|
||||
### Casos de uso comunes
|
||||
|
||||
- inyectar CSS personalizado: crea un archivo `style.css` en la misma carpeta y luego:
|
||||
|
||||
```typescript
|
||||
// index.ts
|
||||
import style from './style.css?inline'; // importar estilo como inline
|
||||
|
||||
import { createPlugin } from '@/utils';
|
||||
|
||||
export default createPlugin({
|
||||
name: 'Plugin Label',
|
||||
restartNeeded: true, // si el valor es true, ytmusic mostrará el diálogo de reinicio
|
||||
config: {
|
||||
enabled: false,
|
||||
}, // tu configuración personalizada
|
||||
stylesheets: [style], // tu estilo personalizado
|
||||
renderer() {} // define el hook del renderizador
|
||||
});
|
||||
```
|
||||
|
||||
- Si quieres cambiar el HTML:
|
||||
|
||||
```typescript
|
||||
import { createPlugin } from '@/utils';
|
||||
|
||||
export default createPlugin({
|
||||
name: 'Plugin Label',
|
||||
restartNeeded: true, // si el valor es true, ytmusic mostrará el diálogo de reinicio
|
||||
config: {
|
||||
enabled: false,
|
||||
}, // tu configuración personalizada
|
||||
renderer() {
|
||||
// Elimina el botón de inicio de sesión
|
||||
document.querySelector(".sign-in-link.ytmusic-nav-bar").remove();
|
||||
} // define el hook del renderizador
|
||||
});
|
||||
```
|
||||
|
||||
- comunicación entre el front y el back: se puede hacer utilizando el módulo ipcMain de electron. Ver archivo `index.ts` y
|
||||
ejemplo en el plugin `sponsorblock`.
|
||||
|
||||
## Compilar
|
||||
|
||||
1. Clonar el repositorio
|
||||
2. Seguir [esta guía](https://pnpm.io/es/installation) para instalar `pnpm`
|
||||
3. Ejecutar `pnpm install --frozen-lockfile` para instalar las dependencias
|
||||
4. Ejecutar `pnpm build:OS`
|
||||
|
||||
- `pnpm dist:win` - Windows
|
||||
- `pnpm dist:linux` - Linux (amd64)
|
||||
- `pnpm dist:linux:deb-arm64` - Linux (arm64 para Debian)
|
||||
- `pnpm dist:linux:rpm-arm64` - Linux (arm64 para Fedora)
|
||||
- `pnpm dist:mac` - macOS (amd64)
|
||||
- `pnpm dist:mac:arm64` - macOS (arm64)
|
||||
|
||||
Construye la aplicación para macOS, Linux y Windows,
|
||||
utilizando [electron-builder](https://github.com/electron-userland/electron-builder).
|
||||
|
||||
## Vista previa de producción
|
||||
|
||||
```bash
|
||||
pnpm start
|
||||
```
|
||||
|
||||
## Tests
|
||||
|
||||
```bash
|
||||
pnpm test
|
||||
```
|
||||
|
||||
Utiliza [Playwright](https://playwright.dev/) para probar la aplicación.
|
||||
|
||||
## Licencia
|
||||
|
||||
MIT © [th-ch](https://github.com/th-ch/youtube-music)
|
||||
|
||||
## Preguntas frecuentes
|
||||
|
||||
### ¿Por qué no se muestra el menú de aplicaciones?
|
||||
|
||||
Si la opción `Ocultar menú` está activada - puedes mostrar el menú con la tecla <kbd>alt</kbd> (o <kbd>\`</kbd> [acento grave] si estás utilizando el plugin in-app-menu)
|
||||
388
docs/readme/README-fr.md
Normal file
388
docs/readme/README-fr.md
Normal file
@ -0,0 +1,388 @@
|
||||
<div align="center">
|
||||
|
||||
# YouTube Music
|
||||
|
||||
[](https://github.com/th-ch/youtube-music/releases/)
|
||||
[](https://github.com/th-ch/youtube-music/blob/master/LICENSE)
|
||||
[](https://github.com/th-ch/youtube-music/blob/master/.eslintrc.js)
|
||||
[](https://GitHub.com/th-ch/youtube-music/releases/)
|
||||
[](https://GitHub.com/th-ch/youtube-music/releases/)
|
||||
[](https://aur.archlinux.org/packages/youtube-music-bin)
|
||||
[](https://snyk.io/test/github/th-ch/youtube-music)
|
||||
|
||||
</div>
|
||||
|
||||

|
||||
|
||||
|
||||
<div align="center">
|
||||
<a href="https://github.com/th-ch/youtube-music/releases/latest">
|
||||
<img src="https://github.com/th-ch/youtube-music/raw/master/web/youtube-music.svg" width="400" height="100" alt="SVG YouTube Music">
|
||||
</a>
|
||||
</div>
|
||||
|
||||
|
||||
**Enveloppe Electron autour de YouTube Music offrant :**
|
||||
|
||||
- Aspect & sensation naturels, vise à conserver l'interface originale
|
||||
- Cadre pour les plugins personnalisés : modifiez YouTube Music selon vos besoins (style, contenu, fonctionnalités), activez/désactivez les plugins en
|
||||
un clic
|
||||
|
||||
## Image de démonstration
|
||||
|
||||
| Écran du lecteur (thème de couleur de l'album & lumière ambiante) |
|
||||
|:---------------------------------------------------------------------------------------------------------:|
|
||||
||
|
||||
|
||||
## Contenu
|
||||
|
||||
- [Fonctionnalités](#fonctionnalités)
|
||||
- [Plugins disponibles](#plugins-disponibles)
|
||||
- [Traduction](#traduction)
|
||||
- [Téléchargement](#téléchargement)
|
||||
- [Arch Linux](#arch-linux)
|
||||
- [MacOS](#macos)
|
||||
- [Windows](#windows)
|
||||
- [Comment installer sans connexion réseau ? (sous Windows)](#comment-installer-sans-connexion-réseau-sous-windows)
|
||||
- [Thèmes](#thèmes)
|
||||
- [Dev](#dev)
|
||||
- [Créez vos propres plugins](#créez-vos-propres-plugins)
|
||||
- [Créer un plugin](#créer-un-plugin)
|
||||
- [Cas d'utilisation courants](#cas-dutilisation-courants)
|
||||
- [Construction](#construction)
|
||||
- [Aperçu de la production](#aperçu-de-la-production)
|
||||
- [Tests](#tests)
|
||||
- [Licence](#licence)
|
||||
- [FAQ](#faq)
|
||||
|
||||
## Fonctionnalités :
|
||||
|
||||
- **Confirmation automatique lors de la pause** (Toujours activé) : désactiver
|
||||
la pop-up ["Continuer à regarder ?"](https://user-images.githubusercontent.com/61631665/129977894-01c60740-7ec6-4bf0-9a2c-25da24491b0e.png)
|
||||
qui pause la musique après un certain temps
|
||||
|
||||
- Et plus encore ...
|
||||
|
||||
## Plugins disponibles :
|
||||
|
||||
- **Bloqueur de publicités** : Bloquez toutes les publicités et le suivi dès le départ
|
||||
|
||||
- **Actions d'album** : Ajoute des boutons Je n'aime pas, Dislike, J'aime, et Unlike pour appliquer cela à toutes les chansons dans une playlist ou un album
|
||||
|
||||
- **Thème de couleur d'album** : Applique un thème dynamique et des effets visuels basés sur la palette de couleurs de l'album
|
||||
|
||||
- **Mode Ambiant** : Applique un effet d'éclairage en projetant des couleurs douces de la vidéo, sur l'arrière-plan de votre écran
|
||||
|
||||
- **Compresseur Audio** : Appliquer une compression audio (diminue le volume des parties les plus fortes du signal et augmente le
|
||||
volume des parties les plus douces)
|
||||
|
||||
- **Barre de navigation floue** : rend la barre de navigation transparente et floue
|
||||
|
||||
- **Contournement des restrictions d'âge** : contourner la vérification d'âge de YouTube
|
||||
|
||||
- **Sélecteur de sous-titres** : Activer les sous-titres
|
||||
|
||||
- **Barre latérale compacte** : Toujours définir la barre latérale en mode compact
|
||||
|
||||
- **Fondu enchaîné** : Fondu enchaîné entre les chansons
|
||||
|
||||
- **Désactiver la lecture automatique** : Fait démarrer chaque chanson en mode "pause"
|
||||
|
||||
- **[Discord](https://discord.com/) Présence riche** : Montrez à vos amis ce que vous écoutez
|
||||
avec [Présence riche](https://user-images.githubusercontent.com/28219076/104362104-a7a0b980-5513-11eb-9744-bb89eabe0016.png)
|
||||
|
||||
- **Téléchargeur** : télécharge des
|
||||
MP3 [directement depuis l'interface](https://user-images.githubusercontent.com/61631665/129977677-83a7d067-c192-45e1-98ae-b5a4927393be.png) [(youtube-dl)](https://github.com/ytdl-org/youtube-dl)
|
||||
|
||||
- **Volume exponentiel** : Rend le curseur de volume
|
||||
[exponentiel](https://greasyfork.org/en/scripts/397686-youtube-music-fix-volume-ratio/) afin qu'il soit plus facile de
|
||||
sélectionner des volumes plus bas
|
||||
|
||||
- **Menu In-App** : [donne aux barres un aspect chic et sombre](https://user-images.githubusercontent.com/78568641/112215894-923dbf00-8c29-11eb-95c3-3ce15db27eca.png)
|
||||
|
||||
> (voir [ce poste](https://github.com/th-ch/youtube-music/issues/410#issuecomment-952060709) si vous avez des problèmes
|
||||
pour accéder au menu après avoir activé ce plugin et l'option masquer-menu)
|
||||
|
||||
- **Scrobbler** : Ajoute le support de scrobbling pour [Last.fm](https://www.last.fm/) et [ListenBrainz](https://listenbrainz.org/)
|
||||
|
||||
- **Lumia Stream** : Ajoute le support de [Lumia Stream](https://lumiastream.com/)
|
||||
|
||||
- **Lyrics Genius** : Ajoute le support des paroles pour la plupart des chansons
|
||||
|
||||
- **Musique Ensemble** : Partagez une playlist avec d'autres. Lorsque l'hôte joue une chanson, tout le monde entendra la même chanson
|
||||
|
||||
- **Navigation** : Flèches de navigation Suivant/Retour directement intégrées dans l'interface, comme dans votre navigateur préféré
|
||||
|
||||
- **Pas de connexion Google** : Supprime les boutons et les liens de connexion Google de l'interface
|
||||
|
||||
- **Notifications** : Affiche une notification lorsqu'une chanson commence à jouer ([notifications interactives](https://user-images.githubusercontent.com/78568641/114102651-63ce0e00-98d0-11eb-9dfe-c5a02bb54f9c.png)
|
||||
sont disponibles sur Windows)
|
||||
|
||||
- **Image dans l'image** : permet de passer l'application en mode image dans l'image
|
||||
|
||||
- **Vitesse de lecture** : Écoutez rapidement, écoutez lentement ! [Ajoute un curseur qui contrôle la vitesse des chansons](https://user-images.githubusercontent.com/61631665/129976003-e55db5ba-bf42-448c-a059-26a009775e68.png)
|
||||
|
||||
- **Volume précis** : Contrôlez le volume précisément en utilisant la molette de la souris/raccourcis clavier, avec un hud personnalisé et des étapes de volume personnalisables
|
||||
|
||||
- **Raccourcis (& MPRIS)** : Permet de définir des raccourcis globaux pour la lecture (lecture/pause/suivant/précédent) +
|
||||
désactive [osd média](https://user-images.githubusercontent.com/84923831/128601225-afa38c1f-dea8-4209-9f72-0f84c1dd8b54.png)
|
||||
en remplaçant les touches multimédias + activer Ctrl/CMD + F pour rechercher + activer le support mpris linux pour
|
||||
les touches multimédias + [raccourcis personnalisés](https://github.com/Araxeus/youtube-music/blob/1e591d6a3df98449bcda6e63baab249b28026148/providers/song-controls.js#L13-L50)
|
||||
pour [utilisateurs avancés](https://github.com/th-ch/youtube-music/issues/106#issuecomment-952156902)
|
||||
|
||||
- **Passer la chanson non aimée** : passe les chansons non aimées
|
||||
|
||||
- **Passer les silences** : passe automatiquement les sections silencieuses
|
||||
|
||||
- [**SponsorBlock**](https://github.com/ajayyy/SponsorBlock) : Saute automatiquement les parties non musicales comme les intros/outros ou
|
||||
les parties des clips vidéo où la chanson n'est pas jouée
|
||||
|
||||
- **Contrôle multimédia de la barre des tâches** : Contrôlez la lecture depuis
|
||||
votre [barre des tâches Windows](https://user-images.githubusercontent.com/78568641/111916130-24a35e80-8a82-11eb-80c8-5021c1aa27f4.png)
|
||||
|
||||
- **TouchBar** : Disposition personnalisée de la TouchBar pour macOS
|
||||
|
||||
- **Tuna OBS** : Intégration avec le
|
||||
plugin [Tuna](https://obsproject.com/forum/resources/tuna.843/) d'[OBS](https://obsproject.com/)
|
||||
|
||||
- **Changeur de qualité vidéo** : Permet de changer la qualité vidéo avec
|
||||
un [bouton](https://user-images.githubusercontent.com/78568641/138574366-70324a5e-2d64-4f6a-acdd-dc2a2b9cecc5.png) sur
|
||||
l'overlay vidéo
|
||||
|
||||
- **Bascule vidéo** : Ajoute
|
||||
un [bouton](https://user-images.githubusercontent.com/28893833/173663950-63e6610e-a532-49b7-9afa-54cb57ddfc15.png) pour
|
||||
basculer entre le mode Vidéo/Chanson. peut également supprimer l'onglet vidéo entier
|
||||
|
||||
- **Visualiseur** : Différents visualiseurs musicaux
|
||||
|
||||
## Traduction
|
||||
|
||||
Vous pouvez aider à la traduction sur [Hosted Weblate](https://hosted.weblate.org/projects/youtube-music/).
|
||||
|
||||
<a href="https://hosted.weblate.org/engage/youtube-music/">
|
||||
<img src="https://hosted.weblate.org/widget/youtube-music/i18n/multi-auto.svg" alt="statut de la traduction" />
|
||||
<img src="https://hosted.weblate.org/widget/youtube-music/i18n/287x66-black.png" alt="statut de la traduction 2" />
|
||||
</a>
|
||||
|
||||
## Téléchargement
|
||||
|
||||
Vous pouvez consulter la [dernière sortie](https://github.com/th-ch/youtube-music/releases/latest) pour trouver rapidement la
|
||||
dernière version.
|
||||
|
||||
### Arch Linux
|
||||
|
||||
Installez le paquet [`youtube-music-bin`](https://aur.archlinux.org/packages/youtube-music-bin) depuis l'AUR. Pour les instructions d'installation de l'AUR, consultez
|
||||
cette [page wiki](https://wiki.archlinux.org/index.php/Arch_User_Repository#Installing_packages).
|
||||
|
||||
### MacOS
|
||||
|
||||
Vous pouvez installer l'application en utilisant Homebrew (voir la [définition du fût](https://github.com/th-ch/homebrew-youtube-music)) :
|
||||
|
||||
```bash
|
||||
brew install th-ch/youtube-music/youtube-music
|
||||
```
|
||||
|
||||
Si vous installez l'application manuellement et obtenez une erreur "est endommagé et ne peut pas être ouvert." lors du lancement de l'application, exécutez ce qui suit dans le Terminal :
|
||||
|
||||
```bash
|
||||
xattr -cr /Applications/YouTube\ Music.app
|
||||
```
|
||||
|
||||
### Windows
|
||||
|
||||
Vous pouvez utiliser le [gestionnaire de paquets Scoop](https://scoop.sh) pour installer le paquet `youtube-music` depuis le [seau `extras`](https://github.com/ScoopInstaller/Extras).
|
||||
|
||||
```bash
|
||||
scoop bucket add extras
|
||||
scoop install extras/youtube-music
|
||||
```
|
||||
|
||||
Alternativement, vous pouvez utiliser [Winget](https://learn.microsoft.com/fr-fr/windows/package-manager/winget/), le gestionnaire de paquets CLI officiel de Windows 11, pour installer le paquet `th-ch.YouTubeMusic`.
|
||||
|
||||
*Note : Microsoft Defender SmartScreen pourrait bloquer l'installation car elle provient d'un "éditeur inconnu". Ceci est également vrai pour l'installation manuelle lors de l'essai d'exécution de l'exécutable (.exe) après un téléchargement manuel ici sur GitHub (même fichier).*
|
||||
|
||||
```bash
|
||||
winget install th-ch.YouTubeMusic
|
||||
```
|
||||
|
||||
#### Comment installer sans connexion réseau ? (sous Windows)
|
||||
|
||||
- Téléchargez le fichier `*.nsis.7z` pour _l'architecture de votre appareil_ sur la [page des versions](https://github.com/th-ch/youtube-music/releases/latest).
|
||||
- `x64` pour Windows 64 bits
|
||||
- `ia32` pour Windows 32 bits
|
||||
- `arm64` pour Windows ARM64
|
||||
- Téléchargez l'installeur sur la page des versions. (`*-Setup.exe`)
|
||||
- Placez-les dans le **même dossier**.
|
||||
- Exécutez l'installeur.
|
||||
|
||||
## Thèmes
|
||||
|
||||
Vous pouvez charger des fichiers CSS pour changer l'apparence de l'application (Options > Ajustements visuels > Thèmes).
|
||||
|
||||
Certains thèmes prédéfinis sont disponibles sur [https://github.com/kerichdev/themes-for-ytmdesktop-player](https://github.com/kerichdev/themes-for-ytmdesktop-player).
|
||||
|
||||
## Dev
|
||||
|
||||
```bash
|
||||
git clone https://github.com/th-ch/youtube-music
|
||||
cd youtube-music
|
||||
pnpm install --frozen-lockfile
|
||||
pnpm dev
|
||||
```
|
||||
## Créez vos propres plugins
|
||||
|
||||
En utilisant des plugins, vous pouvez :
|
||||
|
||||
- manipuler l'application - la `BrowserWindow` d'Electron est passée au gestionnaire de plugin
|
||||
- changer le front en manipulant le HTML/CSS
|
||||
|
||||
### Créer un plugin
|
||||
|
||||
Créez un dossier dans `src/plugins/NOM-DE-VOTRE-PLUGIN` :
|
||||
|
||||
- `index.ts` : le fichier principal du plugin
|
||||
```typescript
|
||||
import style from './style.css?inline'; // importez le style comme inline
|
||||
|
||||
import { createPlugin } from '@/utils';
|
||||
|
||||
export default createPlugin({
|
||||
name: 'Étiquette du plugin',
|
||||
restartNeeded: true, // si la valeur est vraie, ytmusic affichera la boîte de dialogue de redémarrage
|
||||
config: {
|
||||
enabled: false,
|
||||
}, // votre configuration personnalisée
|
||||
stylesheets: [style], // votre style personnalisé,
|
||||
menu: async ({ getConfig, setConfig }) => {
|
||||
// Toutes les méthodes *Config sont des promesses encapsulées <T>
|
||||
const config = await getConfig();
|
||||
return [
|
||||
{
|
||||
label: 'menu',
|
||||
submenu: [1, 2, 3].map((value) => ({
|
||||
label: `valeur ${value}`,
|
||||
type: 'radio',
|
||||
checked: config.value === value,
|
||||
click() {
|
||||
setConfig({ value });
|
||||
},
|
||||
})),
|
||||
},
|
||||
];
|
||||
},
|
||||
backend: {
|
||||
start({ window, ipc }) {
|
||||
window.maximize();
|
||||
|
||||
// vous pouvez communiquer avec le plugin du rendu
|
||||
ipc.handle('un événement', () => {
|
||||
return 'bonjour';
|
||||
});
|
||||
},
|
||||
// il est déclenché lorsque la configuration change
|
||||
onConfigChange(newConfig) { /* ... */ },
|
||||
// il est déclenché lorsque le plugin est désactivé
|
||||
stop(context) { /* ... */ },
|
||||
},
|
||||
renderer: {
|
||||
async start(context) {
|
||||
console.log(await context.ipc.invoke('un événement'));
|
||||
},
|
||||
// Seul le crochet disponible pour le rendu
|
||||
onPlayerApiReady(api: YoutubePlayer, context: RendererContext) {
|
||||
// définir facilement la configuration du plugin
|
||||
context.setConfig({ myConfig: api.getVolume() });
|
||||
},
|
||||
onConfigChange(newConfig) { /* ... */ },
|
||||
stop(_context) { /* ... */ },
|
||||
},
|
||||
preload: {
|
||||
async start({ getConfig }) {
|
||||
const config is obtained by `getConfig` method.
|
||||
},
|
||||
onConfigChange(newConfig) {},
|
||||
stop(_context) {},
|
||||
},
|
||||
});
|
||||
|
||||
```
|
||||
|
||||
### Cas d'utilisation courants
|
||||
|
||||
- **Injection de CSS personnalisé** : créez un fichier `style.css` dans le même dossier puis :
|
||||
|
||||
```typescript
|
||||
// index.ts
|
||||
import style from './style.css?inline'; // importez le style comme en ligne
|
||||
|
||||
import { createPlugin } from '@/utils';
|
||||
|
||||
export default createPlugin({
|
||||
name: 'Étiquette du plugin',
|
||||
restartNeeded: true, // si la valeur est vraie, ytmusic affichera la boîte de dialogue de redémarrage
|
||||
config: {
|
||||
enabled: false,
|
||||
}, // votre configuration personnalisée
|
||||
stylesheets: [style], // votre style personnalisé
|
||||
renderer() {} // définissez le crochet de rendu
|
||||
});
|
||||
```
|
||||
|
||||
- **Si vous voulez modifier le HTML** :
|
||||
|
||||
```typescript
|
||||
import { createPlugin } from '@/utils';
|
||||
|
||||
export default createPlugin({
|
||||
name: 'Étiquette du plugin',
|
||||
restartNeeded: true, // si la valeur est vraie, ytmusic affichera la boîte de dialogue de redémarrage
|
||||
config: {
|
||||
enabled: false,
|
||||
}, // votre configuration personnalisée
|
||||
renderer() {
|
||||
// Supprimez le bouton de connexion
|
||||
document.querySelector(".sign-in-link.ytmusic-nav-bar").remove();
|
||||
} // définissez le crochet de rendu
|
||||
});
|
||||
|
||||
```
|
||||
|
||||
- **Communication entre le front et le back** : cela peut se faire en utilisant le module ipcMain d'Electron. Voir le fichier `index.ts` et l'exemple dans le plugin `sponsorblock`.
|
||||
|
||||
## Construction
|
||||
|
||||
1. Clonez le dépôt
|
||||
2. Suivez [ce guide](https://pnpm.io/installation) pour installer `pnpm`
|
||||
3. Exécutez `pnpm install --frozen-lockfile` pour installer les dépendances
|
||||
4. Exécutez `pnpm build:OS`
|
||||
|
||||
- `pnpm dist:win` - pour Windows
|
||||
- `pnpm dist:linux` - pour Linux
|
||||
- `pnpm dist:mac` - pour MacOS
|
||||
|
||||
Construit l'application pour macOS, Linux et Windows,
|
||||
en utilisant [electron-builder](https://github.com/electron-userland/electron-builder).
|
||||
|
||||
## Aperçu de la production
|
||||
|
||||
```bash
|
||||
pnpm start
|
||||
```
|
||||
|
||||
## Tests
|
||||
|
||||
```bash
|
||||
pnpm test
|
||||
```
|
||||
|
||||
Utilise [Playwright](https://playwright.dev/) pour tester l'application.
|
||||
|
||||
## Licence
|
||||
|
||||
MIT © [th-ch](https://github.com/th-ch/youtube-music)
|
||||
|
||||
## FAQ
|
||||
|
||||
### Pourquoi le menu de l'application ne s'affiche-t-il pas ?
|
||||
|
||||
Si l'option `Masquer le menu` est activée - vous pouvez afficher le menu avec la touche <kbd>alt</kbd> (ou <kbd>\`</kbd> [backtick] si vous utilisez le plugin du menu intégré)
|
||||
@ -24,7 +24,7 @@
|
||||
**Electron umbúðir utan um YouTube Tónlist sem inniheldur:**
|
||||
|
||||
- Innfæddur útlit og tilfinning, miðar að því að halda upprunalegu viðmótinu
|
||||
- Rammi fyrir sérsniðnar viðbætur: breyttu YouTube Tónlist að þínum þörfum (stíl, efni, eiginleikar), virkjaðu/slökktu á viðbætur í
|
||||
- Rammi fyrir sérsniðnar tengiforrit: breyttu YouTube Tónlist að þínum þörfum (stíl, efni, eiginleikar), virkjaðu/slökktu á viðbætur í
|
||||
einn smellur
|
||||
|
||||
## Sýnishornsmynd
|
||||
@ -36,7 +36,7 @@
|
||||
## Efni
|
||||
|
||||
- [Eiginleikar](#eiginleikar)
|
||||
- [Tiltæk viðbætur](#tiltæk-viðbætur)
|
||||
- [Tiltæk tengiforrit](#tiltæk-tengiforrit)
|
||||
- [Þýðing](#þýðing)
|
||||
- [Sækja](#sækja)
|
||||
- [Arch Linux](#arch-linux)
|
||||
@ -62,7 +62,7 @@
|
||||
|
||||
- Og meira...
|
||||
|
||||
## Tiltæk viðbætur:
|
||||
## Tiltæk tengiforrit:
|
||||
|
||||
- **Auglýsingablokkari**: Lokaðu fyrir allar auglýsingar og rakningar úr kassanum
|
||||
|
||||
@ -186,7 +186,7 @@ xattr -cr /Applications/YouTube\ Music.app
|
||||
### Windows
|
||||
|
||||
Þú getur notað [Scoop pakkastjórnun](https://scoop.sh) til að setja upp `youtube-music` pakkann frá
|
||||
[`extras` fötuna](https://github.com/ScoopInstaller/Extras).
|
||||
[`extras` fötunni](https://github.com/ScoopInstaller/Extras).
|
||||
|
||||
```bash
|
||||
scoop bucket add extras
|
||||
@ -229,18 +229,18 @@ pnpm install --frozen-lockfile
|
||||
pnpm dev
|
||||
```
|
||||
|
||||
## Búðu til þín eigin viðbætur
|
||||
## Búðu til þín eigin tengiforrit
|
||||
|
||||
Með því að nota viðbætur geturðu:
|
||||
Með því að nota tengiforrit geturðu:
|
||||
|
||||
- vinna með appið - `BrowserWindow` frá electron er sent til viðbótarstjórans
|
||||
- vinna með appið - `BrowserWindow` frá electron er sent til tengiforritsstjórans
|
||||
- breyttu framhliðinni með því að vinna með HTML/CSS
|
||||
|
||||
### Er að búa til viðbót
|
||||
### Er að búa til tengiforrit
|
||||
|
||||
Búðu til möppu í `src/plugins/YOUR-PLUGIN-NAME`:
|
||||
|
||||
- `index.ts`: aðal skránni af viðbótin
|
||||
- `index.ts`: aðal skránni af tengiforritið
|
||||
```typescript
|
||||
import style from './style.css?inline'; // flytja inn stíl sem inline
|
||||
|
||||
@ -248,7 +248,7 @@ import { createPlugin } from '@/utils';
|
||||
|
||||
export default createPlugin({
|
||||
name: 'Plugin Label',
|
||||
restartNeeded: true, // ef gildi er satt, ytmusic show endurræsa gluggann
|
||||
restartNeeded: true, // ef gildi er satt, ytmusic sjá endurræsa gluggann
|
||||
config: {
|
||||
enabled: false,
|
||||
}, // sérsniðnastillingar þinn
|
||||
@ -274,7 +274,7 @@ export default createPlugin({
|
||||
start({ window, ipc }) {
|
||||
window.maximize();
|
||||
|
||||
// þú getur tengst við renderer viðbótina
|
||||
// þú getur tengst við renderer tengiforritið
|
||||
ipc.handle('some-event', () => {
|
||||
return 'hello';
|
||||
});
|
||||
@ -318,7 +318,7 @@ import { createPlugin } from '@/utils';
|
||||
|
||||
export default createPlugin({
|
||||
name: 'Plugin Label',
|
||||
restartNeeded: true, // ef gildi er satt, ytmusic show endurræsa gluggann
|
||||
restartNeeded: true, // ef gildi er satt, ytmusic sjá endurræsa gluggann
|
||||
config: {
|
||||
enabled: false,
|
||||
}, // sérsniðnastillingar þinn
|
||||
@ -334,7 +334,7 @@ import { createPlugin } from '@/utils';
|
||||
|
||||
export default createPlugin({
|
||||
name: 'Plugin Label',
|
||||
restartNeeded: true, // ef gildi er satt, ytmusic show endurræsa gluggann
|
||||
restartNeeded: true, // ef gildi er satt, ytmusic sjá endurræsa gluggann
|
||||
config: {
|
||||
enabled: false,
|
||||
}, // sérsniðnastillingar þinn
|
||||
@ -346,7 +346,7 @@ export default createPlugin({
|
||||
```
|
||||
|
||||
- samskipti á milli að framan og aftan: hægt að gera með því að nota ipcMain eininguna frá electron. Sjá `index.ts` skrá og
|
||||
dæmi í 'styrktarblokk' viðbótinni.
|
||||
dæmi í 'styrktarblokk' tengiforritinu.
|
||||
|
||||
## Byggja
|
||||
|
||||
|
||||
374
docs/readme/README-ru.md
Normal file
374
docs/readme/README-ru.md
Normal file
@ -0,0 +1,374 @@
|
||||
<div align="center">
|
||||
|
||||
# YouTube Music
|
||||
|
||||
[](https://github.com/th-ch/youtube-music/releases/)
|
||||
[](https://github.com/th-ch/youtube-music/blob/master/LICENSE)
|
||||
[](https://github.com/th-ch/youtube-music/blob/master/.eslintrc.js)
|
||||
[](https://GitHub.com/th-ch/youtube-music/releases/)
|
||||
[](https://GitHub.com/th-ch/youtube-music/releases/)
|
||||
[](https://aur.archlinux.org/packages/youtube-music-bin)
|
||||
[](https://snyk.io/test/github/th-ch/youtube-music)
|
||||
|
||||
</div>
|
||||
|
||||

|
||||
|
||||
|
||||
<div align="center">
|
||||
<a href="https://github.com/th-ch/youtube-music/releases/latest">
|
||||
<img src="web/youtube-music.svg" width="400" height="100" alt="YouTube Music SVG">
|
||||
</a>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
**Клиент для YouTube Music основанный на Electron с поддержкой:**
|
||||
|
||||
- Нативный вид приложения, нацелен на сохранение оригинального интерфейса
|
||||
- Фреймворк для пользовательских плагинов: изменяйте YouTube Music под ваши нужды (внешний вид, контент, возможности), включайте/выключайте плагины в один клик
|
||||
|
||||
## Демо-изображение
|
||||
|
||||
| Экран плеера (цветовая тема альбома & режим Ambient) |
|
||||
|:---------------------------------------------------------------------------------------------------------:|
|
||||
||
|
||||
|
||||
## Содержание
|
||||
|
||||
- [Возможности](#features)
|
||||
- [Доступные плагины](#available-plugins)
|
||||
- [Перевод](#translation)
|
||||
- [Скачать](#download)
|
||||
- [Arch Linux](#arch-linux)
|
||||
- [MacOS](#macos)
|
||||
- [Windows](#windows)
|
||||
- [Как установить без подключения к интернету? (в Windows)](#how-to-install-without-a-network-connection-in-windows)
|
||||
- [Темы](#themes)
|
||||
- [Для разработчиков](#dev)
|
||||
- [Создайте свои собственные плагины](#build-your-own-plugins)
|
||||
- [Создание плагина](#creating-a-plugin)
|
||||
- [Примеры использования](#common-use-cases)
|
||||
- [Сборка](#build)
|
||||
- [Предварительный просмотр](#production-preview)
|
||||
- [Тестирование](#tests)
|
||||
- [Лицензия](#license)
|
||||
- [Часто задаваемые вопросы](#faq)
|
||||
|
||||
## Возможности:
|
||||
|
||||
- **Авто-подтверждение при паузе** (Всегда включено): отключает всплывающие уведомление ["Продолжить просмотр?"](https://user-images.githubusercontent.com/61631665/129977894-01c60740-7ec6-4bf0-9a2c-25da24491b0e.png),
|
||||
которое приостанавливает воспроизведение через определённое время
|
||||
|
||||
- И больше ...
|
||||
|
||||
## Доступные плагины:
|
||||
|
||||
- **Блокировщик рекламы**: Блокирует всю рекламу и трекеры
|
||||
|
||||
- **Действия с альбомом**: Добавляет кнопки "Убрать дизлайк", "Дизлайк", "Лайк", "Убрать лайк" и применяет их действия ко всем трекам в плейлисте или альбоме
|
||||
|
||||
- **Цветовая тема альбома**: Применяет динамическую тему и эффекты, основываясь на цветовой палитре альбома
|
||||
|
||||
- **Режим Ambient**: Применяет световой эффект, проецируя нежные цвета из видео на задний фон вашего экрана
|
||||
|
||||
- **Нормализация аудио**: Применяет нормализацию к аудио (уменьшает громкость громких частей трека и повышает громкость тихих частей трека)
|
||||
|
||||
- **Размытие панели навигации**: Делает панель навигации прозрачной и размытой
|
||||
|
||||
- **Обход возрастных ограничений**: Обходит проверку возраста YouTube
|
||||
|
||||
- **Выбор субтитров**: Включить субтитры
|
||||
|
||||
- **Компактная боковая панель**: Всегда показывать боковую панель компактно
|
||||
|
||||
- **Плавный переход**: Плавный переход между треками
|
||||
|
||||
- **Отключить автопроигрыш**: Каждый трек начинается в режиме паузы
|
||||
|
||||
- **[Discord](https://discord.com/) Rich Presence**: Показывает вашим друзьям, что вы слушаете с помощью [Rich Presence](https://user-images.githubusercontent.com/28219076/104362104-a7a0b980-5513-11eb-9744-bb89eabe0016.png)
|
||||
|
||||
- **Загрузчик**: Загрузка MP3 [напрямую из интерфейса](https://user-images.githubusercontent.com/61631665/129977677-83a7d067-c192-45e1-98ae-b5a4927393be.png) [(youtube-dl)](https://github.com/ytdl-org/youtube-dl)
|
||||
|
||||
- **Расширенная громкость**: Делает слайдер громкости [расширенным](https://greasyfork.org/en/scripts/397686-youtube-music-fix-volume-ratio/) облегчая выбор громкости
|
||||
|
||||
- **Меню в приложении**: [Придаёт панели меню красивый тёмный вид](https://user-images.githubusercontent.com/78568641/112215894-923dbf00-8c29-11eb-95c3-3ce15db27eca.png)
|
||||
|
||||
> (посмотрите [этот пост,](https://github.com/th-ch/youtube-music/issues/410#issuecomment-952060709) если у вас есть проблемы с доступом к меню после включения этого плагина и опции "Скрыть меню")
|
||||
|
||||
- **Скробблер**: Добавляет поддержку скробблинга [Last.fm](https://www.last.fm/) и [ListenBrainz](https://listenbrainz.org/)
|
||||
|
||||
- **Lumia Stream**: Добавляет поддержку [Lumia Stream](https://lumiastream.com/)
|
||||
|
||||
- **Тесты песен Genius**: Добавляет поддержку текстов для большинства песен
|
||||
|
||||
- **Music Together**: Делитесь плейлистом с другими. Когда ведущий воспроизводит трек, все остальные будут слушать этот же трек.
|
||||
|
||||
- **Навигация**: Кнопки Назад/Вперед интегрированы в интерфейс, как в вашем любимом браузере
|
||||
|
||||
- **Без входа в систему Google**: Убирает из интерфейса кнопки и ссылки для входа через Google
|
||||
|
||||
- **Уведомления**: Показывает уведомление, когда трек начинает играть ([интерактивные уведомления](https://user-images.githubusercontent.com/78568641/114102651-63ce0e00-98d0-11eb-9dfe-c5a02bb54f9c.png) доступны только для Windows)
|
||||
|
||||
- **Картинка в картинке**: Позволяет переключить приложение в режим "картинка в картинке"
|
||||
|
||||
- **Скорость воспроизведения**: Слушайте быстрее, слушайте медленнее! [Добавляет слайдер для контроля скорости трека](https://user-images.githubusercontent.com/61631665/129976003-e55db5ba-bf42-448c-a059-26a009775e68.png)
|
||||
|
||||
- **Точная громкость**: Точечно управляйте громкостью с помощью колеса мыши/горячих клавиш, с кастомным интерфейсом и настраиваемыми шагами громкости
|
||||
|
||||
- **Ярлыки (и MPRIS)**: Позволяет настроить глобальные горячие клавиши управления воспроизведением (плей/пауза/следующий/предыдущий) + отключает [отображение медиа на экране,](https://user-images.githubusercontent.com/84923831/128601225-afa38c1f-dea8-4209-9f72-0f84c1dd8b54.png) переопределяя клавиши управления + включает Ctrl/CMD + F для поиска + включает поддержку linux mpris для клавиш управления медиа + [настраиваемые сочетания клавиш](https://github.com/Araxeus/youtube-music/blob/1e591d6a3df98449bcda6e63baab249b28026148/providers/song-controls.js#L13-L50) для [продвинутых пользователей](https://github.com/th-ch/youtube-music/issues/106#issuecomment-952156902)
|
||||
|
||||
- **Пропускать непонравившиеся треки**: Пропускает непонравившиеся треки
|
||||
|
||||
- **Пропуск тишины**: Автоматически пропускает тихие моменты в песнях
|
||||
|
||||
- [**SponsorBlock**](https://github.com/ajayyy/SponsorBlock): Автоматически пропускает немузыкальные части, такие как интро/аутро музыкальных видео, где трек не играет
|
||||
|
||||
- **Управление воспроизведением из панели задач**: Управляйте воспроизведением из [панели задач Windows](https://user-images.githubusercontent.com/78568641/111916130-24a35e80-8a82-11eb-80c8-5021c1aa27f4.png)
|
||||
|
||||
- **TouchBar**: Кастомная раскладка TouchBar для MacOS
|
||||
|
||||
- **Tuna OBS**: Интеграция с [OBS](https://obsproject.com/) плагином [Tuna](https://obsproject.com/forum/resources/tuna.843/)
|
||||
|
||||
- **Изменение качества видео**: Позволяет менять качество видео [кнопкой](https://user-images.githubusercontent.com/78568641/138574366-70324a5e-2d64-4f6a-acdd-dc2a2b9cecc5.png) на медиаплеере видео
|
||||
|
||||
- **Переключатель видео**: Добавляет
|
||||
[кнопку](https://user-images.githubusercontent.com/28893833/173663950-63e6610e-a532-49b7-9afa-54cb57ddfc15.png) переключения режимов Трек/Видео. Также может удалять вкладку "Видео" полностью
|
||||
|
||||
- **Визуализатор**: Различные визуализаторы музыки
|
||||
|
||||
- **Synced Lyrics**:
|
||||
Предоставляет синхронизированные слова для песен из таких источников, как [LRClib](https://lrclib.net).
|
||||
|
||||
## Перевод
|
||||
|
||||
Вы можете помочь с переводом на ваш язык на [Hosted Weblate](https://hosted.weblate.org/projects/youtube-music/).
|
||||
|
||||
<a href="https://hosted.weblate.org/engage/youtube-music/">
|
||||
<img src="https://hosted.weblate.org/widget/youtube-music/i18n/multi-auto.svg" alt="translation status" />
|
||||
<img src="https://hosted.weblate.org/widget/youtube-music/i18n/287x66-black.png" alt="translation status 2" />
|
||||
</a>
|
||||
|
||||
## Скачать
|
||||
|
||||
Вы можете посмотреть [latest release,](https://github.com/th-ch/youtube-music/releases/latest) чтобы быстро найти новую версию.
|
||||
|
||||
### Arch Linux
|
||||
|
||||
Установите пакет [`youtube-music-bin`](https://aur.archlinux.org/packages/youtube-music-bin) из AUR. Инструкции по установке из AUR можете найти на этой [вики-странице](https://wiki.archlinux.org/index.php/Arch_User_Repository#Installing_packages).
|
||||
|
||||
### macOS
|
||||
|
||||
Вы можете установить приложение с помощью Homebrew (сморите [cask definition](https://github.com/th-ch/homebrew-youtube-music)):
|
||||
|
||||
```bash
|
||||
brew install th-ch/youtube-music/youtube-music
|
||||
```
|
||||
|
||||
Если вы устанавливаете приложение вручную и получаете ошибку "is damaged and can’t be opened.", запустите в терминале следующую команду:
|
||||
|
||||
```bash
|
||||
xattr -cr /Applications/YouTube\ Music.app
|
||||
```
|
||||
|
||||
### Windows
|
||||
|
||||
Вы можете использовать [пакетный менеджер Scoop](https://scoop.sh) для установки пакета `youtube-music` из [`extras` bucket](https://github.com/ScoopInstaller/Extras).
|
||||
|
||||
```bash
|
||||
scoop bucket add extras
|
||||
scoop install extras/youtube-music
|
||||
```
|
||||
|
||||
Также для установки вы можете использовать [Winget](https://learn.microsoft.com/en-us/windows/package-manager/winget/), официальный пакетный менеджер командной строки Windows 11, для установки пакета `th-ch.YouTubeMusic`.
|
||||
|
||||
*К сведению: SmartScreen защитника Windows может блокировать установку, так как она от "неизвестного издателя". Это также применимо к методу ручной установки, когда вы пытаетесь запустить исполняемый файл(.exe) после загрузки здесь, на GitHub (тот же файл).*
|
||||
|
||||
```bash
|
||||
winget install th-ch.YouTubeMusic
|
||||
```
|
||||
|
||||
#### Установка без подключения к Интернету? (в Windows)
|
||||
|
||||
- Скачайте файл `*.nsis.7z` из _архетиктура вашего устройства_ на [release page](https://github.com/th-ch/youtube-music/releases/latest).
|
||||
- `x64` для 64-bit Windows
|
||||
- `ia32` для 32-bit Windows
|
||||
- `arm64` для ARM64 Windows
|
||||
- Скачайте установщик в release page. (`*-Setup.exe`)
|
||||
- Поместите их в **одной директории**.
|
||||
- Запустите установщик.
|
||||
|
||||
## Темы
|
||||
|
||||
Вы можете загрузить файл CSS для смены внешнего вида приложения (Настройки > Визуальные настройки > Тема).
|
||||
|
||||
Некоторые предустановленные темы доступны здесь: https://github.com/kerichdev/themes-for-ytmdesktop-player.
|
||||
|
||||
## Для разработчиков
|
||||
|
||||
```bash
|
||||
git clone https://github.com/th-ch/youtube-music
|
||||
cd youtube-music
|
||||
pnpm install --frozen-lockfile
|
||||
pnpm dev
|
||||
```
|
||||
|
||||
## Создайте свои собственные плагины
|
||||
|
||||
Используя плагины вы можете:
|
||||
|
||||
- Манипулировать приложением - `BrowserWindow` из electron проброшен обработчику плагинов
|
||||
- Изменять внешний вид, манипулируя HTML/CSS
|
||||
|
||||
### Создание плагина
|
||||
|
||||
Создайте директорию в `src/plugins/YOUR-PLUGIN-NAME`:
|
||||
|
||||
- `index.ts`: основной файл плагина
|
||||
```typescript
|
||||
import style from './style.css?inline'; // import style as inline
|
||||
|
||||
import { createPlugin } from '@/utils';
|
||||
|
||||
export default createPlugin({
|
||||
name: 'Plugin Label',
|
||||
restartNeeded: true, // if value is true, ytmusic show restart dialog
|
||||
config: {
|
||||
enabled: false,
|
||||
}, // your custom config
|
||||
stylesheets: [style], // your custom style,
|
||||
menu: async ({ getConfig, setConfig }) => {
|
||||
// All *Config methods are wrapped Promise<T>
|
||||
const config = await getConfig();
|
||||
return [
|
||||
{
|
||||
label: 'menu',
|
||||
submenu: [1, 2, 3].map((value) => ({
|
||||
label: `value ${value}`,
|
||||
type: 'radio',
|
||||
checked: config.value === value,
|
||||
click() {
|
||||
setConfig({ value });
|
||||
},
|
||||
})),
|
||||
},
|
||||
];
|
||||
},
|
||||
backend: {
|
||||
start({ window, ipc }) {
|
||||
window.maximize();
|
||||
|
||||
// you can communicate with renderer plugin
|
||||
ipc.handle('some-event', () => {
|
||||
return 'hello';
|
||||
});
|
||||
},
|
||||
// it fired when config changed
|
||||
onConfigChange(newConfig) { /* ... */ },
|
||||
// it fired when plugin disabled
|
||||
stop(context) { /* ... */ },
|
||||
},
|
||||
renderer: {
|
||||
async start(context) {
|
||||
console.log(await context.ipc.invoke('some-event'));
|
||||
},
|
||||
// Only renderer available hook
|
||||
onPlayerApiReady(api: YoutubePlayer, context: RendererContext) {
|
||||
// set plugin config easily
|
||||
context.setConfig({ myConfig: api.getVolume() });
|
||||
},
|
||||
onConfigChange(newConfig) { /* ... */ },
|
||||
stop(_context) { /* ... */ },
|
||||
},
|
||||
preload: {
|
||||
async start({ getConfig }) {
|
||||
const config = await getConfig();
|
||||
},
|
||||
onConfigChange(newConfig) {},
|
||||
stop(_context) {},
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
### Примеры использования
|
||||
|
||||
- Кастомный CSS: создайте файл `style.css` в той же директории, затем:
|
||||
|
||||
```typescript
|
||||
// index.ts
|
||||
import style from './style.css?inline'; // import style as inline
|
||||
|
||||
import { createPlugin } from '@/utils';
|
||||
|
||||
export default createPlugin({
|
||||
name: 'Plugin Label',
|
||||
restartNeeded: true, // if value is true, ytmusic will show a restart dialog
|
||||
config: {
|
||||
enabled: false,
|
||||
}, // your custom config
|
||||
stylesheets: [style], // your custom style
|
||||
renderer() {} // define renderer hook
|
||||
});
|
||||
```
|
||||
|
||||
- Если вы хотите изменить HTML:
|
||||
|
||||
```typescript
|
||||
import { createPlugin } from '@/utils';
|
||||
|
||||
export default createPlugin({
|
||||
name: 'Plugin Label',
|
||||
restartNeeded: true, // if value is true, ytmusic will show the restart dialog
|
||||
config: {
|
||||
enabled: false,
|
||||
}, // your custom config
|
||||
renderer() {
|
||||
// Remove the login button
|
||||
document.querySelector(".sign-in-link.ytmusic-nav-bar").remove();
|
||||
} // define renderer hook
|
||||
});
|
||||
```
|
||||
|
||||
- обмен между фронтом и бэком может быть выполнен с помощью модуля ipcMain из electron. Смотрите файл `index.ts` и
|
||||
пример в плагине `sponsorblock`.
|
||||
|
||||
## Сборка
|
||||
|
||||
1. Склонируйте репозиторий
|
||||
2. Следуйте [этой инструкции,](https://pnpm.io/installation) чтобы установить `pnpm`
|
||||
3. Запустите `pnpm install --frozen-lockfile` для установки зависимостей
|
||||
4. Запустите `pnpm build:OS`
|
||||
|
||||
- `pnpm dist:win` - Windows
|
||||
- `pnpm dist:linux` - Linux (amd64)
|
||||
- `pnpm dist:linux:deb-arm64` - Linux (arm64 for Debian)
|
||||
- `pnpm dist:linux:rpm-arm64` - Linux (arm64 for Fedora)
|
||||
- `pnpm dist:mac` - macOS (amd64)
|
||||
- `pnpm dist:mac:arm64` - macOS (arm64)
|
||||
|
||||
Сборка приложения для macOS, Linux, и Windows,
|
||||
используя [electron-builder](https://github.com/electron-userland/electron-builder).
|
||||
|
||||
## Предварительный просмотр
|
||||
|
||||
```bash
|
||||
pnpm start
|
||||
```
|
||||
|
||||
## Тестирование
|
||||
|
||||
```bash
|
||||
pnpm test
|
||||
```
|
||||
|
||||
Использует [Playwright](https://playwright.dev/) для тестирования приложения.
|
||||
|
||||
## Лицензия
|
||||
|
||||
MIT © [th-ch](https://github.com/th-ch/youtube-music)
|
||||
|
||||
## Часто задаваемые вопросы
|
||||
|
||||
### Почему меня приложения не отображается?
|
||||
|
||||
Если опция `Скрыть меню` включена - вы можете отобразить меню с помощью клавиши <kbd>alt</kbd> (или <kbd>\`</kbd> [обратный апостроф], если используете плагин "Меню в приложении")
|
||||
@ -1,17 +1,17 @@
|
||||
import { resolve, dirname } from 'node:path';
|
||||
import { resolve, dirname, join } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
import { UserConfig } from 'vite';
|
||||
import { defineConfig, defineViteConfig } from 'electron-vite';
|
||||
import builtinModules from 'builtin-modules';
|
||||
import viteResolve from 'vite-plugin-resolve';
|
||||
import Inspect from 'vite-plugin-inspect';
|
||||
import solidPlugin from 'vite-plugin-solid';
|
||||
|
||||
import { pluginVirtualModuleGenerator } from './vite-plugins/plugin-importer.mjs';
|
||||
import pluginLoader from './vite-plugins/plugin-loader.mjs';
|
||||
|
||||
import type { UserConfig } from 'vite';
|
||||
import { i18nImporter } from './vite-plugins/i18n-importer.mjs';
|
||||
import solidPlugin from 'vite-plugin-solid';
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
@ -51,8 +51,12 @@ export default defineConfig({
|
||||
};
|
||||
|
||||
if (mode === 'development') {
|
||||
commonConfig.build!.sourcemap = 'inline';
|
||||
commonConfig.plugins?.push(
|
||||
Inspect({ build: true, outputDir: '.vite-inspect/backend' }),
|
||||
Inspect({
|
||||
build: true,
|
||||
outputDir: join(__dirname, '.vite-inspect/backend'),
|
||||
}),
|
||||
);
|
||||
return commonConfig;
|
||||
}
|
||||
@ -95,8 +99,12 @@ export default defineConfig({
|
||||
};
|
||||
|
||||
if (mode === 'development') {
|
||||
commonConfig.build!.sourcemap = 'inline';
|
||||
commonConfig.plugins?.push(
|
||||
Inspect({ build: true, outputDir: '.vite-inspect/preload' }),
|
||||
Inspect({
|
||||
build: true,
|
||||
outputDir: join(__dirname, '.vite-inspect/preload'),
|
||||
}),
|
||||
);
|
||||
return commonConfig;
|
||||
}
|
||||
@ -142,8 +150,12 @@ export default defineConfig({
|
||||
};
|
||||
|
||||
if (mode === 'development') {
|
||||
commonConfig.build!.sourcemap = 'inline';
|
||||
commonConfig.plugins?.push(
|
||||
Inspect({ build: true, outputDir: '.vite-inspect/renderer' }),
|
||||
Inspect({
|
||||
build: true,
|
||||
outputDir: join(__dirname, '.vite-inspect/renderer'),
|
||||
}),
|
||||
);
|
||||
return commonConfig;
|
||||
}
|
||||
|
||||
80
eslint.config.mjs
Normal file
80
eslint.config.mjs
Normal file
@ -0,0 +1,80 @@
|
||||
//@ts-check
|
||||
|
||||
import eslint from '@eslint/js';
|
||||
import prettier from 'eslint-plugin-prettier/recommended';
|
||||
import stylistic from '@stylistic/eslint-plugin-js';
|
||||
import tsEslint from 'typescript-eslint';
|
||||
|
||||
import * as importPlugin from 'eslint-plugin-import';
|
||||
|
||||
export default tsEslint.config(
|
||||
eslint.configs.recommended,
|
||||
tsEslint.configs.eslintRecommended,
|
||||
...tsEslint.configs.recommendedTypeChecked,
|
||||
prettier,
|
||||
{ ignores: ['dist', 'node_modules', '*.config.*js', '*.test.*js'] },
|
||||
{
|
||||
plugins: {
|
||||
stylistic,
|
||||
importPlugin
|
||||
},
|
||||
languageOptions: {
|
||||
parser: tsEslint.parser,
|
||||
parserOptions: {
|
||||
project: true,
|
||||
sourceType: 'module',
|
||||
ecmaVersion: 'latest'
|
||||
}
|
||||
},
|
||||
rules: {
|
||||
'stylistic/arrow-parens': ['error', 'always'],
|
||||
'stylistic/object-curly-spacing': ['error', 'always'],
|
||||
'prettier/prettier': ['error', { singleQuote: true, semi: true, tabWidth: 2, trailingComma: 'all', quoteProps: 'preserve' }],
|
||||
'@typescript-eslint/no-floating-promises': 'off',
|
||||
'@typescript-eslint/no-misused-promises': ['off', { checksVoidReturn: false }],
|
||||
'@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_' }],
|
||||
'@typescript-eslint/no-non-null-assertion': 'off',
|
||||
'importPlugin/first': 'error',
|
||||
'importPlugin/newline-after-import': 'off',
|
||||
'importPlugin/no-default-export': 'off',
|
||||
'importPlugin/no-duplicates': 'error',
|
||||
'importPlugin/no-unresolved': ['error', { ignore: ['^virtual:', '\\?inline$', '\\?raw$', '\\?asset&asarUnpack'] }],
|
||||
'importPlugin/order': ['error', {
|
||||
'groups': ['builtin', 'external', ['internal', 'index', 'sibling'], 'parent', 'type'],
|
||||
'newlines-between': 'always-and-inside-groups',
|
||||
'alphabetize': { order: 'ignore', caseInsensitive: false }
|
||||
}],
|
||||
'importPlugin/prefer-default-export': 'off',
|
||||
'camelcase': ['error', { properties: 'never' }],
|
||||
'class-methods-use-this': 'off',
|
||||
'stylistic/lines-around-comment': ['error', {
|
||||
beforeBlockComment: false,
|
||||
afterBlockComment: false,
|
||||
beforeLineComment: false,
|
||||
afterLineComment: false,
|
||||
}],
|
||||
'stylistic/max-len': 'off',
|
||||
'stylistic/no-mixed-operators': 'warn', // prettier does not support no-mixed-operators
|
||||
'stylistic/no-multi-spaces': ['error', { ignoreEOLComments: true }],
|
||||
'stylistic/no-tabs': 'error',
|
||||
'no-void': 'error',
|
||||
'no-empty': 'off',
|
||||
'prefer-promise-reject-errors': 'off',
|
||||
'stylistic/quotes': ['error', 'single', {
|
||||
avoidEscape: true,
|
||||
allowTemplateLiterals: false,
|
||||
}],
|
||||
'stylistic/quote-props': ['error', 'consistent'],
|
||||
'stylistic/semi': ['error', 'always'],
|
||||
},
|
||||
settings: {
|
||||
'import/parsers': {
|
||||
'@typescript-eslint/parser': ['.ts']
|
||||
},
|
||||
'import/resolver': {
|
||||
typescript: {},
|
||||
exports: {},
|
||||
},
|
||||
},
|
||||
},
|
||||
);
|
||||
207
package.json
207
package.json
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "youtube-music",
|
||||
"productName": "YouTube Music",
|
||||
"version": "3.3.5",
|
||||
"version": "3.6.2",
|
||||
"description": "YouTube Music Desktop App - including custom plugins",
|
||||
"main": "./dist/main/index.js",
|
||||
"license": "MIT",
|
||||
@ -40,7 +40,8 @@
|
||||
]
|
||||
}
|
||||
],
|
||||
"icon": "assets/generated/icons/mac/icon.icns"
|
||||
"icon": "assets/generated/icons/mac/icon.icns",
|
||||
"compression": "maximum"
|
||||
},
|
||||
"win": {
|
||||
"icon": "assets/generated/icons/win/icon.ico",
|
||||
@ -61,7 +62,8 @@
|
||||
"arm64"
|
||||
]
|
||||
}
|
||||
]
|
||||
],
|
||||
"compression": "maximum"
|
||||
},
|
||||
"nsisWeb": {
|
||||
"runAfterFinish": false
|
||||
@ -70,16 +72,88 @@
|
||||
"icon": "assets/generated/icons/png",
|
||||
"category": "AudioVideo",
|
||||
"target": [
|
||||
"AppImage",
|
||||
"snap",
|
||||
"freebsd",
|
||||
"deb",
|
||||
"rpm"
|
||||
{
|
||||
"target": "AppImage",
|
||||
"arch": [
|
||||
"x64",
|
||||
"arm64",
|
||||
"armv7l"
|
||||
]
|
||||
},
|
||||
{
|
||||
"target": "flatpak",
|
||||
"arch": [
|
||||
"x64"
|
||||
]
|
||||
},
|
||||
{
|
||||
"target": "deb",
|
||||
"arch": [
|
||||
"x64",
|
||||
"arm64",
|
||||
"armv7l"
|
||||
]
|
||||
},
|
||||
{
|
||||
"target": "rpm",
|
||||
"arch": [
|
||||
"x64",
|
||||
"arm64"
|
||||
]
|
||||
},
|
||||
{
|
||||
"target": "snap",
|
||||
"arch": [
|
||||
"x64"
|
||||
]
|
||||
},
|
||||
{
|
||||
"target": "freebsd",
|
||||
"arch": [
|
||||
"x64",
|
||||
"arm64",
|
||||
"armv7l"
|
||||
]
|
||||
},
|
||||
{
|
||||
"target": "tar.gz",
|
||||
"arch": [
|
||||
"x64",
|
||||
"arm64",
|
||||
"armv7l"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"appImage": {
|
||||
"description": "YouTube Music Desktop App bundled with custom plugins (and built-in ad blocker / downloader)",
|
||||
"category": "AudioVideo"
|
||||
},
|
||||
"flatpak": {
|
||||
"description": "YouTube Music Desktop App bundled with custom plugins (and built-in ad blocker / downloader)",
|
||||
"category": "AudioVideo"
|
||||
},
|
||||
"deb": {
|
||||
"depends": [
|
||||
"libgtk-3-0",
|
||||
"libnotify4",
|
||||
"libnss3",
|
||||
"libxss1",
|
||||
"libxtst6",
|
||||
"xdg-utils",
|
||||
"libatspi2.0-0",
|
||||
"libuuid1",
|
||||
"libasound2",
|
||||
"libgbm1"
|
||||
]
|
||||
},
|
||||
"rpm": {
|
||||
"depends": [
|
||||
"/usr/lib64/libuuid.so.1"
|
||||
],
|
||||
"fpm": [
|
||||
"--rpm-rpmbuild-define",
|
||||
"_build_id_links none"
|
||||
]
|
||||
},
|
||||
"snap": {
|
||||
@ -102,11 +176,13 @@
|
||||
"vite:inspect": "pnpm clean && electron-vite build --mode development && pnpm exec serve .vite-inspect",
|
||||
"start": "electron-vite preview",
|
||||
"start:debug": "cross-env ELECTRON_ENABLE_LOGGING=1 pnpm start",
|
||||
"dev": "electron-vite dev --watch",
|
||||
"dev": "cross-env NODE_OPTIONS=--enable-source-maps electron-vite dev --watch",
|
||||
"dev:debug": "cross-env ELECTRON_ENABLE_LOGGING=1 pnpm dev",
|
||||
"clean": "del-cli dist && del-cli pack && del-cli .vite-inspect",
|
||||
"dist": "pnpm clean && pnpm build && pnpm electron-builder --win --mac --linux -p never",
|
||||
"dist:linux": "pnpm clean && pnpm build && pnpm electron-builder --linux -p never",
|
||||
"dist:linux:deb-arm64": "pnpm clean && pnpm build && pnpm electron-builder --linux deb:arm64 -p never",
|
||||
"dist:linux:rpm-arm64": "pnpm clean && pnpm build && pnpm electron-builder --linux rpm:arm64 -p never",
|
||||
"dist:mac": "pnpm clean && pnpm build && pnpm electron-builder --mac dmg:x64 -p never",
|
||||
"dist:mac:arm64": "pnpm clean && pnpm build && pnpm electron-builder --mac dmg:arm64 -p never",
|
||||
"dist:win": "pnpm clean && pnpm build && pnpm electron-builder --win -p never",
|
||||
@ -119,112 +195,127 @@
|
||||
"typecheck": "tsc -p tsconfig.json --noEmit"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
"node": ">=18",
|
||||
"pnpm": ">=8"
|
||||
},
|
||||
"pnpm": {
|
||||
"overrides": {
|
||||
"usocket": "1.0.1",
|
||||
"node-gyp": "10.0.1",
|
||||
"node-gyp": "10.2.0",
|
||||
"xml2js": "0.6.2",
|
||||
"node-fetch": "3.3.2",
|
||||
"@electron/universal": "2.0.1",
|
||||
"@babel/runtime": "7.23.8"
|
||||
"@babel/runtime": "7.25.7"
|
||||
},
|
||||
"patchedDependencies": {
|
||||
"vudio@2.1.1": "patches/vudio@2.1.1.patch",
|
||||
"@xhayper/discord-rpc@1.1.2": "patches/@xhayper__discord-rpc@1.1.2.patch"
|
||||
"app-builder-lib@24.13.3": "patches/app-builder-lib@24.13.3.patch",
|
||||
"@malept/flatpak-bundler": "patches/@malept__flatpak-bundler.patch"
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@cliqz/adblocker-electron": "1.26.16",
|
||||
"@cliqz/adblocker-electron-preload": "1.26.16",
|
||||
"@cliqz/adblocker-electron": "1.27.1",
|
||||
"@cliqz/adblocker-electron-preload": "1.27.1",
|
||||
"@electron-toolkit/tsconfig": "1.0.1",
|
||||
"@electron/remote": "2.1.2",
|
||||
"@ffmpeg.wasm/core-mt": "0.12.0",
|
||||
"@ffmpeg.wasm/main": "0.12.0",
|
||||
"@floating-ui/dom": "1.6.3",
|
||||
"@floating-ui/dom": "1.6.11",
|
||||
"@foobar404/wave": "2.0.5",
|
||||
"@hono/node-server": "1.13.2",
|
||||
"@hono/swagger-ui": "0.4.1",
|
||||
"@hono/zod-openapi": "0.16.4",
|
||||
"@hono/zod-validator": "0.4.1",
|
||||
"@jellybrick/electron-better-web-request": "1.0.4",
|
||||
"@jellybrick/mpris-service": "2.1.4",
|
||||
"@xhayper/discord-rpc": "1.1.2",
|
||||
"@jimp/plugin-invert": "0.22.12",
|
||||
"@skyra/jaro-winkler": "1.1.1",
|
||||
"@xhayper/discord-rpc": "1.2.0",
|
||||
"async-mutex": "0.5.0",
|
||||
"butterchurn": "3.0.0-beta.4",
|
||||
"butterchurn-presets": "3.0.0-beta.4",
|
||||
"color": "4.2.3",
|
||||
"conf": "10.2.0",
|
||||
"custom-electron-prompt": "1.5.7",
|
||||
"conf": "13.0.1",
|
||||
"custom-electron-prompt": "1.5.8",
|
||||
"dbus-next": "0.10.2",
|
||||
"deepmerge-ts": "5.1.0",
|
||||
"electron-debug": "3.2.0",
|
||||
"deepmerge-ts": "7.1.3",
|
||||
"electron-debug": "4.1.0",
|
||||
"electron-is": "3.0.0",
|
||||
"electron-localshortcut": "3.2.1",
|
||||
"electron-store": "8.2.0",
|
||||
"electron-store": "10.0.0",
|
||||
"electron-unhandled": "4.0.1",
|
||||
"electron-updater": "6.1.8",
|
||||
"electron-updater": "6.3.9",
|
||||
"fast-average-color": "9.4.0",
|
||||
"fast-equals": "5.0.1",
|
||||
"filenamify": "6.0.0",
|
||||
"hono": "4.6.5",
|
||||
"howler": "2.2.4",
|
||||
"html-to-text": "9.0.5",
|
||||
"i18next": "23.10.1",
|
||||
"i18next": "23.16.0",
|
||||
"jimp": "1.6.0",
|
||||
"keyboardevent-from-electron-accelerator": "2.0.0",
|
||||
"keyboardevents-areequal": "0.2.2",
|
||||
"node-html-parser": "6.1.12",
|
||||
"node-html-parser": "6.1.13",
|
||||
"node-id3": "0.2.6",
|
||||
"peerjs": "1.5.2",
|
||||
"semver": "7.6.0",
|
||||
"serve": "14.2.1",
|
||||
"peerjs": "1.5.4",
|
||||
"semver": "7.6.3",
|
||||
"serve": "14.2.4",
|
||||
"simple-youtube-age-restriction-bypass": "github:organization/Simple-YouTube-Age-Restriction-Bypass#v2.5.9",
|
||||
"solid-floating-ui": "0.3.1",
|
||||
"solid-js": "1.8.16",
|
||||
"solid-js": "1.9.2",
|
||||
"solid-styled-components": "0.28.5",
|
||||
"solid-transition-group": "0.2.3",
|
||||
"ts-morph": "22.0.0",
|
||||
"ts-morph": "24.0.0",
|
||||
"vudio": "2.1.1",
|
||||
"x11": "2.3.0",
|
||||
"youtubei.js": "9.1.0"
|
||||
"youtubei.js": "10.5.0",
|
||||
"zod": "3.23.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@playwright/test": "1.42.1",
|
||||
"@total-typescript/ts-reset": "0.5.1",
|
||||
"@eslint/js": "9.12.0",
|
||||
"@playwright/test": "1.48.0",
|
||||
"@stylistic/eslint-plugin-js": "2.9.0",
|
||||
"@total-typescript/ts-reset": "0.6.1",
|
||||
"@types/color": "3.0.6",
|
||||
"@types/electron-localshortcut": "3.1.3",
|
||||
"@types/howler": "2.2.11",
|
||||
"@types/eslint__js": "8.42.3",
|
||||
"@types/howler": "2.2.12",
|
||||
"@types/html-to-text": "9.0.4",
|
||||
"@types/semver": "7.5.8",
|
||||
"@typescript-eslint/eslint-plugin": "7.4.0",
|
||||
"@types/trusted-types": "2.0.7",
|
||||
"bufferutil": "4.0.8",
|
||||
"builtin-modules": "3.3.0",
|
||||
"builtin-modules": "4.0.0",
|
||||
"cross-env": "7.0.3",
|
||||
"del-cli": "5.1.0",
|
||||
"discord-api-types": "0.37.76",
|
||||
"electron": "29.1.6",
|
||||
"electron-builder": "24.9.1",
|
||||
"del-cli": "6.0.0",
|
||||
"discord-api-types": "0.37.102",
|
||||
"electron": "33.0.0",
|
||||
"electron-builder": "24.13.3",
|
||||
"electron-devtools-installer": "3.2.0",
|
||||
"electron-vite": "2.1.0",
|
||||
"esbuild": "0.20.2",
|
||||
"eslint": "8.57.0",
|
||||
"electron-vite": "2.3.0",
|
||||
"esbuild": "0.24.0",
|
||||
"eslint": "9.12.0",
|
||||
"eslint-config-prettier": "9.1.0",
|
||||
"eslint-import-resolver-exports": "1.0.0-beta.5",
|
||||
"eslint-import-resolver-typescript": "3.6.1",
|
||||
"eslint-plugin-import": "2.29.1",
|
||||
"eslint-plugin-prettier": "5.1.3",
|
||||
"glob": "10.3.10",
|
||||
"node-gyp": "10.1.0",
|
||||
"playwright": "1.42.1",
|
||||
"rollup": "4.13.1",
|
||||
"typescript": "5.4.3",
|
||||
"utf-8-validate": "6.0.3",
|
||||
"vite": "5.2.6",
|
||||
"vite-plugin-inspect": "0.8.3",
|
||||
"vite-plugin-resolve": "2.5.1",
|
||||
"eslint-import-resolver-typescript": "3.6.3",
|
||||
"eslint-plugin-import": "2.31.0",
|
||||
"eslint-plugin-prettier": "5.2.1",
|
||||
"glob": "11.0.0",
|
||||
"node-gyp": "10.2.0",
|
||||
"playwright": "1.48.0",
|
||||
"rollup": "4.24.0",
|
||||
"typescript": "5.6.3",
|
||||
"typescript-eslint": "8.9.0",
|
||||
"utf-8-validate": "6.0.4",
|
||||
"vite": "5.4.9",
|
||||
"vite-plugin-inspect": "0.8.7",
|
||||
"vite-plugin-resolve": "2.5.2",
|
||||
"vite-plugin-solid": "2.10.2",
|
||||
"ws": "8.16.0"
|
||||
"ws": "8.18.0"
|
||||
},
|
||||
"auto-changelog": {
|
||||
"hideCredit": true,
|
||||
"package": true,
|
||||
"unreleased": true,
|
||||
"output": "changelog.md"
|
||||
},
|
||||
"packageManager": "pnpm@8.15.5"
|
||||
}
|
||||
}
|
||||
|
||||
29
patches/@malept__flatpak-bundler.patch
Normal file
29
patches/@malept__flatpak-bundler.patch
Normal file
@ -0,0 +1,29 @@
|
||||
diff --git a/index.js b/index.js
|
||||
index 5968fcf47b69094993b0f861c03f5560e4a6a9b7..0fe16d4f40612c0abfa57898909ce0083f56944c 100644
|
||||
--- a/index.js
|
||||
+++ b/index.js
|
||||
@@ -56,19 +56,23 @@ function getOptionsWithDefaults (options, manifest) {
|
||||
async function spawnWithLogging (options, command, args, allowFail) {
|
||||
return new Promise((resolve, reject) => {
|
||||
logger(`$ ${command} ${args.join(' ')}`)
|
||||
+ const output = []
|
||||
const child = childProcess.spawn(command, args, { cwd: options['working-dir'] })
|
||||
child.stdout.on('data', (data) => {
|
||||
+ output.push(data)
|
||||
logger(`1> ${data}`)
|
||||
})
|
||||
child.stderr.on('data', (data) => {
|
||||
+ output.push(data)
|
||||
logger(`2> ${data}`)
|
||||
})
|
||||
child.on('error', (error) => {
|
||||
+ logger(`error - ${error.message} ${error.stack}`)
|
||||
reject(error)
|
||||
})
|
||||
child.on('close', (code) => {
|
||||
if (!allowFail && code !== 0) {
|
||||
- reject(new Error(`${command} failed with status code ${code}`))
|
||||
+ reject(new Error(`${command} ${args.join(' ')} failed with status code ${code} ${output.join(' ')}`))
|
||||
}
|
||||
resolve(code === 0)
|
||||
})
|
||||
@ -1,17 +0,0 @@
|
||||
diff --git a/package.json b/package.json
|
||||
index 40db5dfbd8a4455ce2987d8115eca9882e1f9f14..414fc6986b9c0cc288908eb0107b90c4bfd916b2 100644
|
||||
--- a/package.json
|
||||
+++ b/package.json
|
||||
@@ -25,11 +25,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "^1.6.2",
|
||||
- "ws": "^8.15.1"
|
||||
- },
|
||||
- "optionalDependencies": {
|
||||
- "bufferutil": "^4.0.8",
|
||||
- "utf-8-validate": "^6.0.3"
|
||||
+ "ws": "^8.16.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^14.*",
|
||||
21
patches/app-builder-lib@24.13.3.patch
Normal file
21
patches/app-builder-lib@24.13.3.patch
Normal file
@ -0,0 +1,21 @@
|
||||
diff --git a/out/targets/snap.js b/out/targets/snap.js
|
||||
index f72c36355d27cd2d69fc5fdf2d8bb2451db0287f..baae112fe25ebb49ab8e25aaa48efd6bc43b598f 100644
|
||||
--- a/out/targets/snap.js
|
||||
+++ b/out/targets/snap.js
|
||||
@@ -212,14 +212,14 @@ class SnapTarget extends core_1.Target {
|
||||
args.push("--template-url", `electron4:${snapArch}`);
|
||||
}
|
||||
await (0, builder_util_1.executeAppBuilder)(args);
|
||||
- const publishConfig = findSnapPublishConfig(this.packager.config);
|
||||
+
|
||||
await packager.info.callArtifactBuildCompleted({
|
||||
file: artifactPath,
|
||||
safeArtifactName: packager.computeSafeArtifactName(artifactName, "snap", arch, false),
|
||||
target: this,
|
||||
arch,
|
||||
packager,
|
||||
- publishConfig: publishConfig == null ? { provider: "snapStore" } : publishConfig,
|
||||
+ publishConfig: options.publish == null ? { provider: "snapStore" } : null,
|
||||
});
|
||||
}
|
||||
isElectronVersionGreaterOrEqualThan(version) {
|
||||
161
patches/eslint-plugin-import@2.29.1.patch
Normal file
161
patches/eslint-plugin-import@2.29.1.patch
Normal file
@ -0,0 +1,161 @@
|
||||
diff --git a/lib/importDeclaration.js b/lib/importDeclaration.js
|
||||
index afb4de779034cfea080825a5f4320661c48bee32..f10b0a11a39577fbd42569e6b0e768255c1ef276 100644
|
||||
--- a/lib/importDeclaration.js
|
||||
+++ b/lib/importDeclaration.js
|
||||
@@ -1,5 +1,5 @@
|
||||
-"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports["default"] = importDeclaration;function importDeclaration(context) {
|
||||
- var ancestors = context.getAncestors();
|
||||
+"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports["default"] = importDeclaration;function importDeclaration(context, node) {
|
||||
+ var ancestors = context.getSourceCode().getAncestors(node);
|
||||
return ancestors[ancestors.length - 1];
|
||||
}
|
||||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9pbXBvcnREZWNsYXJhdGlvbi5qcyJdLCJuYW1lcyI6WyJpbXBvcnREZWNsYXJhdGlvbiIsImNvbnRleHQiLCJhbmNlc3RvcnMiLCJnZXRBbmNlc3RvcnMiLCJsZW5ndGgiXSwibWFwcGluZ3MiOiJnR0FBd0JBLGlCLENBQVQsU0FBU0EsaUJBQVQsQ0FBMkJDLE9BQTNCLEVBQW9DO0FBQ2pELE1BQU1DLFlBQVlELFFBQVFFLFlBQVIsRUFBbEI7QUFDQSxTQUFPRCxVQUFVQSxVQUFVRSxNQUFWLEdBQW1CLENBQTdCLENBQVA7QUFDRCIsImZpbGUiOiJpbXBvcnREZWNsYXJhdGlvbi5qcyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGltcG9ydERlY2xhcmF0aW9uKGNvbnRleHQpIHtcbiAgY29uc3QgYW5jZXN0b3JzID0gY29udGV4dC5nZXRBbmNlc3RvcnMoKTtcbiAgcmV0dXJuIGFuY2VzdG9yc1thbmNlc3RvcnMubGVuZ3RoIC0gMV07XG59XG4iXX0=
|
||||
\ No newline at end of file
|
||||
diff --git a/lib/rules/first.js b/lib/rules/first.js
|
||||
index a77168660cf32c8c3e96f3ff4b8240a36d7de3a6..c0e00d75f9989916057fef3999eeee8d21820292 100644
|
||||
--- a/lib/rules/first.js
|
||||
+++ b/lib/rules/first.js
|
||||
@@ -66,7 +66,7 @@ module.exports = {
|
||||
}
|
||||
}
|
||||
if (nonImportCount > 0) {var _iteratorNormalCompletion = true;var _didIteratorError = false;var _iteratorError = undefined;try {
|
||||
- for (var _iterator = context.getDeclaredVariables(node)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {var variable = _step.value;
|
||||
+ for (var _iterator = sourceCode.getDeclaredVariables(node)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {var variable = _step.value;
|
||||
if (!shouldSort) {break;}
|
||||
var references = variable.references;
|
||||
if (references.length) {var _iteratorNormalCompletion2 = true;var _didIteratorError2 = false;var _iteratorError2 = undefined;try {
|
||||
diff --git a/lib/rules/namespace.js b/lib/rules/namespace.js
|
||||
index 574d89a60d15c7e0e712956ea6a3ad2d0eac7f08..82e7cb3cff4246592d762cce86323f2b72de92e4 100644
|
||||
--- a/lib/rules/namespace.js
|
||||
+++ b/lib/rules/namespace.js
|
||||
@@ -86,7 +86,7 @@ module.exports = {
|
||||
|
||||
// same as above, but does not add names to local map
|
||||
ExportNamespaceSpecifier: function () {function ExportNamespaceSpecifier(namespace) {
|
||||
- var declaration = (0, _importDeclaration2['default'])(context);
|
||||
+ var declaration = (0, _importDeclaration2['default'])(context, namespace);
|
||||
|
||||
var imports = _ExportMap2['default'].get(declaration.source.value, context);
|
||||
if (imports == null) {return null;}
|
||||
diff --git a/lib/rules/newline-after-import.js b/lib/rules/newline-after-import.js
|
||||
index 6cc15686464a17803a0b976c35b99627cdbfabee..520eec6d9a375527ab72c459960fe4416c046c17 100644
|
||||
--- a/lib/rules/newline-after-import.js
|
||||
+++ b/lib/rules/newline-after-import.js
|
||||
@@ -194,7 +194,7 @@ module.exports = {
|
||||
}return CallExpression;}(),
|
||||
'Program:exit': function () {function ProgramExit() {
|
||||
log('exit processing for', context.getPhysicalFilename ? context.getPhysicalFilename() : context.getFilename());
|
||||
- var scopeBody = getScopeBody(context.getScope());
|
||||
+ var scopeBody = getScopeBody(context.getSourceCode().getScope(node));
|
||||
log('got scope:', scopeBody);
|
||||
|
||||
requireCalls.forEach(function (node, index) {
|
||||
diff --git a/lib/rules/no-amd.js b/lib/rules/no-amd.js
|
||||
index 7ac108bf812ca4f78bfa6fe5ae8b9cf38e2ff497..346c3105dc70f72c4d76fcc6b96b946d1d4ec6d5 100644
|
||||
--- a/lib/rules/no-amd.js
|
||||
+++ b/lib/rules/no-amd.js
|
||||
@@ -23,7 +23,7 @@ module.exports = {
|
||||
create: function () {function create(context) {
|
||||
return {
|
||||
CallExpression: function () {function CallExpression(node) {
|
||||
- if (context.getScope().type !== 'module') {return;}
|
||||
+ if (context.getSourceCode().getScope(node).type !== 'module') {return;}
|
||||
|
||||
if (node.callee.type !== 'Identifier') {return;}
|
||||
if (node.callee.name !== 'require' && node.callee.name !== 'define') {return;}
|
||||
diff --git a/lib/rules/no-commonjs.js b/lib/rules/no-commonjs.js
|
||||
index befeff0026d61d3ac1e6bbcea29f5c471dc1d353..e91c5ed34e968d5867e884ea800e166cda345aef 100644
|
||||
--- a/lib/rules/no-commonjs.js
|
||||
+++ b/lib/rules/no-commonjs.js
|
||||
@@ -107,7 +107,7 @@ module.exports = {
|
||||
|
||||
// exports.
|
||||
if (node.object.name === 'exports') {
|
||||
- var isInScope = context.getScope().
|
||||
+ var isInScope = context.getSourceCode().getScope(node).
|
||||
variables.
|
||||
some(function (variable) {return variable.name === 'exports';});
|
||||
if (!isInScope) {
|
||||
@@ -117,7 +117,7 @@ module.exports = {
|
||||
|
||||
}return MemberExpression;}(),
|
||||
CallExpression: function () {function CallExpression(call) {
|
||||
- if (!validateScope(context.getScope())) {return;}
|
||||
+ if (!validateScope(context.getSourceCode().getScope(call))) {return;}
|
||||
|
||||
if (call.callee.type !== 'Identifier') {return;}
|
||||
if (call.callee.name !== 'require') {return;}
|
||||
diff --git a/lib/rules/no-mutable-exports.js b/lib/rules/no-mutable-exports.js
|
||||
index 40bd1b4cfa95d41732bb13bba0ed1969a91cc7ff..8a25abfbfadb299204b36a6cbf283259bcc2e790 100644
|
||||
--- a/lib/rules/no-mutable-exports.js
|
||||
+++ b/lib/rules/no-mutable-exports.js
|
||||
@@ -32,7 +32,7 @@ module.exports = {
|
||||
}
|
||||
|
||||
function handleExportDefault(node) {
|
||||
- var scope = context.getScope();
|
||||
+ var scope = context.getSourceCode().getScope(node);
|
||||
|
||||
if (node.declaration.name) {
|
||||
checkDeclarationsInScope(scope, node.declaration.name);
|
||||
@@ -40,7 +40,7 @@ module.exports = {
|
||||
}
|
||||
|
||||
function handleExportNamed(node) {
|
||||
- var scope = context.getScope();
|
||||
+ var scope = context.getSourceCode().getScope(node);
|
||||
|
||||
if (node.declaration) {
|
||||
checkDeclaration(node.declaration);
|
||||
diff --git a/lib/rules/no-named-as-default-member.js b/lib/rules/no-named-as-default-member.js
|
||||
index 0c15051e027ad7d1d45f1b51c20be1c000b0af01..5b3d6ba415511b7f9f83a52e1acfebe5a1045a7b 100644
|
||||
--- a/lib/rules/no-named-as-default-member.js
|
||||
+++ b/lib/rules/no-named-as-default-member.js
|
||||
@@ -35,7 +35,7 @@ module.exports = {
|
||||
|
||||
return {
|
||||
ImportDefaultSpecifier: function () {function ImportDefaultSpecifier(node) {
|
||||
- var declaration = (0, _importDeclaration2['default'])(context);
|
||||
+ var declaration = (0, _importDeclaration2['default'])(context, node);
|
||||
var exportMap = _ExportMap2['default'].get(declaration.source.value, context);
|
||||
if (exportMap == null) {return;}
|
||||
|
||||
diff --git a/lib/rules/no-named-as-default.js b/lib/rules/no-named-as-default.js
|
||||
index 63378a33a1c7da004c57a524cec1a1cddf23e210..c81b1f93b11628676158b79f1c4015911943cc7d 100644
|
||||
--- a/lib/rules/no-named-as-default.js
|
||||
+++ b/lib/rules/no-named-as-default.js
|
||||
@@ -18,7 +18,7 @@ module.exports = {
|
||||
// #566: default is a valid specifier
|
||||
if (defaultSpecifier[nameKey].name === 'default') {return;}
|
||||
|
||||
- var declaration = (0, _importDeclaration2['default'])(context);
|
||||
+ var declaration = (0, _importDeclaration2['default'])(context, defaultSpecifier);
|
||||
|
||||
var imports = _ExportMap2['default'].get(declaration.source.value, context);
|
||||
if (imports == null) {return;}
|
||||
diff --git a/lib/rules/no-namespace.js b/lib/rules/no-namespace.js
|
||||
index 2b0c783adea788101b779b17f977bbcb582cfd3f..a7f7b202ac7c4a342febef2a993586c4cc84fc7a 100644
|
||||
--- a/lib/rules/no-namespace.js
|
||||
+++ b/lib/rules/no-namespace.js
|
||||
@@ -43,7 +43,7 @@ var _docsUrl = require('../docsUrl');var _docsUrl2 = _interopRequireDefault(_doc
|
||||
return;
|
||||
}
|
||||
|
||||
- var scopeVariables = context.getScope().variables;
|
||||
+ var scopeVariables = context.getSourceCode().getScope(node).variables;
|
||||
var namespaceVariable = scopeVariables.find(function (variable) {return variable.defs[0].node === node;});
|
||||
var namespaceReferences = namespaceVariable.references;
|
||||
var namespaceIdentifiers = namespaceReferences.map(function (reference) {return reference.identifier;});
|
||||
diff --git a/package.json b/package.json
|
||||
index 5c0af48543483a21791fa23a4a583071d3551772..5deeac3d0accc3878ef0fc93dfb52a8ca7c46e84 100644
|
||||
--- a/package.json
|
||||
+++ b/package.json
|
||||
@@ -72,7 +72,7 @@
|
||||
"chai": "^4.3.10",
|
||||
"cross-env": "^4.0.0",
|
||||
"escope": "^3.6.0",
|
||||
- "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8",
|
||||
+ "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9",
|
||||
"eslint-doc-generator": "^1.6.1",
|
||||
"eslint-import-resolver-node": "file:./resolvers/node",
|
||||
"eslint-import-resolver-typescript": "^1.0.2 || ^1.1.1",
|
||||
11263
pnpm-lock.yaml
generated
11263
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@ -1,9 +1,8 @@
|
||||
import Store from 'electron-store';
|
||||
import { deepmergeCustom } from 'deepmerge-ts';
|
||||
|
||||
import defaultConfig from './defaults';
|
||||
|
||||
import store from './store';
|
||||
import store, { IStore } from './store';
|
||||
import plugins from './plugins';
|
||||
|
||||
import { restart } from '@/providers/app-controls';
|
||||
@ -62,20 +61,19 @@ type Join<K, P> = K extends string | number
|
||||
type Paths<T, D extends number = 10> = [D] extends [never]
|
||||
? never
|
||||
: T extends object
|
||||
? {
|
||||
[K in keyof T]-?: K extends string | number
|
||||
? `${K}` | Join<K, Paths<T[K], Prev[D]>>
|
||||
: never;
|
||||
}[keyof T]
|
||||
: '';
|
||||
? {
|
||||
[K in keyof T]-?: K extends string | number
|
||||
? `${K}` | Join<K, Paths<T[K], Prev[D]>>
|
||||
: never;
|
||||
}[keyof T]
|
||||
: '';
|
||||
|
||||
type SplitKey<K> = K extends `${infer A}.${infer B}` ? [A, B] : [K, string];
|
||||
type PathValue<T, K extends string> = SplitKey<K> extends [
|
||||
infer A extends keyof T,
|
||||
infer B extends string,
|
||||
]
|
||||
? PathValue<T[A], B>
|
||||
: T;
|
||||
type PathValue<T, K extends string> =
|
||||
SplitKey<K> extends [infer A extends keyof T, infer B extends string]
|
||||
? PathValue<T[A], B>
|
||||
: T;
|
||||
|
||||
const get = <Key extends Paths<typeof defaultConfig>>(key: Key) =>
|
||||
store.get(key) as PathValue<typeof defaultConfig, typeof key>;
|
||||
|
||||
@ -86,7 +84,7 @@ export default {
|
||||
setPartial,
|
||||
setMenuOption,
|
||||
edit: () => store.openInEditor(),
|
||||
watch(cb: Parameters<Store['onDidAnyChange']>[0]) {
|
||||
watch(cb: Parameters<IStore['onDidAnyChange']>[0]) {
|
||||
store.onDidAnyChange(cb);
|
||||
},
|
||||
plugins,
|
||||
|
||||
@ -1,12 +1,14 @@
|
||||
import Store from 'electron-store';
|
||||
import Conf from 'conf';
|
||||
|
||||
import defaults from './defaults';
|
||||
|
||||
import { DefaultPresetList, type Preset } from '@/plugins/downloader/types';
|
||||
|
||||
// prettier-ignore
|
||||
export type IStore = InstanceType<typeof import('conf/dist/source/index').default<Record<string, unknown>>>;
|
||||
|
||||
const migrations = {
|
||||
'>=3.3.0'(store: Conf<Record<string, unknown>>) {
|
||||
'>=3.3.0'(store: IStore) {
|
||||
const lastfmConfig = store.get('plugins.lastfm') as {
|
||||
enabled?: boolean;
|
||||
token?: string;
|
||||
@ -16,21 +18,21 @@ const migrations = {
|
||||
secret?: string;
|
||||
};
|
||||
if (lastfmConfig) {
|
||||
let scrobblerConfig = store.get(
|
||||
'plugins.scrobbler',
|
||||
) as {
|
||||
enabled?: boolean;
|
||||
scrobblers?: {
|
||||
lastfm?: {
|
||||
let scrobblerConfig = store.get('plugins.scrobbler') as
|
||||
| {
|
||||
enabled?: boolean;
|
||||
token?: string;
|
||||
sessionKey?: string;
|
||||
apiRoot?: string;
|
||||
apiKey?: string;
|
||||
secret?: string;
|
||||
};
|
||||
};
|
||||
} | undefined;
|
||||
scrobblers?: {
|
||||
lastfm?: {
|
||||
enabled?: boolean;
|
||||
token?: string;
|
||||
sessionKey?: string;
|
||||
apiRoot?: string;
|
||||
apiKey?: string;
|
||||
secret?: string;
|
||||
};
|
||||
};
|
||||
}
|
||||
| undefined;
|
||||
|
||||
if (!scrobblerConfig) {
|
||||
scrobblerConfig = {
|
||||
@ -56,7 +58,7 @@ const migrations = {
|
||||
store.delete('plugins.lastfm');
|
||||
}
|
||||
},
|
||||
'>=3.0.0'(store: Conf<Record<string, unknown>>) {
|
||||
'>=3.0.0'(store: IStore) {
|
||||
const discordConfig = store.get('plugins.discord') as Record<
|
||||
string,
|
||||
unknown
|
||||
@ -78,14 +80,14 @@ const migrations = {
|
||||
}
|
||||
}
|
||||
},
|
||||
'>=2.1.3'(store: Conf<Record<string, unknown>>) {
|
||||
'>=2.1.3'(store: IStore) {
|
||||
const listenAlong = store.get('plugins.discord.listenAlong');
|
||||
if (listenAlong !== undefined) {
|
||||
store.set('plugins.discord.playOnYouTubeMusic', listenAlong);
|
||||
store.delete('plugins.discord.listenAlong');
|
||||
}
|
||||
},
|
||||
'>=2.1.0'(store: Conf<Record<string, unknown>>) {
|
||||
'>=2.1.0'(store: IStore) {
|
||||
const originalPreset = store.get('plugins.downloader.preset') as
|
||||
| string
|
||||
| undefined;
|
||||
@ -110,7 +112,7 @@ const migrations = {
|
||||
store.delete('plugins.downloader.ffmpegArgs');
|
||||
}
|
||||
},
|
||||
'>=1.20.0'(store: Conf<Record<string, unknown>>) {
|
||||
'>=1.20.0'(store: IStore) {
|
||||
store.delete('plugins.visualizer'); // default value is now in the plugin
|
||||
|
||||
if (store.get('plugins.notifications.toastStyle') === undefined) {
|
||||
@ -125,14 +127,14 @@ const migrations = {
|
||||
store.set('options.likeButtons', 'force');
|
||||
}
|
||||
},
|
||||
'>=1.17.0'(store: Conf<Record<string, unknown>>) {
|
||||
'>=1.17.0'(store: IStore) {
|
||||
store.delete('plugins.picture-in-picture'); // default value is now in the plugin
|
||||
|
||||
if (store.get('plugins.video-toggle.mode') === undefined) {
|
||||
store.set('plugins.video-toggle.mode', 'custom');
|
||||
}
|
||||
},
|
||||
'>=1.14.0'(store: Conf<Record<string, unknown>>) {
|
||||
'>=1.14.0'(store: IStore) {
|
||||
if (
|
||||
typeof store.get('plugins.precise-volume.globalShortcuts') !== 'object'
|
||||
) {
|
||||
@ -144,12 +146,12 @@ const migrations = {
|
||||
store.set('plugins.video-toggle.enabled', true);
|
||||
}
|
||||
},
|
||||
'>=1.13.0'(store: Conf<Record<string, unknown>>) {
|
||||
'>=1.13.0'(store: IStore) {
|
||||
if (store.get('plugins.discord.listenAlong') === undefined) {
|
||||
store.set('plugins.discord.listenAlong', true);
|
||||
}
|
||||
},
|
||||
'>=1.12.0'(store: Conf<Record<string, unknown>>) {
|
||||
'>=1.12.0'(store: IStore) {
|
||||
const options = store.get('plugins.shortcuts') as
|
||||
| Record<
|
||||
string,
|
||||
@ -187,12 +189,12 @@ const migrations = {
|
||||
}
|
||||
}
|
||||
},
|
||||
'>=1.11.0'(store: Conf<Record<string, unknown>>) {
|
||||
'>=1.11.0'(store: IStore) {
|
||||
if (store.get('options.resumeOnStart') === undefined) {
|
||||
store.set('options.resumeOnStart', true);
|
||||
}
|
||||
},
|
||||
'>=1.7.0'(store: Conf<Record<string, unknown>>) {
|
||||
'>=1.7.0'(store: IStore) {
|
||||
const enabledPlugins = store.get('plugins') as string[];
|
||||
if (!Array.isArray(enabledPlugins)) {
|
||||
console.warn('Plugins are not in array format, cannot migrate');
|
||||
@ -233,4 +235,4 @@ export default new Store({
|
||||
},
|
||||
clearInvalidConfig: false,
|
||||
migrations,
|
||||
});
|
||||
}) as Store & IStore;
|
||||
|
||||
38
src/custom-electron-prompt.d.ts
vendored
38
src/custom-electron-prompt.d.ts
vendored
@ -64,29 +64,29 @@ declare module 'custom-electron-prompt' {
|
||||
export type PromptOptions<T extends string> = T extends 'input'
|
||||
? InputPromptOptions
|
||||
: T extends 'select'
|
||||
? SelectPromptOptions
|
||||
: T extends 'counter'
|
||||
? CounterPromptOptions
|
||||
: T extends 'keybind'
|
||||
? KeybindPromptOptions
|
||||
: T extends 'multiInput'
|
||||
? MultiInputPromptOptions
|
||||
: never;
|
||||
? SelectPromptOptions
|
||||
: T extends 'counter'
|
||||
? CounterPromptOptions
|
||||
: T extends 'keybind'
|
||||
? KeybindPromptOptions
|
||||
: T extends 'multiInput'
|
||||
? MultiInputPromptOptions
|
||||
: never;
|
||||
|
||||
type PromptResult<T extends string> = T extends 'input'
|
||||
? string
|
||||
: T extends 'select'
|
||||
? string
|
||||
: T extends 'counter'
|
||||
? number
|
||||
: T extends 'keybind'
|
||||
? {
|
||||
value: string;
|
||||
accelerator: string;
|
||||
}[]
|
||||
: T extends 'multiInput'
|
||||
? string[]
|
||||
: never;
|
||||
? string
|
||||
: T extends 'counter'
|
||||
? number
|
||||
: T extends 'keybind'
|
||||
? {
|
||||
value: string;
|
||||
accelerator: string;
|
||||
}[]
|
||||
: T extends 'multiInput'
|
||||
? string[]
|
||||
: never;
|
||||
|
||||
const prompt: <T extends Type>(
|
||||
options?: PromptOptions<T> & { type: T },
|
||||
|
||||
214
src/i18n/resources/ar.json
Normal file
214
src/i18n/resources/ar.json
Normal file
@ -0,0 +1,214 @@
|
||||
{
|
||||
"common": {
|
||||
"console": {
|
||||
"plugins": {
|
||||
"execute-failed": "فشل تشغيل الاضافة {{pluginName}}::{{contextName}}",
|
||||
"executed-at-ms": "تم تشغيل الاضافة {{pluginName}}::{{contextName}} خلال {{ms}} جزء من الثانية",
|
||||
"initialize-failed": "فشل تنفيذ الاضافة \"{{pluginName}}\"",
|
||||
"load-all": "جاري تحميل جميع الاضافات",
|
||||
"load-failed": "فشل في تحميل الاضافة \"{{pluginName}}\"",
|
||||
"loaded": "تم تحميل الاضافة \"{{pluginName}}\"",
|
||||
"unload-failed": "فشل ازالة الاضافة \"{{pluginName}}\"",
|
||||
"unloaded": "تم ازالة الاضافة \"{{pluginName}}\""
|
||||
}
|
||||
}
|
||||
},
|
||||
"language": {
|
||||
"code": "ar",
|
||||
"local-name": "العربية",
|
||||
"name": "Arabic"
|
||||
},
|
||||
"main": {
|
||||
"console": {
|
||||
"did-finish-load": {
|
||||
"dev-tools": "انتهى التحميل, تم فتح قائمة المطور"
|
||||
},
|
||||
"i18n": {
|
||||
"loaded": "تم تحميل i18n"
|
||||
},
|
||||
"second-instance": {
|
||||
"receive-command": "تم الحصول على أمر عن طريق: \"{{command}}\""
|
||||
},
|
||||
"theme": {
|
||||
"css-file-not-found": "ملف \"{{cssFile}}\" غير متواجد,سيتم التجاهل"
|
||||
},
|
||||
"unresponsive": {
|
||||
"details": "خطء عدم استجابة!\n{{error}}"
|
||||
},
|
||||
"when-ready": {
|
||||
"clearing-cache-after-20s": "ازالة بيانات التطبيق المخزنة"
|
||||
},
|
||||
"window": {
|
||||
"tried-to-render-offscreen": "تم محاولة فتح الصفحة خارج الشاشة, حجم الصفحة={{windowSize}}, حجم الشاشة={{displaySize}}, مكان={{position}}"
|
||||
}
|
||||
},
|
||||
"dialog": {
|
||||
"hide-menu-enabled": {
|
||||
"detail": "تم اخفاء القائمة, استخدم 'Alt' لاظهار القائمة (أو 'Escape' اذا كنت تستخدم القائمة داخل التطبيق)",
|
||||
"message": "اخفاء القائمة مفعل",
|
||||
"title": "تم تفعيل اخفاء القائمة"
|
||||
},
|
||||
"need-to-restart": {
|
||||
"buttons": {
|
||||
"later": "لاحقاً",
|
||||
"restart-now": "اعادة التشغيل الأن"
|
||||
},
|
||||
"detail": "\"{{pluginName}}\" هذه الاضافة تتطلب اعادة التشغيل ليتم تفعيلها",
|
||||
"message": "\"{{pluginName}}\" بحاجة الى اعادة التشغيل",
|
||||
"title": "مطلوب اعادة التشغيل"
|
||||
},
|
||||
"unresponsive": {
|
||||
"buttons": {
|
||||
"quit": "خروج",
|
||||
"relaunch": "اعادة التشغيل",
|
||||
"wait": "انتظار"
|
||||
},
|
||||
"detail": "نأسف على الإزعاج! يرجى اختيار ما يجب القيام به:",
|
||||
"message": "التطبيق لا يستجيب",
|
||||
"title": "الصفحة لا تستجيب"
|
||||
},
|
||||
"update-available": {
|
||||
"buttons": {
|
||||
"disable": "ايقاف التحديثات",
|
||||
"download": "تحميل",
|
||||
"ok": "موافق"
|
||||
},
|
||||
"detail": "يوجد نسخة جديدة يمكن تحميلها من خلال {{downloadLink}}",
|
||||
"message": "يوجد نسخة حديثة",
|
||||
"title": "يوجد تحديث"
|
||||
}
|
||||
},
|
||||
"menu": {
|
||||
"about": "عنا",
|
||||
"navigation": {
|
||||
"label": "التنقل",
|
||||
"submenu": {
|
||||
"copy-current-url": "نسخ الرابط الحالي",
|
||||
"go-back": "العودة للخلف",
|
||||
"go-forward": "التقدم",
|
||||
"quit": "الخروج",
|
||||
"restart": "اعادة تشغيل التطبيق"
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"label": "الاعدادات",
|
||||
"submenu": {
|
||||
"advanced-options": {
|
||||
"label": "الاعدادات المتقدمة",
|
||||
"submenu": {
|
||||
"auto-reset-app-cache": "إعادة تعيين ذاكرة التخزين المؤقت للتطبيق عند بدء التشغيل",
|
||||
"disable-hardware-acceleration": "تعطيل تسريع الأجهزة",
|
||||
"edit-config-json": "تعديل ملف الاعدادات",
|
||||
"override-user-agent": "تجاوز وكيل المستخدم",
|
||||
"restart-on-config-changes": "اعادة التشغيل بعد تعديل الاعدادات",
|
||||
"set-proxy": {
|
||||
"label": "تعيين الوكيل",
|
||||
"prompt": {
|
||||
"label": "أدخل عنوان الوكيل: (اتركه فارغًا للتعطيل)",
|
||||
"placeholder": "مثال: SOCKS5://127.0.0.1:9999",
|
||||
"title": "اضافة الوكيل"
|
||||
}
|
||||
},
|
||||
"toggle-dev-tools": "تثبيت أدوات التطوير"
|
||||
}
|
||||
},
|
||||
"always-on-top": "دائما في القمة",
|
||||
"auto-update": "تحديث تلقائي",
|
||||
"hide-menu": {
|
||||
"dialog": {
|
||||
"message": "سيتم إخفاء القائمة عند التشغيل التالي، استخدم [Alt] لإظهارها (أو ضع علامة اختيار على [`] في حالة استخدام القائمة داخل التطبيق)",
|
||||
"title": "إخفاء القائمة ممكن"
|
||||
},
|
||||
"label": "إخفاء القائمة"
|
||||
},
|
||||
"language": {
|
||||
"dialog": {
|
||||
"message": "سيتم تغيير اللغة بعد اعادة التشغيل",
|
||||
"title": "تم تغير اللغة"
|
||||
},
|
||||
"label": "اللغة",
|
||||
"submenu": {
|
||||
"to-help-translate": "تريد المساعدة في الترجمة؟ اضغط هنا"
|
||||
}
|
||||
},
|
||||
"resume-on-start": "تكملة الأغنية الأخيرة عند بدأ التشغيل",
|
||||
"single-instance-lock": "قفل مثيل واحد",
|
||||
"start-at-login": "ابدأ عند تسجيل الدخول",
|
||||
"starting-page": {
|
||||
"label": "صفحة البداية",
|
||||
"unset": "الغاء"
|
||||
},
|
||||
"tray": {
|
||||
"label": "قائمة",
|
||||
"submenu": {
|
||||
"disabled": "غير مفعل",
|
||||
"enabled-and-hide-app": "تمكين وإخفاء التطبيق",
|
||||
"enabled-and-show-app": "ممكين وأظهر التطبيق",
|
||||
"play-pause-on-click": "تشغيل/إيقاف مؤقت عند النقر"
|
||||
}
|
||||
},
|
||||
"visual-tweaks": {
|
||||
"label": "تعديلات المظهر",
|
||||
"submenu": {
|
||||
"like-buttons": {
|
||||
"default": "الافتراضي",
|
||||
"force-show": "اجبار الظهور",
|
||||
"hide": "اخفاء",
|
||||
"label": "أزرار الاعجاب"
|
||||
},
|
||||
"remove-upgrade-button": "ازالة زرار التطوير",
|
||||
"theme": {
|
||||
"dialog": {
|
||||
"button": {
|
||||
"cancel": "إلغاء",
|
||||
"remove": "ازالة"
|
||||
},
|
||||
"remove-theme": "هل أنت متأكد أنك تريد إزالة السمة المخصصة؟",
|
||||
"remove-theme-message": "سيؤدي هذا إلى إزالة السمة المخصصة"
|
||||
},
|
||||
"label": "السمة",
|
||||
"submenu": {
|
||||
"import-css-file": "استيراد ملف CSS مخصص",
|
||||
"no-theme": "بدون سمة"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"plugins": {
|
||||
"enabled": "مفعل",
|
||||
"label": "الاضافات",
|
||||
"new": "جديد"
|
||||
},
|
||||
"view": {
|
||||
"label": "اظهار",
|
||||
"submenu": {
|
||||
"force-reload": "اجبار اعادة التحميل",
|
||||
"reload": "اعادة التحميل",
|
||||
"reset-zoom": "الحجم الحقيقي",
|
||||
"toggle-fullscreen": "ملء الشاشة",
|
||||
"zoom-in": "تكبير",
|
||||
"zoom-out": "تصغير"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tray": {
|
||||
"next": "التالي",
|
||||
"previous": "السابق",
|
||||
"quit": "خروج",
|
||||
"restart": "إعادة تشغيل التطبيق",
|
||||
"show": "عرض النافدة",
|
||||
"tooltip": {
|
||||
"default": "يوتيوب اغاني",
|
||||
"with-song-info": "يوتيوب أغاني: {{الفنان}}-{{العنوان}}"
|
||||
}
|
||||
}
|
||||
},
|
||||
"plugins": {
|
||||
"adblocker": {
|
||||
"description": "حجب جميع الإعلانات والمسارات خارج الصندوق",
|
||||
"name": "حاجب الإعلانات"
|
||||
}
|
||||
}
|
||||
}
|
||||
813
src/i18n/resources/ca.json
Normal file
813
src/i18n/resources/ca.json
Normal file
@ -0,0 +1,813 @@
|
||||
{
|
||||
"common": {
|
||||
"console": {
|
||||
"plugins": {
|
||||
"execute-failed": "Ha fallat l'execució de l'extensió {{pluginName}}::{{contextName}}",
|
||||
"executed-at-ms": "L'extensió {{pluginName}}::{{contextName}} s'ha executat als {{ms}}ms",
|
||||
"initialize-failed": "Ha fallat la inicialització de l'extensió «{{pluginName}}»",
|
||||
"load-all": "Carregant totes les extensions",
|
||||
"load-failed": "Error al carregar l'extensió «{{pluginName}}»",
|
||||
"loaded": "L'extensió «{{pluginName}}» s'ha carregat",
|
||||
"unload-failed": "Error al deshabilitar l'extensió «{{pluginName}}»",
|
||||
"unloaded": "Extensió «{{pluginName}}» deshabilitada"
|
||||
}
|
||||
}
|
||||
},
|
||||
"language": {
|
||||
"code": "ca",
|
||||
"local-name": "Català",
|
||||
"name": "Catalan"
|
||||
},
|
||||
"main": {
|
||||
"console": {
|
||||
"did-finish-load": {
|
||||
"dev-tools": "Càrrega finalitzada. S'han obert les DevTools"
|
||||
},
|
||||
"i18n": {
|
||||
"loaded": "i18n carregat"
|
||||
},
|
||||
"second-instance": {
|
||||
"receive-command": "Comanda rebuda a través del protocol: «{{command}}»"
|
||||
},
|
||||
"theme": {
|
||||
"css-file-not-found": "L'arxiu CSS «{{cssFile}}» no existeix, s'ha ignorat"
|
||||
},
|
||||
"unresponsive": {
|
||||
"details": "Error sense resposta!\n{{error}}"
|
||||
},
|
||||
"when-ready": {
|
||||
"clearing-cache-after-20s": "Netejant la memòria cau de l'aplicació"
|
||||
},
|
||||
"window": {
|
||||
"tried-to-render-offscreen": "La finestra s'ha intentat mostrar fora de la pantalla, windowSize={{windowSize}}, displaySize={{displaySize}}, position={{position}}"
|
||||
}
|
||||
},
|
||||
"dialog": {
|
||||
"hide-menu-enabled": {
|
||||
"detail": "El menú es troba amagat, premi «Alt» per mostrar-lo (o «Escapament» si utilitza el menú integrat In-App)",
|
||||
"message": "S'ha habilitat l'amagament del menú",
|
||||
"title": "Amagament del menú habilitat"
|
||||
},
|
||||
"need-to-restart": {
|
||||
"buttons": {
|
||||
"later": "Més tard",
|
||||
"restart-now": "Reinicia ara"
|
||||
},
|
||||
"detail": "L'extensió «{{pluginName}}» requereix reiniciar l'aplicació per fer tenir efecte",
|
||||
"message": "\"{{pluginName}}\" necessita reiniciar-se",
|
||||
"title": "Es requereix reiniciar"
|
||||
},
|
||||
"unresponsive": {
|
||||
"buttons": {
|
||||
"quit": "Marxar",
|
||||
"relaunch": "Rellançar",
|
||||
"wait": "Espera"
|
||||
},
|
||||
"detail": "Ho sentim per les molèsties! si us plau, tria què fer:",
|
||||
"message": "L'aplicació ha deixat de respondre",
|
||||
"title": "La finestra ha deixat de respondre"
|
||||
},
|
||||
"update-available": {
|
||||
"buttons": {
|
||||
"disable": "Deshabilita les actualitzacions",
|
||||
"download": "Descarrega",
|
||||
"ok": "D'acord"
|
||||
},
|
||||
"detail": "Hi ha una nova versió disponible i pot ser descarregada a {{downloadLink}}",
|
||||
"message": "Hi ha una nova versió disponible",
|
||||
"title": "Actualització disponible"
|
||||
}
|
||||
},
|
||||
"menu": {
|
||||
"about": "Quant a",
|
||||
"navigation": {
|
||||
"label": "Navegació",
|
||||
"submenu": {
|
||||
"copy-current-url": "Copia l'URL actual",
|
||||
"go-back": "Ves enrere",
|
||||
"go-forward": "Ves endavant",
|
||||
"quit": "Surt",
|
||||
"restart": "Reinicia l'aplicació"
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"label": "Opcions",
|
||||
"submenu": {
|
||||
"advanced-options": {
|
||||
"label": "Opcions avançades",
|
||||
"submenu": {
|
||||
"auto-reset-app-cache": "Reinicialitza la memòria cau de l'aplicació quan es reiniciï",
|
||||
"disable-hardware-acceleration": "Deshabilita l'acceleració per hardware",
|
||||
"edit-config-json": "Edita el config.json",
|
||||
"override-user-agent": "Sobreescriu l'agent d'usuari (User-Agent)",
|
||||
"restart-on-config-changes": "Reinicia quan es canviï la configuració",
|
||||
"set-proxy": {
|
||||
"label": "Definir servidor intermediari (proxy)",
|
||||
"prompt": {
|
||||
"label": "Introduir l'adreça del servidor intermediari: (deixar en blanc per deshabilitar)",
|
||||
"placeholder": "Exemple: SOCKS5://127.0.0.1:9999",
|
||||
"title": "Definir servidor intermediari (proxy)"
|
||||
}
|
||||
},
|
||||
"toggle-dev-tools": "Commuta les DevTools"
|
||||
}
|
||||
},
|
||||
"always-on-top": "Mostra sempre per sobre",
|
||||
"auto-update": "Actualitza automàticament",
|
||||
"hide-menu": {
|
||||
"dialog": {
|
||||
"message": "El menú s'amagarà la següent vegada que s'iniciï l'aplicació, prem «Alt» per mostrar-lo (o accent obert « ` » si utilitza el menú integrat In-App)",
|
||||
"title": "Amagament del menú habilitat"
|
||||
},
|
||||
"label": "Amaga el menú"
|
||||
},
|
||||
"language": {
|
||||
"dialog": {
|
||||
"message": "L'idioma es canviarà un cop es reiniciï",
|
||||
"title": "Idioma canviat"
|
||||
},
|
||||
"label": "Idioma",
|
||||
"submenu": {
|
||||
"to-help-translate": "Vols ajudar a traduir? Clica aquí"
|
||||
}
|
||||
},
|
||||
"resume-on-start": "Reprèn l'última cançó quan s'inicia l'aplicació",
|
||||
"single-instance-lock": "Bloqueja en una única instància",
|
||||
"start-at-login": "Obre a l'iniciar sessió",
|
||||
"starting-page": {
|
||||
"label": "Pàgina d'inici",
|
||||
"unset": "Sense establir"
|
||||
},
|
||||
"tray": {
|
||||
"label": "Safata d'icones",
|
||||
"submenu": {
|
||||
"disabled": "Deshabilitat",
|
||||
"enabled-and-hide-app": "Mostra la icona i amaga l'aplicació",
|
||||
"enabled-and-show-app": "Mostra la icona i mostra l'aplicació",
|
||||
"play-pause-on-click": "Reprodueix / pausa en clicar"
|
||||
}
|
||||
},
|
||||
"visual-tweaks": {
|
||||
"label": "Opcions visuals",
|
||||
"submenu": {
|
||||
"like-buttons": {
|
||||
"default": "Per defecte",
|
||||
"force-show": "Força que es mostri",
|
||||
"hide": "Amaga",
|
||||
"label": "Botons de «m'agrada»"
|
||||
},
|
||||
"remove-upgrade-button": "Elimina el botó «Actualitza a Music Premium»",
|
||||
"theme": {
|
||||
"dialog": {
|
||||
"button": {
|
||||
"cancel": "Cancel·la",
|
||||
"remove": "Elimina"
|
||||
},
|
||||
"remove-theme": "De debó vols eliminar el tema personalitzat?",
|
||||
"remove-theme-message": "Això eliminarà el tema personalitzat"
|
||||
},
|
||||
"label": "Tema",
|
||||
"submenu": {
|
||||
"import-css-file": "Importa un arxiu CSS personalitzat",
|
||||
"no-theme": "Cap tema"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"plugins": {
|
||||
"enabled": "Habilitat",
|
||||
"label": "Extensions",
|
||||
"new": "NOU"
|
||||
},
|
||||
"view": {
|
||||
"label": "Veure",
|
||||
"submenu": {
|
||||
"force-reload": "Força la recàrrega",
|
||||
"reload": "Recarrega",
|
||||
"reset-zoom": "Mida real",
|
||||
"toggle-fullscreen": "Commuta la pantalla completa",
|
||||
"zoom-in": "Apropa el zoom",
|
||||
"zoom-out": "Allunya el zoom"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tray": {
|
||||
"next": "Següent",
|
||||
"play-pause": "Reprodueix/Pausa",
|
||||
"previous": "Anterior",
|
||||
"quit": "Tanca",
|
||||
"restart": "Reinicia l'aplicació",
|
||||
"show": "Mostra la finestra",
|
||||
"tooltip": {
|
||||
"default": "YouTube Music",
|
||||
"with-song-info": "YouTube Music: {{artist}} - {{title}}"
|
||||
}
|
||||
}
|
||||
},
|
||||
"plugins": {
|
||||
"ad-speedup": {
|
||||
"description": "Si es reprodueix un anunci, silencia l'àudio i el reprodueix a la velocitat 16x",
|
||||
"name": "Accelera els anuncis"
|
||||
},
|
||||
"adblocker": {
|
||||
"description": "Bloqueja tots els anuncis i el seguiment",
|
||||
"menu": {
|
||||
"blocker": "Bloquejador"
|
||||
},
|
||||
"name": "Bloquejador d'anuncis"
|
||||
},
|
||||
"album-actions": {
|
||||
"description": "Afegeix botons de «no m'agrada / retirar el no m'agrada» i «m'agrada / retirar el m'agrada» per aplicar-ho a totes les cançons en una llista de reproducció o àlbum",
|
||||
"name": "Accions a l'àlbum"
|
||||
},
|
||||
"album-color-theme": {
|
||||
"description": "Aplica un tema dinàmic i efectes visuals basats en la paleta de colors de l'àlbum",
|
||||
"menu": {
|
||||
"color-mix-ratio": {
|
||||
"label": "Proporció de la barreja de colors",
|
||||
"submenu": {
|
||||
"percent": "{{ratio}}%"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "Tema de color de l'àlbum"
|
||||
},
|
||||
"ambient-mode": {
|
||||
"description": "Aplica un efecte d'il·luminació que projecta colors difusos del vídeo al fons de la pantalla",
|
||||
"menu": {
|
||||
"blur-amount": {
|
||||
"label": "Quantitat de desenfocament",
|
||||
"submenu": {
|
||||
"pixels": "{{blurAmount}} píxels"
|
||||
}
|
||||
},
|
||||
"buffer": {
|
||||
"label": "Buffer",
|
||||
"submenu": {
|
||||
"buffer": "{{buffer}}"
|
||||
}
|
||||
},
|
||||
"opacity": {
|
||||
"label": "Opacitat",
|
||||
"submenu": {
|
||||
"percent": "{{opacity}}%"
|
||||
}
|
||||
},
|
||||
"quality": {
|
||||
"label": "Qualitat",
|
||||
"submenu": {
|
||||
"pixels": "{{quality}} píxels"
|
||||
}
|
||||
},
|
||||
"size": {
|
||||
"label": "Mida",
|
||||
"submenu": {
|
||||
"percent": "{{size}}%"
|
||||
}
|
||||
},
|
||||
"smoothness-transition": {
|
||||
"label": "Transició suau",
|
||||
"submenu": {
|
||||
"during": "Durant {{interpolationTime}} s"
|
||||
}
|
||||
},
|
||||
"use-fullscreen": {
|
||||
"label": "Utilitza en pantalla completa"
|
||||
}
|
||||
},
|
||||
"name": "Mode ambient"
|
||||
},
|
||||
"api-server": {
|
||||
"description": "Afegeix un servidor API per controlar el reproductor",
|
||||
"dialog": {
|
||||
"request": {
|
||||
"buttons": {
|
||||
"allow": "Permet",
|
||||
"deny": "Denegar"
|
||||
},
|
||||
"message": "Permetre que {{ID}} ({{origin}}) accedeixi a l'API?",
|
||||
"title": "Petició d'autorització API"
|
||||
}
|
||||
},
|
||||
"menu": {
|
||||
"auth-strategy": {
|
||||
"label": "Estratègia d'autorització",
|
||||
"submenu": {
|
||||
"auth-at-first": {
|
||||
"label": "Autoritza a la primera petició"
|
||||
},
|
||||
"none": {
|
||||
"label": "Sense autorització"
|
||||
}
|
||||
}
|
||||
},
|
||||
"hostname": {
|
||||
"label": "Nom del host"
|
||||
},
|
||||
"port": {
|
||||
"label": "Port"
|
||||
}
|
||||
},
|
||||
"name": "Servidor API [Beta]",
|
||||
"prompt": {
|
||||
"hostname": {
|
||||
"label": "Introdueix el nom del host (per exemple 0.0.0.0) pel servidor API:",
|
||||
"title": "Nom del host"
|
||||
},
|
||||
"port": {
|
||||
"label": "Introdueix el port pel servidor API:",
|
||||
"title": "Port"
|
||||
}
|
||||
}
|
||||
},
|
||||
"audio-compressor": {
|
||||
"description": "Aplica compressió a l'àudio (baixa el volum de les parts més sorolloses de la senyal d'àudio i puja el volum de les parts més fluixes)",
|
||||
"name": "Compressió d'àudio"
|
||||
},
|
||||
"blur-nav-bar": {
|
||||
"description": "Desenfoca i aplica transparència a la barra de navegació",
|
||||
"name": "Desenfoca la barra de navegació"
|
||||
},
|
||||
"bypass-age-restrictions": {
|
||||
"description": "Esquiva la verificació d'edat de YouTube",
|
||||
"name": "Esquiva les restriccions d'edat"
|
||||
},
|
||||
"captions-selector": {
|
||||
"description": "Selector de subtítols per les pistes d'àudio de YouTube Music",
|
||||
"menu": {
|
||||
"autoload": "Selecciona automàticament l'últim subtítol emprat",
|
||||
"disable-captions": "Sense subtítols per defecte"
|
||||
},
|
||||
"name": "Selector de subtítols",
|
||||
"prompt": {
|
||||
"selector": {
|
||||
"label": "Idioma actual dels subtítols: {{language}}",
|
||||
"none": "Cap",
|
||||
"title": "Selecciona l'idioma dels subtítols"
|
||||
}
|
||||
},
|
||||
"templates": {
|
||||
"title": "Obra el selector de subtítols"
|
||||
}
|
||||
},
|
||||
"compact-sidebar": {
|
||||
"description": "Sempre mostrar la barra lateral en mode compacte",
|
||||
"name": "Barra lateral compacta"
|
||||
},
|
||||
"crossfade": {
|
||||
"description": "Transició creuada (crossfade) entre cançons",
|
||||
"menu": {
|
||||
"advanced": "Avançat"
|
||||
},
|
||||
"name": "Transició creuada [Beta]",
|
||||
"prompt": {
|
||||
"options": {
|
||||
"multi-input": {
|
||||
"fade-in-duration": "Durada de la transició d'entrada (ms)",
|
||||
"fade-out-duration": "Durada de la transició de sortida (ms)",
|
||||
"fade-scaling": {
|
||||
"label": "Escala de la transició",
|
||||
"linear": "Linear",
|
||||
"logarithmic": "Logarítmica"
|
||||
},
|
||||
"seconds-before-end": "Transiciona N segons abans del final"
|
||||
},
|
||||
"title": "Opcions de transició creuada"
|
||||
}
|
||||
}
|
||||
},
|
||||
"disable-autoplay": {
|
||||
"description": "Fa que la cançó comenci en mode «pausat»",
|
||||
"menu": {
|
||||
"apply-once": "Tan sols s'aplica a l'inici"
|
||||
},
|
||||
"name": "Deshabilita la reproducció automàtica"
|
||||
},
|
||||
"discord": {
|
||||
"backend": {
|
||||
"already-connected": "S'ha intentat connectar amb una connexió activa",
|
||||
"connected": "Connectat a Discord",
|
||||
"disconnected": "Desconnectat de Discord"
|
||||
},
|
||||
"description": "Mostra als teus amics allò que escoltes a l'estat d'activitat",
|
||||
"menu": {
|
||||
"auto-reconnect": "Reconnecta automàticament",
|
||||
"clear-activity": "Esborra l'activitat",
|
||||
"clear-activity-after-timeout": "Esborra l'activitat al cap d'un temps",
|
||||
"connected": "Connectat",
|
||||
"disconnected": "Desconnectat",
|
||||
"hide-duration-left": "Amaga la durada restant",
|
||||
"hide-github-button": "Amaga el botó de l'enllaç a GitHub",
|
||||
"play-on-youtube-music": "Reprodueix a YouTube Music",
|
||||
"set-inactivity-timeout": "Estableix temps d'espera d'inactivitat"
|
||||
},
|
||||
"name": "Estat d'activitat de Discord",
|
||||
"prompt": {
|
||||
"set-inactivity-timeout": {
|
||||
"label": "Introdueix el temps d'espera d'inactivitat en segons:",
|
||||
"title": "Estableix el temps d'espera d'inactivitat"
|
||||
}
|
||||
}
|
||||
},
|
||||
"downloader": {
|
||||
"backend": {
|
||||
"dialog": {
|
||||
"error": {
|
||||
"buttons": {
|
||||
"ok": "D'acord"
|
||||
},
|
||||
"message": "Caram! Ho sentim, ha fallat la descàrrega…",
|
||||
"title": "Error a la descàrrega!"
|
||||
},
|
||||
"start-download-playlist": {
|
||||
"buttons": {
|
||||
"ok": "D'acord"
|
||||
},
|
||||
"detail": "({{playlistSize}} cançons)",
|
||||
"message": "Descarregant llista de reproducció {{playlistTitle}}",
|
||||
"title": "Descàrrega començada"
|
||||
}
|
||||
},
|
||||
"feedback": {
|
||||
"conversion-progress": "Conversió: {{percent}}%",
|
||||
"converting": "Convertint…",
|
||||
"done": "Fet: {{filePath}}",
|
||||
"download-info": "Descarregant {{artist}} - {{title}} [{{videoId}}",
|
||||
"download-progress": "Descàrrega: {{percent}}%",
|
||||
"downloading": "Descarregant…",
|
||||
"downloading-counter": "Descarregant {{current}}/{{total}}…",
|
||||
"downloading-playlist": "Descarregant la llista de reproducció «{{playlistTitle}}» - {{playlistSize}} cançons ({{playlistId}})",
|
||||
"error-while-downloading": "Error al descarregar «{{author}} - {{title}}»: {{error}}",
|
||||
"folder-already-exists": "La carpeta {{playlistFolder}} ja existeix",
|
||||
"getting-playlist-info": "Obtenint la informació de la llista de reproducció…",
|
||||
"loading": "Carregant…",
|
||||
"playlist-has-only-one-song": "La llista de reproducció té un sol element, descarregant-lo directament",
|
||||
"playlist-id-not-found": "No s'ha trobat cap ID de llista de reproducció",
|
||||
"playlist-is-empty": "La llista de reproducció és buida",
|
||||
"playlist-is-mix-or-private": "Error obtenint la informació de la llista de reproducció: assegura't que no és una llista de reproducció privada o de «Mixos per a tu»\n\n{{error}}",
|
||||
"preparing-file": "Preparant arxiu…",
|
||||
"saving": "Desant…",
|
||||
"trying-to-get-playlist-id": "Intentant obtenir l'ID de la llista de reproducció: {{playlistId}}",
|
||||
"video-id-not-found": "Vídeo no trobat",
|
||||
"writing-id3": "Escrivint les etiquetes ID3…"
|
||||
}
|
||||
},
|
||||
"description": "Descarrega el MP3 / àudio d'origen directament des de la interfície",
|
||||
"menu": {
|
||||
"choose-download-folder": "Tria la carpeta de descàrrega",
|
||||
"download-finish-settings": {
|
||||
"label": "Descarrega en finalitzar",
|
||||
"prompt": {
|
||||
"last-percent": "Desprès del x percent",
|
||||
"last-seconds": "Últims x segons",
|
||||
"title": "Configura quan descarregar"
|
||||
},
|
||||
"submenu": {
|
||||
"advanced": "Avançat",
|
||||
"enabled": "Habilitat",
|
||||
"mode": "Mode de temps",
|
||||
"percent": "Percentatge",
|
||||
"seconds": "Segons"
|
||||
}
|
||||
},
|
||||
"download-playlist": "Descarrega la llista de reproducció",
|
||||
"presets": "Configuracions predefinides",
|
||||
"skip-existing": "Omet els arxius existents"
|
||||
},
|
||||
"name": "Descàrregues",
|
||||
"renderer": {
|
||||
"can-not-update-progress": "No es pot actualitzar el progrés"
|
||||
},
|
||||
"templates": {
|
||||
"button": "Descarrega"
|
||||
}
|
||||
},
|
||||
"exponential-volume": {
|
||||
"description": "Fa que el control lliscant del volum sigui exponencial per que sigui més fàcil seleccionar volums més baixos.",
|
||||
"name": "Volum exponencial"
|
||||
},
|
||||
"in-app-menu": {
|
||||
"description": "Fa que la barra de menú superior tingui un elegant aspecte fosc o basat en el color de l'àlbum",
|
||||
"menu": {
|
||||
"hide-dom-window-controls": "Amaga els controls de la finestra del DOM"
|
||||
},
|
||||
"name": "Menú integrat In-App"
|
||||
},
|
||||
"lumiastream": {
|
||||
"description": "Afegeix suport pel Lumia Stream",
|
||||
"name": "Lumia Stream [Beta]"
|
||||
},
|
||||
"lyrics-genius": {
|
||||
"description": "Afegeix suport per la lletra de la majoria de cançons",
|
||||
"menu": {
|
||||
"romanized-lyrics": "Lletra romanitzada"
|
||||
},
|
||||
"name": "Lletres de Genius",
|
||||
"renderer": {
|
||||
"fetched-lyrics": "S'ha buscat la lletra a Genius"
|
||||
}
|
||||
},
|
||||
"music-together": {
|
||||
"description": "Comparteix una llista de reproducció amb els demés. Quan l'amfitrió reprodueix una cançó, la resta també sentiran la mateixa",
|
||||
"dialog": {
|
||||
"enter-host": "Introdueix l'ID de l'amfitrió"
|
||||
},
|
||||
"internal": {
|
||||
"save": "Desa",
|
||||
"track-source": "Origen de la pista",
|
||||
"unknown-user": "Usuari desconegut"
|
||||
},
|
||||
"menu": {
|
||||
"click-to-copy-id": "Copia l'ID d'amfitrió",
|
||||
"close": "Tanca el Music Together",
|
||||
"connected-users": "Usuaris connectats",
|
||||
"disconnect": "Desconnecta el Music Together",
|
||||
"empty-user": "No hi ha usuaris connectats",
|
||||
"host": "Amfitrió de Music Together",
|
||||
"join": "Uneix-te a Music Together",
|
||||
"permission": {
|
||||
"all": "Permet que els convidats controlin la llista de reproducció i el reproductor",
|
||||
"host-only": "Tan sols l'amfitrió pot controlar la llista de reproducció i el reproductor",
|
||||
"playlist": "Permet que els convidats controlin la llista de reproducció"
|
||||
},
|
||||
"set-permission": "Canvia els permisos de control",
|
||||
"status": {
|
||||
"disconnected": "Desconnectat",
|
||||
"guest": "Connectat com a convidat",
|
||||
"host": "Connectat com amfitrió"
|
||||
}
|
||||
},
|
||||
"name": "Music Together [Beta]",
|
||||
"toast": {
|
||||
"add-song-failed": "Error al afegir la cançó",
|
||||
"closed": "Music Together tancat",
|
||||
"disconnected": "Music Together desconnectat",
|
||||
"host-failed": "No s'ha pogut començar el Music Together",
|
||||
"id-copied": "L'ID d'amfitrió s'ha copiat al porta-retalls",
|
||||
"id-copy-failed": "Error al copiar l'ID d'amfitrió al porta-retalls",
|
||||
"join-failed": "Error al unir-se al Music Together",
|
||||
"joined": "T'has unit al Music Together",
|
||||
"permission-changed": "Els permisos de Music Together han canviat a «{{permission}}»",
|
||||
"remove-song-failed": "Error al eliminar la cançó",
|
||||
"user-connected": "{{name}} s'ha unit al Music Together",
|
||||
"user-disconnected": "{{name}} s'ha desconnectat del Music Together"
|
||||
}
|
||||
},
|
||||
"navigation": {
|
||||
"description": "Fletxes de navegació Següent / Enrere integrades directament a la interfície, com al teu navegador preferit",
|
||||
"name": "Navegació"
|
||||
},
|
||||
"no-google-login": {
|
||||
"description": "Elimina els botons d'inici de sessió de Google de la interfície",
|
||||
"name": "Amaga l'inici de sessió de Google"
|
||||
},
|
||||
"notifications": {
|
||||
"description": "Mostra una notificació quan una cançó es comença a reproduir (les notificacions interactives estan disponibles a Windows)",
|
||||
"menu": {
|
||||
"interactive": "Notificacions interactives",
|
||||
"interactive-settings": {
|
||||
"label": "Configuració interactiva",
|
||||
"submenu": {
|
||||
"hide-button-text": "Amaga text del botó",
|
||||
"refresh-on-play-pause": "Recarrega al Reproduir/Pausar",
|
||||
"tray-controls": "Obra/Tanca en clicar a la safata"
|
||||
}
|
||||
},
|
||||
"priority": "Prioritat de les notificacions",
|
||||
"toast-style": "Estil dels missatges emergents",
|
||||
"unpause-notification": "Mostra notificació en reprendre la reproducció"
|
||||
},
|
||||
"name": "Notificacions"
|
||||
},
|
||||
"picture-in-picture": {
|
||||
"description": "Permet commutar el mode d'imatge en imatge (PiP)",
|
||||
"menu": {
|
||||
"always-on-top": "Mostra sempre a sobre",
|
||||
"hotkey": {
|
||||
"label": "Drecera del teclat",
|
||||
"prompt": {
|
||||
"keybind-options": {
|
||||
"hotkey": "Drecera del teclat"
|
||||
},
|
||||
"label": "Tria una drecera per commutar el mode d'imatge en imatge (PiP)",
|
||||
"title": "Drecera del mode imatge en imatge (PiP)"
|
||||
}
|
||||
},
|
||||
"save-window-position": "Desa la posició de la finestra",
|
||||
"save-window-size": "Desa la mida de la finestra",
|
||||
"use-native-pip": "Utilitza l'imatge en imatge (PiP) nativa del navegador"
|
||||
},
|
||||
"name": "Imatge en imatge (PiP)",
|
||||
"templates": {
|
||||
"button": "Imatge en imatge (PiP)"
|
||||
}
|
||||
},
|
||||
"playback-speed": {
|
||||
"description": "Escolta-ho ràpid, escolta-ho lent! Afegeix un control lliscant per canviar la velocitat de la cançó",
|
||||
"name": "Velocitat de la reproducció",
|
||||
"templates": {
|
||||
"button": "Velocitat"
|
||||
}
|
||||
},
|
||||
"precise-volume": {
|
||||
"description": "Controla el volum de manera precisa a través de la rodeta del ratolí / dreceres del teclat, amb una interfície personalitzada i passos de volum personalitzats",
|
||||
"menu": {
|
||||
"arrows-shortcuts": "Controls locals de tecles de fletxa",
|
||||
"custom-volume-steps": "Estableix passos de volum personalitzats",
|
||||
"global-shortcuts": "Dreceres de teclat globals"
|
||||
},
|
||||
"name": "Volum precís",
|
||||
"prompt": {
|
||||
"global-shortcuts": {
|
||||
"keybind-options": {
|
||||
"decrease": "Baixa el volum",
|
||||
"increase": "Puja el volum"
|
||||
},
|
||||
"label": "Tria les dreceres globals de volum:",
|
||||
"title": "Dreceres globals de volum"
|
||||
},
|
||||
"volume-steps": {
|
||||
"label": "Tria els passos d'augment o disminució del volum",
|
||||
"title": "Passos de volum"
|
||||
}
|
||||
}
|
||||
},
|
||||
"quality-changer": {
|
||||
"backend": {
|
||||
"dialog": {
|
||||
"quality-changer": {
|
||||
"detail": "Qualitat actual: {{quality}}",
|
||||
"message": "Tria la qualitat del vídeo:",
|
||||
"title": "Tria la qualitat del vídeo"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": "Permet canviar la qualitat del vídeo amb un botó que s'hi mostra a sobre",
|
||||
"name": "Botó de qualitat del vídeo"
|
||||
},
|
||||
"scrobbler": {
|
||||
"description": "Afegeix suport per scrobbling (Last.fm, ListenBrainz, etc.)",
|
||||
"dialog": {
|
||||
"lastfm": {
|
||||
"auth-failed": {
|
||||
"message": "Error al autenticar amb Last.fm\nAmaga la finestra emergent fins el següent reinici.",
|
||||
"title": "Error d'autenticació"
|
||||
}
|
||||
}
|
||||
},
|
||||
"menu": {
|
||||
"lastfm": {
|
||||
"api-settings": "Configuració de l'API de Last.fm"
|
||||
},
|
||||
"listenbrainz": {
|
||||
"token": "Introduir token d'usuari de ListenBrainz"
|
||||
},
|
||||
"scrobble-other-media": "Scrobble amb altres mitjans"
|
||||
},
|
||||
"name": "Scrobbler",
|
||||
"prompt": {
|
||||
"lastfm": {
|
||||
"api-key": "Clau d'API de Last.fm",
|
||||
"api-secret": "Clau secreta de l'API de Last.fm"
|
||||
},
|
||||
"listenbrainz": {
|
||||
"token": {
|
||||
"label": "Introdueix el teu token de ListenBrainz:",
|
||||
"title": "Token de ListenBrainz"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"shortcuts": {
|
||||
"description": "Permet l'ús de dreceres globals del teclat per la reproducció (reproduir/pausar/següent/anterior) i desactivar l'OSD dels mitjans en sobreescriure les tecles de control multimèdia, habilita el Ctrl/CMD + F per buscar, habilita el suport MPRIS a Linux per tecles de control multimèdia, i dreceres de teclat personalitzades per usuaris avançats",
|
||||
"menu": {
|
||||
"override-media-keys": "Sobreescriu les tecles de control multimèdia",
|
||||
"set-keybinds": "Estableix controls globals de les cançons"
|
||||
},
|
||||
"name": "Dreceres i MPRIS",
|
||||
"prompt": {
|
||||
"keybind": {
|
||||
"keybind-options": {
|
||||
"next": "Següent",
|
||||
"play-pause": "Reproduir / Pausar",
|
||||
"previous": "Anterior"
|
||||
},
|
||||
"label": "Tria combinacions de tecles per controlar les cançons:",
|
||||
"title": "Dreceres globals"
|
||||
}
|
||||
}
|
||||
},
|
||||
"skip-disliked-songs": {
|
||||
"description": "Salta les cançons amb «no m'agrada»",
|
||||
"name": "Salta les cançons que no t'agraden"
|
||||
},
|
||||
"skip-silences": {
|
||||
"description": "Omet automàticament les seccions amb silenci a les cançons",
|
||||
"name": "Omet els silencis"
|
||||
},
|
||||
"sponsorblock": {
|
||||
"description": "Omet automàticament els segments dels vídeos que no son música, com la intro o el final",
|
||||
"name": "SponsorBlock"
|
||||
},
|
||||
"synced-lyrics": {
|
||||
"description": "Proporciona lletres sincronitzades amb les cançons, a través de proveïdors com LRClib.",
|
||||
"errors": {
|
||||
"fetch": "⚠️ - Se ha produït un error en descarregar la lletra. Si us plau, intenta-ho més tard.",
|
||||
"not-found": "⚠️ - No s'ha trobat la lletra per aquesta cançó."
|
||||
},
|
||||
"menu": {
|
||||
"default-text-string": {
|
||||
"label": "Caràcter per defecte entre lletres",
|
||||
"tooltip": "Tria el caràcter per defecte que es mostrarà a l'espai entre les lletres"
|
||||
},
|
||||
"line-effect": {
|
||||
"label": "Efecte de la línia",
|
||||
"submenu": {
|
||||
"focus": {
|
||||
"label": "Focus",
|
||||
"tooltip": "Mostra tan sols la línia actual en blanc"
|
||||
},
|
||||
"offset": {
|
||||
"label": "Desplaçament",
|
||||
"tooltip": "Desplaçament a la dreta de la línia actual"
|
||||
},
|
||||
"scale": {
|
||||
"label": "Escala",
|
||||
"tooltip": "Redimensiona la línia actual"
|
||||
}
|
||||
},
|
||||
"tooltip": "Tria l'efecte a aplicar a la línia actual"
|
||||
},
|
||||
"precise-timing": {
|
||||
"label": "Fes que les lletres es sincronitzin a la perfecció",
|
||||
"tooltip": "Calcula al mil·lisegon l'aparició de la següent línia (pot tenir un petit impacte en el rendiment)"
|
||||
},
|
||||
"show-lyrics-even-if-inexact": {
|
||||
"label": "Mostra la lletra tot i que sigui inexacta",
|
||||
"tooltip": "Si no es troba la cançó, el plugin torna a intentar obtenir la lletra amb una cerca diferent.\nEl resultat d'aquesta segona cerca podria no ser exacte."
|
||||
},
|
||||
"show-time-codes": {
|
||||
"label": "Mostra els codis de temps",
|
||||
"tooltip": "Mostra els codis de temps al costat de la lletra"
|
||||
}
|
||||
},
|
||||
"name": "Lletres sincronitzades",
|
||||
"refetch-btn": {
|
||||
"fetching": "Obtenint...",
|
||||
"normal": "Tornar a obtenir la lletra"
|
||||
},
|
||||
"warnings": {
|
||||
"duration-mismatch": "⚠️ - La lletra podria no estar ben sincronitzada, la durada no és coincident.",
|
||||
"inexact": "⚠️ - La lletra d'aquesta cançó podria no ser exacta",
|
||||
"instrumental": "⚠️ - Aquesta cançó és instrumental"
|
||||
}
|
||||
},
|
||||
"taskbar-mediacontrol": {
|
||||
"description": "Controla la reproducció des de la barra de tasques del Windows",
|
||||
"name": "Control multimèdia a la barra de tasques"
|
||||
},
|
||||
"touchbar": {
|
||||
"description": "Afegeix un giny a la Touch Bar per usuaris de macOS",
|
||||
"name": "TouchBar"
|
||||
},
|
||||
"tuna-obs": {
|
||||
"description": "Integració amb l'extensió «Tuna» del OBS",
|
||||
"name": "Tuna OBS"
|
||||
},
|
||||
"video-toggle": {
|
||||
"description": "Afegeix un botó per commutar entre el mode de vídeo o de cançó. Opcionalment, es pot eliminar la pestanya de vídeo per complet",
|
||||
"menu": {
|
||||
"align": {
|
||||
"label": "Alineament",
|
||||
"submenu": {
|
||||
"left": "Esquerra",
|
||||
"middle": "Mig",
|
||||
"right": "Dreta"
|
||||
}
|
||||
},
|
||||
"force-hide": "Força amagar la pestanya de vídeo",
|
||||
"mode": {
|
||||
"label": "Mode",
|
||||
"submenu": {
|
||||
"custom": "Commutador personalitzat",
|
||||
"disabled": "Deshabilitat",
|
||||
"native": "Commutador nadiu"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "Botó de vídeo",
|
||||
"templates": {
|
||||
"button": "Cançó"
|
||||
}
|
||||
},
|
||||
"visualizer": {
|
||||
"description": "Afegeix un visualitzador al reproductor",
|
||||
"menu": {
|
||||
"visualizer-type": "Tipus de visualitzador"
|
||||
},
|
||||
"name": "Visualitzador"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -39,12 +39,12 @@
|
||||
"clearing-cache-after-20s": "Čištění mezipaměti aplikace"
|
||||
},
|
||||
"window": {
|
||||
"tried-to-render-offscreen": "Okno se pokusilo vykreslit na pozadí, velikost okna = {{windowSize}}, display velikost = {{displaySize}}, pozice = {{position}}"
|
||||
"tried-to-render-offscreen": "Okno se pokusilo vykreslit na pozadí, velikost okna = {{windowSize}}, zobrazovací velikost = {{displaySize}}, pozice = {{position}}"
|
||||
}
|
||||
},
|
||||
"dialog": {
|
||||
"hide-menu-enabled": {
|
||||
"detail": "Menu je skryté, stiskněte 'Alt' k jeho zobrazení (nebo 'Escape', pokud používáte in-app-menu)",
|
||||
"detail": "Menu je skryté, stiskněte 'Alt' k jeho zobrazení (nebo 'ESC', pokud používáte vestavěné menu)",
|
||||
"message": "Skrýt menu je povoleno",
|
||||
"title": "Skrýt menu Povolené"
|
||||
},
|
||||
@ -158,6 +158,14 @@
|
||||
},
|
||||
"remove-upgrade-button": "Odebrat upgrade tlačítko",
|
||||
"theme": {
|
||||
"dialog": {
|
||||
"button": {
|
||||
"cancel": "zrušit",
|
||||
"remove": "Odstranit"
|
||||
},
|
||||
"remove-theme": "Jste si jisti že chcete odstranit tento vlastní motiv?",
|
||||
"remove-theme-message": "Tohle odstraní vlastní motiv"
|
||||
},
|
||||
"label": "Motiv",
|
||||
"submenu": {
|
||||
"import-css-file": "Vložit vlastní CSS soubor",
|
||||
@ -191,27 +199,43 @@
|
||||
"previous": "Minulý",
|
||||
"quit": "Ukončit",
|
||||
"restart": "Restartovat aplikaci",
|
||||
"show": "Zobrazit okno"
|
||||
"show": "Zobrazit okno",
|
||||
"tooltip": {
|
||||
"default": "Youtube Music",
|
||||
"with-song-info": "Youtube Music {{Umělec}} - {{Titul}}"
|
||||
}
|
||||
}
|
||||
},
|
||||
"plugins": {
|
||||
"ad-speedup": {
|
||||
"description": "Pokud se přehraje reklama tak ztlumí zvuk a nastaví rychlost přehrávání na 16x",
|
||||
"name": "Zrychlovač Reklam"
|
||||
},
|
||||
"adblocker": {
|
||||
"description": "Blokuje všechny reklamy a sledování ihned od začátku",
|
||||
"menu": {
|
||||
"blocker": "Blokátor"
|
||||
},
|
||||
"name": "Blokovač reklam"
|
||||
"name": "Blokátor reklam"
|
||||
},
|
||||
"album-actions": {
|
||||
"description": "Přidává Undislike, Dislike, Like, a Unlike tlačítka k apply this ke všem písničkám v seznamu písniček nebo albumu.",
|
||||
"description": "Přidává Undislike, Dislike, Like, a Unlike tlačítka k aplikování tohoto ke všem písničkám v seznamu písniček nebo albumu",
|
||||
"name": "Album akce"
|
||||
},
|
||||
"album-color-theme": {
|
||||
"description": "Používá dynamický motiv a vizuální efekty na základě palety barev alba",
|
||||
"menu": {
|
||||
"color-mix-ratio": {
|
||||
"label": "Poměr míchání barev",
|
||||
"submenu": {
|
||||
"percent": "{{poměr}}%"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "Motiv podle barvy Alba"
|
||||
},
|
||||
"ambient-mode": {
|
||||
"description": "Applies bleskové efekty pomocí casting jemných barev z videa, do vašeho pozadí obrazovky.",
|
||||
"description": "Aplikuje světelné efekty pomocí vrhání jemných barev z videa, do vašeho pozadí obrazovky",
|
||||
"menu": {
|
||||
"blur-amount": {
|
||||
"label": "Množství rozmazání",
|
||||
@ -298,7 +322,10 @@
|
||||
"prompt": {
|
||||
"options": {
|
||||
"multi-input": {
|
||||
"fade-in-duration": "Délka Sílení (ms)",
|
||||
"fade-out-duration": "Délka Slábnutí (ms)",
|
||||
"fade-scaling": {
|
||||
"label": "Škálování Přechodu",
|
||||
"linear": "Lineární",
|
||||
"logarithmic": "Logaritmické"
|
||||
},
|
||||
@ -362,6 +389,7 @@
|
||||
},
|
||||
"feedback": {
|
||||
"conversion-progress": "Konverze: {{percent}}%",
|
||||
"converting": "Převádím…",
|
||||
"done": "Hotovo: {{filePath}}",
|
||||
"download-info": "Stahování {{artist}} - {{title}} [{{videoId}}",
|
||||
"download-progress": "Stahování: {{percent}}%",
|
||||
@ -386,6 +414,11 @@
|
||||
"description": "Stahuje MP3 / source audio přímo z rozhraní",
|
||||
"menu": {
|
||||
"choose-download-folder": "Vybrat složku pro stahování",
|
||||
"download-finish-settings": {
|
||||
"submenu": {
|
||||
"advanced": "Pokoročile"
|
||||
}
|
||||
},
|
||||
"download-playlist": "Stáhnout seznam písniček",
|
||||
"presets": "Předvolby",
|
||||
"skip-existing": "Přeskočit existující soubory"
|
||||
@ -406,7 +439,8 @@
|
||||
"description": "Dává menu panelům fancy, tmavý nebo album-color vzhled",
|
||||
"menu": {
|
||||
"hide-dom-window-controls": "Skrýt DOM window controls"
|
||||
}
|
||||
},
|
||||
"name": "Vestavěné Menu"
|
||||
},
|
||||
"lumiastream": {
|
||||
"description": "Přidává Lumia Stream podporu",
|
||||
@ -414,21 +448,26 @@
|
||||
},
|
||||
"lyrics-genius": {
|
||||
"description": "Přidává lyrics podporu pro většinu písniček",
|
||||
"menu": {
|
||||
"romanized-lyrics": "Romanizované Lyrics"
|
||||
},
|
||||
"name": "Lyrics Genius",
|
||||
"renderer": {
|
||||
"fetched-lyrics": "Fetched lyrics pro Genius"
|
||||
}
|
||||
},
|
||||
"music-together": {
|
||||
"description": "Sdílejte seznam písniček s ostatními. Když the host hraje písničku, uslyší jí i všichni ostatní.",
|
||||
"description": "Sdílejte playlist s ostatními. Když hostitel přehrává písničku, uslyší jí i všichni ostatní.",
|
||||
"dialog": {
|
||||
"enter-host": "Zadejte Host ID"
|
||||
},
|
||||
"internal": {
|
||||
"save": "Uložit",
|
||||
"track-source": "Zdroj Písně",
|
||||
"unknown-user": "Neznámý uživatel"
|
||||
},
|
||||
"menu": {
|
||||
"click-to-copy-id": "Zkopírovat Host ID",
|
||||
"click-to-copy-id": "Zkopírovat ID Hosta",
|
||||
"close": "Zavřít Hudba Spolu",
|
||||
"connected-users": "Připojení uživatelé",
|
||||
"disconnect": "Odpojit od Hudby Spolu",
|
||||
@ -437,7 +476,7 @@
|
||||
"join": "Připojit se k Hudbě Spolu",
|
||||
"permission": {
|
||||
"all": "Povolit hostům ovládat seznam písniček a přehrávač",
|
||||
"host-only": "Jenom host může ovládat seznam písniček a přehrávač",
|
||||
"host-only": "Jenom hostitel může ovládat seznam písniček a přehrávač",
|
||||
"playlist": "Povolit hostům ovládat seznam písniček"
|
||||
},
|
||||
"set-permission": "Změnit ovládací oprávnění",
|
||||
@ -454,6 +493,7 @@
|
||||
"disconnected": "Hudba Spolu odpojena",
|
||||
"host-failed": "Selhalo hostování Hudby Spolu",
|
||||
"id-copied": "Host ID zkopírováno do schránky",
|
||||
"id-copy-failed": "Kopírování ID Hosta do schránky selhalo",
|
||||
"join-failed": "Selhalo připojení k Hudba Spolu",
|
||||
"joined": "Připojil/a jste se k Hudbě Spolu",
|
||||
"permission-changed": "Oprávnění Hudby Spolu se změnilo na \"{{permission}}\"",
|
||||
@ -483,6 +523,7 @@
|
||||
}
|
||||
},
|
||||
"priority": "Priorita Oznámení",
|
||||
"toast-style": "Toast Styl",
|
||||
"unpause-notification": "Zobrazit oznámení na unpause"
|
||||
},
|
||||
"name": "Oznámení"
|
||||
@ -520,6 +561,7 @@
|
||||
"precise-volume": {
|
||||
"description": "Přesná kontrola hlasitosti pomocí kolečka myši/klávesnicových zkratek, s vlastní HUD a customizable hlasitostních steps",
|
||||
"menu": {
|
||||
"arrows-shortcuts": "Ovádání Šipkami",
|
||||
"custom-volume-steps": "Nastavit vlastní hlasitostní steps",
|
||||
"global-shortcuts": "Globální klávesové zkratky"
|
||||
},
|
||||
@ -552,6 +594,37 @@
|
||||
"description": "Umožňuje měnit kvalitu videa pomocí tlačítka na video overlay",
|
||||
"name": "Měnič kvality videa"
|
||||
},
|
||||
"scrobbler": {
|
||||
"description": "Přidat scrobbing podporu (např .last.fm , Listenbrainz)",
|
||||
"dialog": {
|
||||
"lastfm": {
|
||||
"auth-failed": {
|
||||
"message": "Selhalo ověření s Last.fm\nSchovat vyskakovací okno do dalšího restartu.",
|
||||
"title": "Ověření Selhalo"
|
||||
}
|
||||
}
|
||||
},
|
||||
"menu": {
|
||||
"lastfm": {
|
||||
"api-settings": "Last.fm API nastavení"
|
||||
},
|
||||
"listenbrainz": {
|
||||
"token": "Vložte Listenbrainz user token"
|
||||
},
|
||||
"scrobble-other-media": "Scrobble jiné média"
|
||||
},
|
||||
"name": "Scrobbler",
|
||||
"prompt": {
|
||||
"lastfm": {
|
||||
"api-key": "Last,fm API klíč"
|
||||
},
|
||||
"listenbrainz": {
|
||||
"token": {
|
||||
"label": "Vložte svůj Listenbrainz user token:"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"shortcuts": {
|
||||
"description": "Dovoluje nastavit globální klávesové zkratky pro playback (přehrát/pozastavit/další/předchozí) a vypínání media OSD pomocí přepisování media klíčů, zapínání Ctrl/CMD + F k vyhledávání, zapínání Linux MPRIS podporu pro media klíče, a vlastní klávesové zkratky pro pokročilé uživatele.",
|
||||
"menu": {
|
||||
|
||||
@ -158,6 +158,14 @@
|
||||
},
|
||||
"remove-upgrade-button": "Upgrade-Schaltfläche entfernen",
|
||||
"theme": {
|
||||
"dialog": {
|
||||
"button": {
|
||||
"cancel": "Abbrechen",
|
||||
"remove": "Entfernen"
|
||||
},
|
||||
"remove-theme": "Sind Sie sich sicher, dass Sie das benutzerdefinierte Aussehen ändern wollen?",
|
||||
"remove-theme-message": "Dies wird das benutzerdefinierte Aussehen löschen"
|
||||
},
|
||||
"label": "Thema",
|
||||
"submenu": {
|
||||
"import-css-file": "Importiere eigene CSS-Datei",
|
||||
@ -199,6 +207,10 @@
|
||||
}
|
||||
},
|
||||
"plugins": {
|
||||
"ad-speedup": {
|
||||
"description": "Wenn eine Werbung spielt, stummt es das Audio und setzt die Wiedergabegeschwindigkeit auf 16x",
|
||||
"name": "Werbungsbeschleunigung"
|
||||
},
|
||||
"adblocker": {
|
||||
"description": "Blockiere jegliche Werbung und Tracker",
|
||||
"menu": {
|
||||
@ -402,6 +414,21 @@
|
||||
"description": "Lädt MP3-/Original-Audio direkt von der Schnittstelle herunter",
|
||||
"menu": {
|
||||
"choose-download-folder": "Downloadordner wählen",
|
||||
"download-finish-settings": {
|
||||
"label": "Song am Ende runterladen",
|
||||
"prompt": {
|
||||
"last-percent": "Nach x Prozent",
|
||||
"last-seconds": "Letzten x Sekunden",
|
||||
"title": "Konfiguriere wann runtergeladen werden soll"
|
||||
},
|
||||
"submenu": {
|
||||
"advanced": "Erweitert",
|
||||
"enabled": "Aktiviert",
|
||||
"mode": "Zeitmodus",
|
||||
"percent": "Prozent",
|
||||
"seconds": "Sekunden"
|
||||
}
|
||||
},
|
||||
"download-playlist": "Wiedergabeliste herunterladen",
|
||||
"presets": "Voreinstellungen",
|
||||
"skip-existing": "Vorhandene Dateien überspringen"
|
||||
@ -641,6 +668,54 @@
|
||||
"description": "Überspringt automatisch nicht-musikalische Teile wie Intro/Outro oder Teile von Musikvideos, in denen der Song nicht gespielt wird",
|
||||
"name": "SponsorBlock"
|
||||
},
|
||||
"synced-lyrics": {
|
||||
"description": "Bietet synchronisierte Liedtexte zu Songs, verwendet Anbieter wie LRClib.",
|
||||
"errors": {
|
||||
"fetch": "⚠️ - Beim Abrufen des Liedtexts ist ein Fehler aufgetreten. Bitte versuchen Sie es später nochmal.",
|
||||
"not-found": "⚠️ - Kein Text für diesen Song gefunden."
|
||||
},
|
||||
"menu": {
|
||||
"default-text-string": {
|
||||
"label": "Standardzeichen zwischen Texten",
|
||||
"tooltip": "Standardzeichen für die Lücke zwischen Songtexten auswählen"
|
||||
},
|
||||
"line-effect": {
|
||||
"label": "Zeileneffekt",
|
||||
"submenu": {
|
||||
"focus": {
|
||||
"label": "Fokussieren",
|
||||
"tooltip": "Nur aktive Zeile weiß darstellen"
|
||||
},
|
||||
"offset": {
|
||||
"label": "Versatz"
|
||||
},
|
||||
"scale": {
|
||||
"label": "Skalieren",
|
||||
"tooltip": "Aktuelle Zeile skalieren"
|
||||
}
|
||||
},
|
||||
"tooltip": "Effekt für aktive Zeile auswählen"
|
||||
},
|
||||
"precise-timing": {
|
||||
"label": "Den Songtext perfekt synchronisieren",
|
||||
"tooltip": "Auf die Millisekunde genau berechnen, wann die nächste Zeile angezeigt werden soll (Kann Einfluss auf die Leistung haben)"
|
||||
},
|
||||
"show-time-codes": {
|
||||
"label": "Zeitkodierungen anzeigen",
|
||||
"tooltip": "Zeitkodierungen neben Songtext anzeigen"
|
||||
}
|
||||
},
|
||||
"name": "Synchronisierte Texte",
|
||||
"refetch-btn": {
|
||||
"fetching": "Hole Songtext...",
|
||||
"normal": "Songtext neu holen"
|
||||
},
|
||||
"warnings": {
|
||||
"duration-mismatch": "⚠️ - Es kann sein, dass die Synchronization nicht stimmt, da die Songdauer nicht übereinstimmt.",
|
||||
"inexact": "⚠️ - Es ist Möglich, dass der Songtext für diesen Song nicht übereinstimmt.",
|
||||
"instrumental": "⚠️ - Das ist ein instrumentales Lied"
|
||||
}
|
||||
},
|
||||
"taskbar-mediacontrol": {
|
||||
"description": "Wiedergabe aus der Windows Taskleiste kontrollieren",
|
||||
"name": "Mediensteuerung in der Taskleiste"
|
||||
|
||||
@ -2,7 +2,14 @@
|
||||
"common": {
|
||||
"console": {
|
||||
"plugins": {
|
||||
"execute-failed": "Αποτυχία εκτέλεσης προσθέτου {{pluginName}}::{{contextName}}"
|
||||
"execute-failed": "Απέτυχε η εκτέλεση του πρόσθετου {{pluginName}}::{{contextName}}",
|
||||
"executed-at-ms": "Το πρόσθετο {{pluginName}}::{{contextName}} εκτελέστηκε σε {{ms}}ms",
|
||||
"initialize-failed": "Απέτυχε η αρχικοποίηση του πρόσθετου \"{{pluginName}}\"",
|
||||
"load-all": "Φόρτωση όλων των πρόσθετων",
|
||||
"load-failed": "Απέτυχε η φόρτωση του πρόσθετου \"{{pluginName}}\"",
|
||||
"loaded": "Το πρόσθετο \"{{pluginName}}\" φορτώθηκε",
|
||||
"unload-failed": "Απέτυχε η απεγκατάσταση του πρόσθετου \"{{pluginName}}\"",
|
||||
"unloaded": "Το πρόσθετο \"{{pluginName}}\" απεγκαταστάθηκε"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -12,54 +19,156 @@
|
||||
"name": "Greek"
|
||||
},
|
||||
"main": {
|
||||
"console": {
|
||||
"did-finish-load": {
|
||||
"dev-tools": "Η φόρτωση ολοκληρώθηκε. Τα DevTools άνοιξαν"
|
||||
},
|
||||
"i18n": {
|
||||
"loaded": "Το i18n φορτώθηκε"
|
||||
},
|
||||
"second-instance": {
|
||||
"receive-command": "Λήφθηκε εντολή μέσω πρωτοκόλλου: \"{{command}}\""
|
||||
},
|
||||
"theme": {
|
||||
"css-file-not-found": "Το αρχείο CSS \"{{cssFile}}\" δεν υπάρχει, αγνοείται"
|
||||
},
|
||||
"unresponsive": {
|
||||
"details": "Σφάλμα ανταπόκρισης!\n{{error}}"
|
||||
},
|
||||
"when-ready": {
|
||||
"clearing-cache-after-20s": "Εκκαθάριση μνήμης cache εφαρμογής"
|
||||
},
|
||||
"window": {
|
||||
"tried-to-render-offscreen": "Το παράθυρο προσπάθησε να απεικονίσει εκτός οθόνης, windowSize={{windowSize}}, displaySize={{displaySize}}, position={{position}}"
|
||||
}
|
||||
},
|
||||
"dialog": {
|
||||
"hide-menu-enabled": {
|
||||
"message": "Απόκρυψη μενού είναι ενεργοποιημένο"
|
||||
"detail": "Το μενού είναι κρυμμένο, χρησιμοποιήστε το 'Alt' για να το εμφανίσετε (ή το 'Escape' αν χρησιμοποιείτε το μενού εφαρμογής)",
|
||||
"message": "Η απόκρυψη μενού είναι ενεργοποιημένη",
|
||||
"title": "Η απόκρυψη μενού ενεργοποιήθηκε"
|
||||
},
|
||||
"need-to-restart": {
|
||||
"buttons": {
|
||||
"later": "Αργότερα",
|
||||
"restart-now": "Επανεκκίνηση τώρα"
|
||||
},
|
||||
"detail": "Το πρόσθετο \"{{pluginName}}\" απαιτεί επανεκκίνηση για να ισχύσει",
|
||||
"message": "Το \"{{pluginName}}\" χρειάζεται επανεκκίνηση",
|
||||
"title": "Απαιτείται επανεκκίνηση"
|
||||
},
|
||||
"unresponsive": {
|
||||
"buttons": {
|
||||
"quit": "Έξοδος",
|
||||
"relaunch": "Επανεκκίνηση",
|
||||
"wait": "Περιμένετε"
|
||||
},
|
||||
"detail": "Λυπούμαστε για την ταλαιπωρία! Παρακαλούμε επιλέξτε τι να κάνετε:",
|
||||
"message": "Η εφαρμογή δεν ανταποκρίνεται",
|
||||
"title": "Το παράθυρο δεν ανταποκρίνεται"
|
||||
},
|
||||
"update-available": {
|
||||
"buttons": {
|
||||
"download": "Download",
|
||||
"disable": "Απενεργοποίηση ενημερώσεων",
|
||||
"download": "Λήψη",
|
||||
"ok": "OK"
|
||||
}
|
||||
},
|
||||
"detail": "Μια νέα έκδοση είναι διαθέσιμη και μπορεί να ληφθεί από τον σύνδεσμο {{downloadLink}}",
|
||||
"message": "Μια νέα έκδοση είναι διαθέσιμη",
|
||||
"title": "Υπάρχει διαθέσιμη ενημέρωση"
|
||||
}
|
||||
},
|
||||
"menu": {
|
||||
"about": "Σχετικά",
|
||||
"navigation": {
|
||||
"label": "Navigation"
|
||||
"label": "Πλοήγηση",
|
||||
"submenu": {
|
||||
"copy-current-url": "Αντιγραφή τρέχουσας διεύθυνσης URL",
|
||||
"go-back": "Πήγαινε πίσω",
|
||||
"go-forward": "Πήγαινε μπροστά",
|
||||
"quit": "Έξοδος",
|
||||
"restart": "Επανεκκίνηση εφαρμογής"
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"label": "Options",
|
||||
"label": "Επιλογές",
|
||||
"submenu": {
|
||||
"advanced-options": {
|
||||
"label": "Προηγμένες επιλογές",
|
||||
"submenu": {
|
||||
"auto-reset-app-cache": "Επαναφορά της cache της εφαρμογής κατά την εκκίνηση της εφαρμογής",
|
||||
"disable-hardware-acceleration": "Απενεργοποίηση επιτάχυνσης υλικού",
|
||||
"edit-config-json": "Επεξεργασία του config.json",
|
||||
"override-user-agent": "Αντικατάσταση του User-Agent",
|
||||
"restart-on-config-changes": "Επανεκκίνηση κατά τις αλλαγές στο config",
|
||||
"set-proxy": {
|
||||
"label": "Set proxy",
|
||||
"label": "Ορισμός διακομιστή μεσολάβησης (proxy)",
|
||||
"prompt": {
|
||||
"title": "Set proxy"
|
||||
"label": "Εισαγωγή διεύθυνσης διακομιστή μεσολάβησης (proxy): (αφήστε κενό για απενεργοποίηση)",
|
||||
"placeholder": "Παράδειγμα: SOCKS5://127.0.0.1:9999",
|
||||
"title": "Ορισμός μεσολάβησης"
|
||||
}
|
||||
}
|
||||
},
|
||||
"toggle-dev-tools": "Εναλλαγή DevTools"
|
||||
}
|
||||
},
|
||||
"auto-update": "Auto Update",
|
||||
"language": {
|
||||
"label": "Γλώσσα"
|
||||
"always-on-top": "Πάντα επάνω",
|
||||
"auto-update": "Αυτόματη Ενημέρωση",
|
||||
"hide-menu": {
|
||||
"dialog": {
|
||||
"message": "Το μενού θα κρυφτεί στην επόμενη εκκίνηση, χρησιμοποιήστε [Alt] για να το εμφανίσετε (ή το πλήκτρο backtick [`] αν χρησιμοποιείτε το μενού εφαρμογής)",
|
||||
"title": "Η Δυνατότητα Απόκρυψης του Μενού ενεργοποιήθηκε"
|
||||
},
|
||||
"label": "Απόκρυψη Μενού"
|
||||
},
|
||||
"start-at-login": "Start at login",
|
||||
"tray": {
|
||||
"label": "Tray",
|
||||
"language": {
|
||||
"dialog": {
|
||||
"message": "Η γλώσσα θα αλλάξει μετά την επανεκκίνηση",
|
||||
"title": "Η γλώσσα άλλαξε"
|
||||
},
|
||||
"label": "Γλώσσα",
|
||||
"submenu": {
|
||||
"to-help-translate": "Θέλετε να βοηθήσετε στη μετάφραση; Κάντε κλικ εδώ"
|
||||
}
|
||||
},
|
||||
"resume-on-start": "Συνέχιση του τελευταίου τραγουδιού όταν η εφαρμογή ξεκινά",
|
||||
"single-instance-lock": "Κλείδωμα Μοναδικής Εκδοχής",
|
||||
"start-at-login": "Έναρξη κατά την σύνδεση",
|
||||
"starting-page": {
|
||||
"label": "Σελίδα έναρξης",
|
||||
"unset": "Κατάργηση ορισμού"
|
||||
},
|
||||
"tray": {
|
||||
"label": "Δίσκος",
|
||||
"submenu": {
|
||||
"disabled": "Απενεργοποιημένο",
|
||||
"enabled-and-hide-app": "Ενεργοποιημένο και απόκρυψη της εφαρμογής",
|
||||
"play-pause-on-click": "Play/Pause στο πάτημα"
|
||||
"enabled-and-show-app": "Ενεργοποιημένο και εμφάνιση της εφαρμογής",
|
||||
"play-pause-on-click": "Αναπαραγωγή/Παύση με κλικ"
|
||||
}
|
||||
},
|
||||
"visual-tweaks": {
|
||||
"label": "Τροποποιήσεις Εμφάνισης",
|
||||
"submenu": {
|
||||
"like-buttons": {
|
||||
"default": "Default"
|
||||
"default": "Default",
|
||||
"force-show": "Αναγκαστική Εμφάνιση",
|
||||
"hide": "Απόκρυψη",
|
||||
"label": "Μου αρέσει"
|
||||
},
|
||||
"remove-upgrade-button": "Αφαίρεση κουμπιού αναβάθμισης",
|
||||
"theme": {
|
||||
"label": "Theme",
|
||||
"dialog": {
|
||||
"button": {
|
||||
"cancel": "Άκυρο",
|
||||
"remove": "Αφαίρεση"
|
||||
},
|
||||
"remove-theme": "Είστε βέβαιοι ότι θέλετε να αφαιρέσετε το προσαρμοσμένο θέμα;",
|
||||
"remove-theme-message": "Αυτό θα αφαιρέσει το προσαρμοσμένο θέμα"
|
||||
},
|
||||
"label": "Θέμα",
|
||||
"submenu": {
|
||||
"import-css-file": "Εισαγωγή προσαρμοσμένου αρχείου CSS",
|
||||
"no-theme": "No theme"
|
||||
}
|
||||
}
|
||||
@ -68,29 +177,68 @@
|
||||
}
|
||||
},
|
||||
"plugins": {
|
||||
"label": "Plugins"
|
||||
"enabled": "Ενεργοποιημένο",
|
||||
"label": "Πρόσθετα",
|
||||
"new": "ΝΕΟ"
|
||||
},
|
||||
"view": {
|
||||
"label": "View"
|
||||
"label": "Προβολή",
|
||||
"submenu": {
|
||||
"force-reload": "Αναγκαστική Eπαναφόρτωση",
|
||||
"reload": "Επαναφόρτωση",
|
||||
"reset-zoom": "Πραγματικό μέγεθος",
|
||||
"toggle-fullscreen": "Εναλλαγή Πλήρους Οθόνης",
|
||||
"zoom-in": "Μεγέθυνση",
|
||||
"zoom-out": "Σμίκρυνση"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tray": {
|
||||
"next": "Επόμενο",
|
||||
"play-pause": "Αναπαραγωγή/Παύση",
|
||||
"previous": "Προηγούμενο",
|
||||
"quit": "Έξοδος",
|
||||
"restart": "Επανεκκίνηση εφαρμογής",
|
||||
"show": "Εμφάνιση παραθύρου",
|
||||
"tooltip": {
|
||||
"default": "YouTube Music",
|
||||
"with-song-info": "YouTube Music: {{artist}} - {{title}}"
|
||||
}
|
||||
}
|
||||
},
|
||||
"plugins": {
|
||||
"ad-speedup": {
|
||||
"description": "Εαν παίξει διαφήμιση κάνει σίγαση του ήχου και θέτει την ταχύτητα αναπαραγωγής στο 16x",
|
||||
"name": "Γρήγορη Προώθηση Διαφημίσεων"
|
||||
},
|
||||
"adblocker": {
|
||||
"description": "Αποκλεισμός όλων των διαφημίσεων και tracker",
|
||||
"menu": {
|
||||
"blocker": "Μέθοδος αποκλεισμού"
|
||||
},
|
||||
"name": "Adblocker"
|
||||
"name": "Μπλοκάρισμα Διαφημίσεων"
|
||||
},
|
||||
"album-actions": {
|
||||
"description": "Προσθέτει κουμπιά Like/Unlike και Dislike/Undislike που δρουν συνολικά σε όλα τα κομμάτια μιας playlist ή ενός άλμπουμ",
|
||||
"name": "Ενέργειες σε Άλμπουμ"
|
||||
},
|
||||
"album-color-theme": {
|
||||
"description": "Εφαρμόζει ένα δυναμικό θέμα και εφέ με βάση τη χρωματική παλέτα του άλμπουμ",
|
||||
"menu": {
|
||||
"color-mix-ratio": {
|
||||
"label": "Αναλογία μίξης χρώματος",
|
||||
"submenu": {
|
||||
"percent": "{{ratio}}%"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "Album Color Theme"
|
||||
},
|
||||
"ambient-mode": {
|
||||
"description": "Εφαρμόζει ένα εφέ φωτισμού ρίχνοντας απαλά χρώματα από το βίντεο, στο φόντο της οθόνης σας.",
|
||||
"menu": {
|
||||
"blur-amount": {
|
||||
"label": "Ένταση θαμπώματος",
|
||||
"submenu": {
|
||||
"pixels": "{{blurAmount}} pixels"
|
||||
}
|
||||
@ -102,25 +250,30 @@
|
||||
}
|
||||
},
|
||||
"opacity": {
|
||||
"label": "Ποσότητα αδιαφάνειας",
|
||||
"label": "Αδιαφάνεια",
|
||||
"submenu": {
|
||||
"percent": "{{opacity}}%"
|
||||
}
|
||||
},
|
||||
"quality": {
|
||||
"label": "Ποιότητα",
|
||||
"submenu": {
|
||||
"pixels": "{{quality}} pixels"
|
||||
}
|
||||
},
|
||||
"size": {
|
||||
"label": "Μέγεθος",
|
||||
"submenu": {
|
||||
"percent": "{{size}}%"
|
||||
}
|
||||
},
|
||||
"smoothness-transition": {
|
||||
"submenu": {
|
||||
"during": "Σε {{interpolationTime}} δεύτερα"
|
||||
"during": "Σε {{interpolationTime}} δευτερόλεπτα"
|
||||
}
|
||||
},
|
||||
"use-fullscreen": {
|
||||
"label": "Χρήση πλήρους οθόνης"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -162,11 +315,14 @@
|
||||
"description": "Κάνει τα τραγούδια να είναι αυτόματα σε παύση",
|
||||
"menu": {
|
||||
"apply-once": "Εφαρμόζεται μόνο στο πρώτο τραγούδι"
|
||||
}
|
||||
},
|
||||
"name": "Απενεργοποίηση αυτόματης αναπαραγωγής"
|
||||
},
|
||||
"discord": {
|
||||
"description": "Δείξτε στους φίλους σας τι ακούτε με το Rich Presence",
|
||||
"menu": {
|
||||
"auto-reconnect": "Αυτόματη επανασύνδεση",
|
||||
"clear-activity": "Εκκαθάριση δραστηριότητας",
|
||||
"hide-duration-left": "Απόκρυψη της διάρκειας που απομένει",
|
||||
"hide-github-button": "Απόκρυψη του συνδέσμου προς GitHub",
|
||||
"set-inactivity-timeout": "Ορισμός χρονικού ορίου αδράνειας"
|
||||
@ -185,34 +341,113 @@
|
||||
"buttons": {
|
||||
"ok": "OK"
|
||||
},
|
||||
"message": "Λήψη λίστας αναπαραγωγής {{playlistTitle}}",
|
||||
"title": "Λήψη ξεκίνησε"
|
||||
"detail": "{{playlistSize}} τραγούδια)",
|
||||
"message": "Λήψη της λίστας αναπαραγωγής {{playlistTitle}}",
|
||||
"title": "Η λήψη ξεκίνησε"
|
||||
}
|
||||
},
|
||||
"feedback": {
|
||||
"conversion-progress": "Μετατροπή: {{percent}}%",
|
||||
"download-progress": "Download: {{percent}}%",
|
||||
"preparing-file": "Προετοιμασία αρχείου…"
|
||||
"converting": "Μετατροπή…",
|
||||
"download-info": "Λήψη του {{artist}} - {{title}} [{{videoId}}",
|
||||
"download-progress": "Λήψη: {{percent}}%",
|
||||
"downloading": "Λήψη…",
|
||||
"downloading-counter": "Λήψη {{current}}/{{total}}…",
|
||||
"downloading-playlist": "Λήψη της λίστας αναπαραγωγής \"{{playlistTitle}}\" - {{playlistSize}} τραγούδια ({{playlistId}})",
|
||||
"folder-already-exists": "Ο φάκελος {{playlistFolder}} υπάρχει ήδη",
|
||||
"loading": "Φόρτωση…",
|
||||
"playlist-is-empty": "Η λίστα αναπραγωγής είναι άδεια",
|
||||
"preparing-file": "Προετοιμασία αρχείου…",
|
||||
"saving": "Αποθήκευση…",
|
||||
"video-id-not-found": "Το βίντεο δεν βρέθηκε"
|
||||
}
|
||||
},
|
||||
"menu": {
|
||||
"download-finish-settings": {
|
||||
"prompt": {
|
||||
"last-seconds": "Τελευταία x δευτερόλεπτα"
|
||||
},
|
||||
"submenu": {
|
||||
"percent": "Ποσοστό",
|
||||
"seconds": "Δευτερόλεπτα"
|
||||
}
|
||||
},
|
||||
"download-playlist": "Λήψη λίστας αναπαραγωγής",
|
||||
"skip-existing": "Παράλειψη υπάρχοντων αρχείων"
|
||||
},
|
||||
"templates": {
|
||||
"button": "Download"
|
||||
"button": "Λήψη"
|
||||
}
|
||||
},
|
||||
"music-together": {
|
||||
"internal": {
|
||||
"save": "Αποθήκευση",
|
||||
"unknown-user": "Άγνωστος χρήστης"
|
||||
},
|
||||
"menu": {
|
||||
"connected-users": "Συνδεδεμένοι χρήστες"
|
||||
},
|
||||
"toast": {
|
||||
"add-song-failed": "Απέτυχε η προσθήκη τραγουδιού",
|
||||
"remove-song-failed": "Απέτυχε η αφαίρεση τραγουδιού"
|
||||
}
|
||||
},
|
||||
"navigation": {
|
||||
"name": "Navigation"
|
||||
"name": "Πλοήγηση"
|
||||
},
|
||||
"no-google-login": {
|
||||
"name": "No Google Login"
|
||||
},
|
||||
"notifications": {
|
||||
"name": "Notifications"
|
||||
"name": "Ειδοποιήσεις"
|
||||
},
|
||||
"picture-in-picture": {
|
||||
"menu": {
|
||||
"always-on-top": "Πάντα σε πρώτο πλάνο",
|
||||
"hotkey": {
|
||||
"label": "Πλήκτρο πρόσβασης",
|
||||
"prompt": {
|
||||
"keybind-options": {
|
||||
"hotkey": "Πλήκτρο πρόσβασης"
|
||||
}
|
||||
}
|
||||
},
|
||||
"save-window-position": "Αποθήκευση θέσης παραθύρου",
|
||||
"save-window-size": "Αποθήκευση μεγέθους παραθύρου"
|
||||
}
|
||||
},
|
||||
"playback-speed": {
|
||||
"name": "Ταχύτητα αναπαραγωγής",
|
||||
"templates": {
|
||||
"button": "Ταχύτητα"
|
||||
}
|
||||
},
|
||||
"precise-volume": {
|
||||
"prompt": {
|
||||
"global-shortcuts": {
|
||||
"keybind-options": {
|
||||
"decrease": "Μείωση έντασης",
|
||||
"increase": "Αύξηση έντασης"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"quality-changer": {
|
||||
"backend": {
|
||||
"dialog": {
|
||||
"quality-changer": {
|
||||
"detail": "Τρέχουσα ποιότητα: {{quality}}"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"shortcuts": {
|
||||
"prompt": {
|
||||
"keybind": {
|
||||
"keybind-options": {
|
||||
"next": "Next"
|
||||
"next": "Επόμενο",
|
||||
"play-pause": "Αναπαραγωγή / Παύση",
|
||||
"previous": "Προηγούμενο"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -158,6 +158,14 @@
|
||||
},
|
||||
"remove-upgrade-button": "Remove upgrade button",
|
||||
"theme": {
|
||||
"dialog": {
|
||||
"button": {
|
||||
"cancel": "Cancel",
|
||||
"remove": "Remove"
|
||||
},
|
||||
"remove-theme": "Are you sure you want to remove the custom theme?",
|
||||
"remove-theme-message": "This will remove the custom theme"
|
||||
},
|
||||
"label": "Theme",
|
||||
"submenu": {
|
||||
"import-css-file": "Import custom CSS file",
|
||||
@ -199,6 +207,10 @@
|
||||
}
|
||||
},
|
||||
"plugins": {
|
||||
"ad-speedup": {
|
||||
"description": "If an ad play it mutes the audio and sets playback speed to 16x",
|
||||
"name": "Ad Speedup"
|
||||
},
|
||||
"adblocker": {
|
||||
"description": "Block all ads and tracking out of the box",
|
||||
"menu": {
|
||||
@ -212,7 +224,6 @@
|
||||
},
|
||||
"album-color-theme": {
|
||||
"description": "Applies a dynamic theme and visual effects based on the album color palette",
|
||||
"name": "Album Color Theme",
|
||||
"menu": {
|
||||
"color-mix-ratio": {
|
||||
"label": "Color mix ratio",
|
||||
@ -220,7 +231,8 @@
|
||||
"percent": "{{ratio}}%"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "Album Color Theme"
|
||||
},
|
||||
"ambient-mode": {
|
||||
"description": "Applies a lighting effect by casting gentle colors from the video, into your screen’s background",
|
||||
@ -267,6 +279,49 @@
|
||||
},
|
||||
"name": "Ambient Mode"
|
||||
},
|
||||
"api-server": {
|
||||
"description": "Adds an API server to control the player",
|
||||
"dialog": {
|
||||
"request": {
|
||||
"buttons": {
|
||||
"allow": "Allow",
|
||||
"deny": "Deny"
|
||||
},
|
||||
"message": "Allow {{ID}} ({{origin}}) to access the API?",
|
||||
"title": "API authorization request"
|
||||
}
|
||||
},
|
||||
"menu": {
|
||||
"auth-strategy": {
|
||||
"label": "Authorization strategy",
|
||||
"submenu": {
|
||||
"auth-at-first": {
|
||||
"label": "Authorize at first request"
|
||||
},
|
||||
"none": {
|
||||
"label": "No authorization"
|
||||
}
|
||||
}
|
||||
},
|
||||
"hostname": {
|
||||
"label": "Hostname"
|
||||
},
|
||||
"port": {
|
||||
"label": "Port"
|
||||
}
|
||||
},
|
||||
"name": "API Server [Beta]",
|
||||
"prompt": {
|
||||
"hostname": {
|
||||
"label": "Enter the hostname (like 0.0.0.0) for the API server:",
|
||||
"title": "Hostname"
|
||||
},
|
||||
"port": {
|
||||
"label": "Enter the port for the API server:",
|
||||
"title": "Port"
|
||||
}
|
||||
}
|
||||
},
|
||||
"audio-compressor": {
|
||||
"description": "Apply compression to audio (lowers the volume of the loudest parts of the signal and raises the volume of the softest parts)",
|
||||
"name": "Audio Compressor"
|
||||
@ -402,6 +457,21 @@
|
||||
"description": "Downloads MP3 / source audio directly from the interface",
|
||||
"menu": {
|
||||
"choose-download-folder": "Choose download folder",
|
||||
"download-finish-settings": {
|
||||
"label": "Download on finish",
|
||||
"prompt": {
|
||||
"last-percent": "After x percent",
|
||||
"last-seconds": "Last x seconds",
|
||||
"title": "Configure when to download"
|
||||
},
|
||||
"submenu": {
|
||||
"advanced": "Advanced",
|
||||
"enabled": "Enabled",
|
||||
"mode": "Time mode",
|
||||
"percent": "Percent",
|
||||
"seconds": "Seconds"
|
||||
}
|
||||
},
|
||||
"download-playlist": "Download playlist",
|
||||
"presets": "Presets",
|
||||
"skip-existing": "Skip existing files"
|
||||
@ -582,19 +652,19 @@
|
||||
"dialog": {
|
||||
"lastfm": {
|
||||
"auth-failed": {
|
||||
"title": "Authentication Failed",
|
||||
"message": "Failed to authenticate with Last.fm\nHide the popup until the next restart."
|
||||
"message": "Failed to authenticate with Last.fm\nHide the popup until the next restart.",
|
||||
"title": "Authentication Failed"
|
||||
}
|
||||
}
|
||||
},
|
||||
"menu": {
|
||||
"scrobble-other-media": "Scrobble other media",
|
||||
"lastfm": {
|
||||
"api-settings": "Last.fm API Settings"
|
||||
},
|
||||
"listenbrainz": {
|
||||
"token": "Enter ListenBrainz user token"
|
||||
}
|
||||
},
|
||||
"scrobble-other-media": "Scrobble other media"
|
||||
},
|
||||
"name": "Scrobbler",
|
||||
"prompt": {
|
||||
@ -641,6 +711,59 @@
|
||||
"description": "Automatically Skips non-music parts like intro/outro or parts of music videos where the song isn't playing",
|
||||
"name": "SponsorBlock"
|
||||
},
|
||||
"synced-lyrics": {
|
||||
"description": "Provides synced lyrics to songs, using providers like LRClib.",
|
||||
"errors": {
|
||||
"fetch": "⚠️ - An error occurred while fetching the lyrics. Please try again later.",
|
||||
"not-found": "⚠️ - No lyrics found for this song."
|
||||
},
|
||||
"menu": {
|
||||
"default-text-string": {
|
||||
"label": "Default character between lyrics",
|
||||
"tooltip": "Choose the default character to use for the gap between lyrics"
|
||||
},
|
||||
"line-effect": {
|
||||
"label": "Line effect",
|
||||
"submenu": {
|
||||
"focus": {
|
||||
"label": "Focus",
|
||||
"tooltip": "Make only the current line white"
|
||||
},
|
||||
"offset": {
|
||||
"label": "Offset",
|
||||
"tooltip": "Offset on the right the current line"
|
||||
},
|
||||
"scale": {
|
||||
"label": "Scale",
|
||||
"tooltip": "Scale the current line"
|
||||
}
|
||||
},
|
||||
"tooltip": "Choose the effect to apply to the current line"
|
||||
},
|
||||
"precise-timing": {
|
||||
"label": "Make the lyrics perfectly synced",
|
||||
"tooltip": "Calculate to the milisecond the display of the next line (can have a small impact on performance)"
|
||||
},
|
||||
"show-lyrics-even-if-inexact": {
|
||||
"label": "Show lyrics even if inexact",
|
||||
"tooltip": "If the song is not found, the plugin tries again with a different search query.\nThe result from the second attempt may not be exact."
|
||||
},
|
||||
"show-time-codes": {
|
||||
"label": "Show time codes",
|
||||
"tooltip": "Show the time codes next to the lyrics"
|
||||
}
|
||||
},
|
||||
"name": "Synced Lyrics",
|
||||
"refetch-btn": {
|
||||
"fetching": "Fetching...",
|
||||
"normal": "Refetch lyrics"
|
||||
},
|
||||
"warnings": {
|
||||
"duration-mismatch": "⚠️ - The lyrics may be out of sync due to a duration mismatch.",
|
||||
"inexact": "⚠️ - The lyrics for this song may not be exact",
|
||||
"instrumental": "⚠️ - This is an instrumental song"
|
||||
}
|
||||
},
|
||||
"taskbar-mediacontrol": {
|
||||
"description": "Control playback from your Windows taskbar",
|
||||
"name": "Taskbar Media Control"
|
||||
|
||||
@ -158,6 +158,14 @@
|
||||
},
|
||||
"remove-upgrade-button": "Remover el botón de Actualización",
|
||||
"theme": {
|
||||
"dialog": {
|
||||
"button": {
|
||||
"cancel": "Cancelar",
|
||||
"remove": "Quitar"
|
||||
},
|
||||
"remove-theme": "¿Estás seguro de que quieres eliminar el tema personalizado?",
|
||||
"remove-theme-message": "Esto eliminará el tema personalizado"
|
||||
},
|
||||
"label": "Tema",
|
||||
"submenu": {
|
||||
"import-css-file": "Importar archivo CSS personalizado",
|
||||
@ -199,6 +207,10 @@
|
||||
}
|
||||
},
|
||||
"plugins": {
|
||||
"ad-speedup": {
|
||||
"description": "Si se reproduce un anuncio, silencia el audio y fija la velocidad de reproducción en 16x",
|
||||
"name": "Aumento de la velocidad de anuncios"
|
||||
},
|
||||
"adblocker": {
|
||||
"description": "Bloquear todos los anuncios y el rastreo",
|
||||
"menu": {
|
||||
@ -267,6 +279,49 @@
|
||||
},
|
||||
"name": "Modo ambiente"
|
||||
},
|
||||
"api-server": {
|
||||
"description": "Añade un servidor API para controlar el reproductor",
|
||||
"dialog": {
|
||||
"request": {
|
||||
"buttons": {
|
||||
"allow": "Permitir",
|
||||
"deny": "Denegar"
|
||||
},
|
||||
"message": "¿Permitir {{ID}} ({{origin}}) acceder a la API?",
|
||||
"title": "Petición de autorización API"
|
||||
}
|
||||
},
|
||||
"menu": {
|
||||
"auth-strategy": {
|
||||
"label": "Estrategia de autorización",
|
||||
"submenu": {
|
||||
"auth-at-first": {
|
||||
"label": "Autorizar la primera solicitud"
|
||||
},
|
||||
"none": {
|
||||
"label": "Sin autorización"
|
||||
}
|
||||
}
|
||||
},
|
||||
"hostname": {
|
||||
"label": "Nombre del host"
|
||||
},
|
||||
"port": {
|
||||
"label": "Puerto"
|
||||
}
|
||||
},
|
||||
"name": "Servidor API [Beta]",
|
||||
"prompt": {
|
||||
"hostname": {
|
||||
"label": "Introduzca el nombre de host (como 0.0.0.0) para el servidor API:",
|
||||
"title": "Nombre de host"
|
||||
},
|
||||
"port": {
|
||||
"label": "Introduzca el puerto para el servidor API:",
|
||||
"title": "Puerto"
|
||||
}
|
||||
}
|
||||
},
|
||||
"audio-compressor": {
|
||||
"description": "Aplicar compresión al audio (reduce la diferencia entre las partes más fuertes y más suaves de una pista para que tenga un nivel más consistente)",
|
||||
"name": "Compresor de audio"
|
||||
@ -402,6 +457,21 @@
|
||||
"description": "Descarga MP3 / audio fuente directamente desde la interfaz",
|
||||
"menu": {
|
||||
"choose-download-folder": "Elija la carpeta de descarga",
|
||||
"download-finish-settings": {
|
||||
"label": "Descargar al finalizar",
|
||||
"prompt": {
|
||||
"last-percent": "Después del x por ciento",
|
||||
"last-seconds": "Últimos x segundos",
|
||||
"title": "Configurar cuándo descargar"
|
||||
},
|
||||
"submenu": {
|
||||
"advanced": "Avanzado",
|
||||
"enabled": "Activado",
|
||||
"mode": "Modo de tiempo",
|
||||
"percent": "Porcentaje",
|
||||
"seconds": "Segundos"
|
||||
}
|
||||
},
|
||||
"download-playlist": "Descargar lista de reproducción",
|
||||
"presets": "Preajustes",
|
||||
"skip-existing": "Saltar archivos existentes"
|
||||
@ -641,6 +711,59 @@
|
||||
"description": "Salta automáticamente las partes no musicales como la introducción/final o secciones de videos musicales donde la canción no está sonando",
|
||||
"name": "SponsorBlock"
|
||||
},
|
||||
"synced-lyrics": {
|
||||
"description": "Proporciona letras de canciones sincronizadas, utilizando proveedores como LRClib.",
|
||||
"errors": {
|
||||
"fetch": "⚠️ - Se ha producido un error al descargar la letra. Por favor, vuelve a intentarlo más tarde.",
|
||||
"not-found": "⚠️ - No se ha encontrado ninguna letra para esta canción."
|
||||
},
|
||||
"menu": {
|
||||
"default-text-string": {
|
||||
"label": "Carácter predeterminado entre letras",
|
||||
"tooltip": "Elige el carácter predeterminado que se utilizará para el espacio entre letras"
|
||||
},
|
||||
"line-effect": {
|
||||
"label": "Efecto de la línea",
|
||||
"submenu": {
|
||||
"focus": {
|
||||
"label": "Enfoque",
|
||||
"tooltip": "Mostrar solo la línea actual en blanco"
|
||||
},
|
||||
"offset": {
|
||||
"label": "Desplazamiento",
|
||||
"tooltip": "Desplazamiento a la derecha de la línea actual"
|
||||
},
|
||||
"scale": {
|
||||
"label": "Escala",
|
||||
"tooltip": "Escala de la línea actual"
|
||||
}
|
||||
},
|
||||
"tooltip": "Elige el efecto que deseas aplicar a la línea actual"
|
||||
},
|
||||
"precise-timing": {
|
||||
"label": "Haz que la letra esté perfectamente sincronizada",
|
||||
"tooltip": "Calcular al milisegundo la visualización de la línea siguiente (puede tener un pequeño impacto en el rendimiento)"
|
||||
},
|
||||
"show-lyrics-even-if-inexact": {
|
||||
"label": "Mostrar la letra aunque sea inexacta",
|
||||
"tooltip": "Si no se encuentra la canción, el complemento vuelve a intentarlo con una búsqueda diferente.\nEl resultado del segundo intento puede no ser exacto."
|
||||
},
|
||||
"show-time-codes": {
|
||||
"label": "Visualización del código de tiempo",
|
||||
"tooltip": "Mostrar los códigos de tiempo junto a la letra"
|
||||
}
|
||||
},
|
||||
"name": "Letras sincronizadas",
|
||||
"refetch-btn": {
|
||||
"fetching": "Recuperando...",
|
||||
"normal": "Volver a buscar letras"
|
||||
},
|
||||
"warnings": {
|
||||
"duration-mismatch": "⚠️ - La letra puede estar desincronizada debido a un desajuste en la duración.",
|
||||
"inexact": "⚠️ - La letra de esta canción puede no ser exacta",
|
||||
"instrumental": "⚠️ - Se trata de una canción instrumental"
|
||||
}
|
||||
},
|
||||
"taskbar-mediacontrol": {
|
||||
"description": "Controla la reproducción desde la barra de tareas de Windows",
|
||||
"name": "Control de medios de la barra de tareas"
|
||||
|
||||
182
src/i18n/resources/et.json
Normal file
182
src/i18n/resources/et.json
Normal file
@ -0,0 +1,182 @@
|
||||
{
|
||||
"common": {
|
||||
"console": {
|
||||
"plugins": {
|
||||
"execute-failed": "{{pluginName}}::{{contextName}} lisamooduli käivitamine ei õnnestunud",
|
||||
"executed-at-ms": "{{pluginName}}::{{contextName}} lisamoodul käivitus {{ms}} millisekundiga",
|
||||
"initialize-failed": "„{{pluginName}}“ lisamooduli töö alustamine ei õnnestunud",
|
||||
"load-all": "Laadime kõiki lisamooduleid",
|
||||
"load-failed": "„{{pluginName}}“ lisamooduli laadimine ei õnnestunud",
|
||||
"loaded": "„{{pluginName}}“ lisamoodul on laaditud",
|
||||
"unload-failed": "„{{pluginName}}“ lisamooduli mälust eemaldamine ei õnnestunud",
|
||||
"unloaded": "„{{pluginName}}“ lisamoodul on mälust eemaldatud"
|
||||
}
|
||||
}
|
||||
},
|
||||
"language": {
|
||||
"code": "et",
|
||||
"local-name": "Eesti",
|
||||
"name": "Estonian"
|
||||
},
|
||||
"main": {
|
||||
"console": {
|
||||
"did-finish-load": {
|
||||
"dev-tools": "Laadimine lõppes, arendaja tarvikud on avatud"
|
||||
},
|
||||
"i18n": {
|
||||
"loaded": "i18n on laaditud"
|
||||
},
|
||||
"second-instance": {
|
||||
"receive-command": "„{{command}}“ käsk on vastu võetud"
|
||||
},
|
||||
"theme": {
|
||||
"css-file-not-found": "CSS faili „{{cssFile}}“ pole olemas, seega eirame eelistust"
|
||||
}
|
||||
},
|
||||
"dialog": {
|
||||
"hide-menu-enabled": {
|
||||
"detail": "Menüü on peidetud ja „Alt“ klahviga saad ta nähtavaks (rakenduse-siseses menüüs „Esc“ klahviga)",
|
||||
"message": "Menüü peitmine on sisselülitatud",
|
||||
"title": "Menüü peitmine on sisselülitatud"
|
||||
},
|
||||
"need-to-restart": {
|
||||
"buttons": {
|
||||
"later": "Hiljem",
|
||||
"restart-now": "Taaskäivita kohe"
|
||||
},
|
||||
"detail": "„{{pluginName}}“ lisamooduli sisselülitamine eeldab rakenduse taaskäivitamist",
|
||||
"message": "„{{pluginName}}“ lisamoodul eeldab rakenduse taaskäivitamist",
|
||||
"title": "Palun käivita rakendus uuesti"
|
||||
},
|
||||
"unresponsive": {
|
||||
"buttons": {
|
||||
"quit": "Välju",
|
||||
"relaunch": "Käivita uuesti",
|
||||
"wait": "Oota"
|
||||
}
|
||||
}
|
||||
},
|
||||
"menu": {
|
||||
"navigation": {
|
||||
"label": "Liikumine",
|
||||
"submenu": {
|
||||
"copy-current-url": "Kopeeri esitamisel oleva pala URL",
|
||||
"go-back": "Mine tagasi",
|
||||
"go-forward": "Mine edasi",
|
||||
"quit": "Välju",
|
||||
"restart": "Käivita rakendus uuesti"
|
||||
}
|
||||
},
|
||||
"plugins": {
|
||||
"label": "Lisamoodulid",
|
||||
"new": "UUS"
|
||||
},
|
||||
"view": {
|
||||
"submenu": {
|
||||
"zoom-in": "Suumi sisse",
|
||||
"zoom-out": "Suumi välja"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tray": {
|
||||
"next": "Edasi",
|
||||
"play-pause": "Esita/Peata esitus",
|
||||
"previous": "Eelmine",
|
||||
"quit": "Välju",
|
||||
"restart": "Käivita rakendus uuesti",
|
||||
"show": "Näita akent",
|
||||
"tooltip": {
|
||||
"default": "YouTube Music",
|
||||
"with-song-info": "YouTube Music: {{artist}} - {{title}}"
|
||||
}
|
||||
}
|
||||
},
|
||||
"plugins": {
|
||||
"ad-speedup": {
|
||||
"description": "Reklaami esitamisel summutatakse heli ja keritakse edasi 16-kordse kiirusega",
|
||||
"name": "Reklaamikiirendaja"
|
||||
},
|
||||
"adblocker": {
|
||||
"description": "Blokeeri kõik reklaamid ja jälitajad",
|
||||
"menu": {
|
||||
"blocker": "Blokeerijad"
|
||||
},
|
||||
"name": "Reklaamiblokeerija"
|
||||
},
|
||||
"ambient-mode": {
|
||||
"menu": {
|
||||
"opacity": {
|
||||
"submenu": {
|
||||
"percent": "{{opacity}}%"
|
||||
}
|
||||
},
|
||||
"quality": {
|
||||
"label": "Kvaliteet",
|
||||
"submenu": {
|
||||
"pixels": "{{quality}} pikslit"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"blur-nav-bar": {
|
||||
"description": "Muudab navigatsiooniriba läbipaistavaks ja hägusaks",
|
||||
"name": "Hägus navigatsiooniriba"
|
||||
},
|
||||
"lyrics-genius": {
|
||||
"description": "Lisa enamustele lugudele laulusõnad",
|
||||
"menu": {
|
||||
"romanized-lyrics": "Latiniseeritud laulusõnad"
|
||||
},
|
||||
"name": "Lyrics Genius",
|
||||
"renderer": {
|
||||
"fetched-lyrics": "Leidsime Geeniuse jaoks ühed laulusõnad"
|
||||
}
|
||||
},
|
||||
"navigation": {
|
||||
"name": "Liikumine"
|
||||
},
|
||||
"scrobbler": {
|
||||
"description": "Lisa kraasimise tugi (last.fm, Listenbrainz, jne)",
|
||||
"dialog": {
|
||||
"lastfm": {
|
||||
"auth-failed": {
|
||||
"message": "Last.fm'i autentimine ei õnnestunud\nPeida hüpikaken järgmise taaskäivituseni.",
|
||||
"title": "Autentimine ei õnnestunud"
|
||||
}
|
||||
}
|
||||
},
|
||||
"menu": {
|
||||
"lastfm": {
|
||||
"api-settings": "Last.fm API seadistused"
|
||||
},
|
||||
"listenbrainz": {
|
||||
"token": "Sisesta ListenBrainz'i kasutaja tunnusluba"
|
||||
},
|
||||
"scrobble-other-media": "Kraasi muud meediat"
|
||||
},
|
||||
"name": "Kraasija",
|
||||
"prompt": {
|
||||
"lastfm": {
|
||||
"api-key": "Last.fm API võti",
|
||||
"api-secret": "Last.fm API saladus"
|
||||
},
|
||||
"listenbrainz": {
|
||||
"token": {
|
||||
"label": "Sisesta oma ListenBrainz'i tunnusluba:",
|
||||
"title": "ListenBrainz'i tunnusluba"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"synced-lyrics": {
|
||||
"menu": {
|
||||
"show-lyrics-even-if-inexact": {
|
||||
"tooltip": "Kui lugu ei leidu, siis lisamoodul üritab uut otsingut teistsuguse päringuga.\nTeise katse puhul tulemused ei pruugi olla väga täpsed."
|
||||
}
|
||||
}
|
||||
},
|
||||
"tuna-obs": {
|
||||
"description": "Lõimimine OBSi Tuna lisamooduliga"
|
||||
}
|
||||
}
|
||||
}
|
||||
397
src/i18n/resources/fa.json
Normal file
397
src/i18n/resources/fa.json
Normal file
@ -0,0 +1,397 @@
|
||||
{
|
||||
"common": {
|
||||
"console": {
|
||||
"plugins": {
|
||||
"execute-failed": "اجرای افزونه {{pluginName}}::{{contextName}} با خطا مواجه شد",
|
||||
"executed-at-ms": "افزونه {{pluginName}}::{{contextName}} در {{ms}} میلیثانیه اجرا شد",
|
||||
"initialize-failed": "افزونه \"{{pluginName}}\" با خطا در حین مقداردهی اولیه مواجه شد",
|
||||
"load-all": "در حال بارگذاری تمامی افزونهها",
|
||||
"load-failed": "افزونه \"{{pluginName}}\" بارگیری نشد",
|
||||
"loaded": "افزونه \"{{pluginName}}\" بارگیری شد",
|
||||
"unload-failed": "افزونه \"{{pluginName}}\" بارگذاری نشد",
|
||||
"unloaded": "افزونه \"{{pluginName}}\" بارگذاری شد"
|
||||
}
|
||||
}
|
||||
},
|
||||
"language": {
|
||||
"code": "fa",
|
||||
"local-name": "فارسی",
|
||||
"name": "Persian"
|
||||
},
|
||||
"main": {
|
||||
"console": {
|
||||
"did-finish-load": {
|
||||
"dev-tools": "بارگذاری کامل شد. DevTools باز شد"
|
||||
},
|
||||
"i18n": {
|
||||
"loaded": "i18n بارگذاری شد"
|
||||
},
|
||||
"second-instance": {
|
||||
"receive-command": "دریافت فرمان از طریق پروتکل: \"{{command}}\""
|
||||
},
|
||||
"theme": {
|
||||
"css-file-not-found": "فایل CSS \"{{cssFile}}\" وجود ندارد، نادیده گرفته شد"
|
||||
},
|
||||
"unresponsive": {
|
||||
"details": "خطای عدم پاسخگویی!\n{{error}}"
|
||||
},
|
||||
"when-ready": {
|
||||
"clearing-cache-after-20s": "پاکسازی حافظه کش برنامه"
|
||||
},
|
||||
"window": {
|
||||
"tried-to-render-offscreen": "پنجره تلاش کرد خارج از صفحه نمایش داده شود، اندازه پنجره={{windowSize}}، اندازه نمایشگر={{displaySize}}، موقعیت={{position}}"
|
||||
}
|
||||
},
|
||||
"dialog": {
|
||||
"hide-menu-enabled": {
|
||||
"detail": "منو مخفی است، از 'Alt' برای نمایش آن استفاده کنید (یا 'Escape' اگر از منوی داخل برنامه استفاده میکنید)",
|
||||
"message": "پنهانسازی منو فعال است",
|
||||
"title": "پنهان کردن منو فعال شد"
|
||||
},
|
||||
"need-to-restart": {
|
||||
"buttons": {
|
||||
"later": "بعداً",
|
||||
"restart-now": "هماکنون راهاندازی مجدد کنید"
|
||||
},
|
||||
"detail": "افزونه \"{{pluginName}}\" برای اعمال تغییرات نیاز به راهاندازی مجدد دارد",
|
||||
"message": "\"{{pluginName}}\" نیاز به راهاندازی مجدد دارد",
|
||||
"title": "نیاز به راهاندازی مجدد"
|
||||
},
|
||||
"unresponsive": {
|
||||
"buttons": {
|
||||
"quit": "خروج",
|
||||
"relaunch": "راهاندازی مجدد",
|
||||
"wait": "منتظر بمانید"
|
||||
},
|
||||
"detail": "از بابت این مشکل متأسفیم! لطفاً انتخاب کنید که چه کاری انجام دهید:",
|
||||
"message": "برنامه پاسخی نمیدهد",
|
||||
"title": "پنجره بدون پاسخ"
|
||||
},
|
||||
"update-available": {
|
||||
"buttons": {
|
||||
"disable": "غیرفعال کردن بهروزرسانیها",
|
||||
"download": "دانلود",
|
||||
"ok": "تأیید"
|
||||
},
|
||||
"detail": "نسخه جدیدی در دسترس است و میتوان آن را از {{downloadLink}} دانلود کرد",
|
||||
"message": "نسخه جدیدی در دسترس است",
|
||||
"title": "بهروزرسانی موجود است"
|
||||
}
|
||||
},
|
||||
"menu": {
|
||||
"about": "درباره",
|
||||
"navigation": {
|
||||
"label": "ناوبری",
|
||||
"submenu": {
|
||||
"copy-current-url": "کپی کردن URL فعلی",
|
||||
"go-back": "بازگشت",
|
||||
"go-forward": "حرکت به جلو",
|
||||
"quit": "خروجی",
|
||||
"restart": "راهاندازی مجدد برنامه"
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"label": "گزینهها",
|
||||
"submenu": {
|
||||
"advanced-options": {
|
||||
"label": "گزینههای پیشرفته",
|
||||
"submenu": {
|
||||
"auto-reset-app-cache": "ریست کردن حافظه کش برنامه هنگام شروع",
|
||||
"disable-hardware-acceleration": "غیرفعال کردن شتاب سختافزاری",
|
||||
"edit-config-json": "ویرایش config.json",
|
||||
"override-user-agent": "تغییر User-Agent",
|
||||
"restart-on-config-changes": "راهاندازی مجدد در صورت تغییرات در پیکربندی",
|
||||
"set-proxy": {
|
||||
"label": "تنظیم پراکسی",
|
||||
"prompt": {
|
||||
"label": "آدرس پراکسی را وارد کنید: (برای غیرفعال کردن، خالی بگذارید)",
|
||||
"placeholder": "مثال: SOCKS5://127.0.0.1:9999",
|
||||
"title": "تنظیم پراکسی"
|
||||
}
|
||||
},
|
||||
"toggle-dev-tools": "باز کردن DevTools"
|
||||
}
|
||||
},
|
||||
"always-on-top": "همیشه در بالا",
|
||||
"auto-update": "بهروزرسانی خودکار",
|
||||
"hide-menu": {
|
||||
"dialog": {
|
||||
"message": "منو در اجرای بعدی مخفی خواهد بود، از [Alt] برای نمایش استفاده کنید (یا [`] اگر از منوی داخل برنامه استفاده میکنید)",
|
||||
"title": "پنهانسازی منو فعال شد"
|
||||
},
|
||||
"label": "پنهان کردن منو"
|
||||
},
|
||||
"language": {
|
||||
"dialog": {
|
||||
"message": "زبان پس از راهاندازی مجدد تغییر خواهد کرد",
|
||||
"title": "زبان تغییر کرد"
|
||||
},
|
||||
"label": "زبان",
|
||||
"submenu": {
|
||||
"to-help-translate": "میخواهید به ترجمه کمک کنید؟ اینجا کلیک کنید"
|
||||
}
|
||||
},
|
||||
"resume-on-start": "ادامه آخرین آهنگ هنگام شروع برنامه",
|
||||
"single-instance-lock": "قفل تنها یک نمونه",
|
||||
"start-at-login": "شروع هنگام ورود",
|
||||
"starting-page": {
|
||||
"label": "صفحه شروع",
|
||||
"unset": "لغو تنظیم"
|
||||
},
|
||||
"tray": {
|
||||
"label": "نوار",
|
||||
"submenu": {
|
||||
"disabled": "غیرفعال",
|
||||
"enabled-and-hide-app": "فعال و پنهان کردن برنامه",
|
||||
"enabled-and-show-app": "فعال و نمایش برنامه",
|
||||
"play-pause-on-click": "پخش/توقف با کلیک"
|
||||
}
|
||||
},
|
||||
"visual-tweaks": {
|
||||
"label": "تغییرات ظاهری",
|
||||
"submenu": {
|
||||
"like-buttons": {
|
||||
"default": "پیشفرض",
|
||||
"force-show": "اجبار به نمایش",
|
||||
"hide": "پنهان کردن",
|
||||
"label": "دکمههای پسندیدن"
|
||||
},
|
||||
"remove-upgrade-button": "حذف دکمه ارتقا",
|
||||
"theme": {
|
||||
"dialog": {
|
||||
"button": {
|
||||
"cancel": "لغو",
|
||||
"remove": "حذف"
|
||||
},
|
||||
"remove-theme": "آیا مطمئن هستید که میخواهید تم سفارشی را حذف کنید؟",
|
||||
"remove-theme-message": "این کار تم سفارشی را حذف خواهد کرد"
|
||||
},
|
||||
"label": "تم",
|
||||
"submenu": {
|
||||
"import-css-file": "وارد کردن فایل CSS سفارشی",
|
||||
"no-theme": "بدون تم"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"plugins": {
|
||||
"enabled": "فعال",
|
||||
"label": "افزونهها",
|
||||
"new": "جدید"
|
||||
},
|
||||
"view": {
|
||||
"label": "مشاهده",
|
||||
"submenu": {
|
||||
"force-reload": "اجبار به بارگذاری مجدد",
|
||||
"reload": "بارگذاری مجدد",
|
||||
"reset-zoom": "اندازه واقعی",
|
||||
"toggle-fullscreen": "تغییر به تمامصفحه",
|
||||
"zoom-in": "بزرگنمایی",
|
||||
"zoom-out": "کوچکنمایی"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tray": {
|
||||
"next": "بعدی",
|
||||
"play-pause": "پخش/توقف",
|
||||
"previous": "قبلی",
|
||||
"quit": "خروجی",
|
||||
"restart": "راهاندازی مجدد برنامه",
|
||||
"show": "نمایش پنجره",
|
||||
"tooltip": {
|
||||
"default": "یوتیوب موسیقی",
|
||||
"with-song-info": "یوتیوب موسیقی: {{artist}} - {{title}}"
|
||||
}
|
||||
}
|
||||
},
|
||||
"plugins": {
|
||||
"ad-speedup": {
|
||||
"description": "اگر تبلیغ پخش شود، صدا را بیصدا کرده و سرعت پخش را به 16 برابر افزایش میدهد",
|
||||
"name": "سرعتدهی به تبلیغ"
|
||||
},
|
||||
"adblocker": {
|
||||
"description": "مسدود کردن تمامی تبلیغات و ردیابیها از ابتدا",
|
||||
"menu": {
|
||||
"blocker": "مسدودکننده"
|
||||
},
|
||||
"name": "مسدودکننده تبلیغات"
|
||||
},
|
||||
"album-actions": {
|
||||
"description": "افزودن دکمههای \"برگرفتن ناپسند\"، \"ناپسند\"، \"پسند\"، و \"حذف پسند\" برای اعمال آنها روی همه آهنگها در یک فهرست پخش یا آلبوم",
|
||||
"name": "عملیات آلبوم"
|
||||
},
|
||||
"album-color-theme": {
|
||||
"description": "اعمال یک تم پویا و جلوههای بصری بر اساس پالت رنگ آلبوم",
|
||||
"menu": {
|
||||
"color-mix-ratio": {
|
||||
"label": "نسبت ترکیب رنگ"
|
||||
}
|
||||
},
|
||||
"name": "تم رنگ آلبوم"
|
||||
},
|
||||
"ambient-mode": {
|
||||
"description": "اعمال یک اثر نوری با پخش رنگهای ملایم از ویدئو به پسزمینه صفحه نمایش شما",
|
||||
"menu": {
|
||||
"blur-amount": {
|
||||
"label": "میزان تاری",
|
||||
"submenu": {
|
||||
"pixels": "{{blurAmount}} پیکسل"
|
||||
}
|
||||
},
|
||||
"buffer": {
|
||||
"label": "بافر"
|
||||
},
|
||||
"opacity": {
|
||||
"label": "شفافیت"
|
||||
},
|
||||
"quality": {
|
||||
"label": "کیفیت",
|
||||
"submenu": {
|
||||
"pixels": "{{quality}} پیکسل"
|
||||
}
|
||||
},
|
||||
"size": {
|
||||
"label": "اندازه"
|
||||
},
|
||||
"smoothness-transition": {
|
||||
"label": "انتقال نرمی",
|
||||
"submenu": {
|
||||
"during": "در طول {{interpolationTime}} ثانیه"
|
||||
}
|
||||
},
|
||||
"use-fullscreen": {
|
||||
"label": "استفاده از تمامصفحه"
|
||||
}
|
||||
},
|
||||
"name": "حالت محیطی"
|
||||
},
|
||||
"audio-compressor": {
|
||||
"description": "اعمال فشردهسازی به صدا (کاهش حجم بلندترین بخشهای سیگنال و افزایش حجم بخشهای نرمتر)",
|
||||
"name": "فشردهساز صدا"
|
||||
},
|
||||
"blur-nav-bar": {
|
||||
"description": "شفاف و محو کردن نوار ناوبری",
|
||||
"name": "محو کردن نوار ناوبری"
|
||||
},
|
||||
"bypass-age-restrictions": {
|
||||
"description": "دور زدن تأیید سن یوتیوب",
|
||||
"name": "دور زدن محدودیتهای سنی"
|
||||
},
|
||||
"captions-selector": {
|
||||
"description": "انتخاب زیرنویس برای آهنگهای یوتیوب موسیقی",
|
||||
"menu": {
|
||||
"autoload": "به طور خودکار انتخاب آخرین زیرنویس استفاده شده",
|
||||
"disable-captions": "بدون زیرنویس به صورت پیشفرض"
|
||||
},
|
||||
"name": "انتخابکننده زیرنویس",
|
||||
"prompt": {
|
||||
"selector": {
|
||||
"label": "زبان زیرنویس فعلی: {{language}}",
|
||||
"none": "هیچکدام",
|
||||
"title": "انتخاب زبان زیرنویس"
|
||||
}
|
||||
},
|
||||
"templates": {
|
||||
"title": "باز کردن انتخابکننده زیرنویس"
|
||||
}
|
||||
},
|
||||
"compact-sidebar": {
|
||||
"description": "همیشه نوار کناری را در حالت فشرده تنظیم کن",
|
||||
"name": "نوار کناری فشرده"
|
||||
},
|
||||
"crossfade": {
|
||||
"description": "تداخل بین آهنگها",
|
||||
"menu": {
|
||||
"advanced": "پیشرفته"
|
||||
},
|
||||
"name": "تداخل [بتا]",
|
||||
"prompt": {
|
||||
"options": {
|
||||
"multi-input": {
|
||||
"fade-in-duration": "مدت زمان ورود تدریجی (میلیثانیه)",
|
||||
"fade-out-duration": "مدت زمان خروج تدریجی (میلیثانیه)",
|
||||
"fade-scaling": {
|
||||
"label": "مقیاسبندی ورود تدریجی",
|
||||
"linear": "خطی",
|
||||
"logarithmic": "لگاریتمی"
|
||||
},
|
||||
"seconds-before-end": "تداخل N ثانیه قبل از پایان"
|
||||
},
|
||||
"title": "گزینههای تداخل"
|
||||
}
|
||||
}
|
||||
},
|
||||
"disable-autoplay": {
|
||||
"description": "شروع آهنگ در حالت \"توقف\"",
|
||||
"menu": {
|
||||
"apply-once": "فقط در شروع اعمال میشود"
|
||||
},
|
||||
"name": "غیرفعال کردن پخش خودکار"
|
||||
},
|
||||
"discord": {
|
||||
"backend": {
|
||||
"already-connected": "تلاش برای اتصال با اتصال فعال",
|
||||
"connected": "متصل به Discord",
|
||||
"disconnected": "قطع اتصال از Discord"
|
||||
},
|
||||
"description": "نمایش آنچه گوش میدهید به دوستان با Rich Presence",
|
||||
"menu": {
|
||||
"auto-reconnect": "اتصال خودکار مجدد",
|
||||
"clear-activity": "پاک کردن فعالیت",
|
||||
"clear-activity-after-timeout": "پاک کردن فعالیت پس از تایماوت",
|
||||
"connected": "متصل",
|
||||
"disconnected": "قطع شده",
|
||||
"hide-duration-left": "مخفی کردن مدت زمان باقیمانده",
|
||||
"hide-github-button": "مخفی کردن دکمه لینک GitHub",
|
||||
"play-on-youtube-music": "پخش در یوتیوب موسیقی",
|
||||
"set-inactivity-timeout": "تنظیم تایماوت عدم فعالیت"
|
||||
},
|
||||
"name": "Rich Presence در Discord",
|
||||
"prompt": {
|
||||
"set-inactivity-timeout": {
|
||||
"label": "ورود تایماوت عدم فعالیت به ثانیه:",
|
||||
"title": "تنظیم تایماوت عدم فعالیت"
|
||||
}
|
||||
}
|
||||
},
|
||||
"downloader": {
|
||||
"backend": {
|
||||
"dialog": {
|
||||
"error": {
|
||||
"buttons": {
|
||||
"ok": "تأیید"
|
||||
},
|
||||
"message": "اوه! متاسفیم، دانلود شکست خورد…",
|
||||
"title": "خطا در دانلود!"
|
||||
},
|
||||
"start-download-playlist": {
|
||||
"buttons": {
|
||||
"ok": "تأیید"
|
||||
},
|
||||
"detail": "({{playlistSize}} آهنگ)",
|
||||
"message": "دانلود فهرست پخش {{playlistTitle}}",
|
||||
"title": "دانلود شروع شد"
|
||||
}
|
||||
},
|
||||
"feedback": {
|
||||
"conversion-progress": "تبدیل: {{percent}}%",
|
||||
"converting": "در حال تبدیل…",
|
||||
"done": "انجام شد: {{filePath}}",
|
||||
"download-info": "در حال دانلود {{artist}} - {{title}} [{{videoId}}",
|
||||
"download-progress": "دانلود: {{percent}}%",
|
||||
"downloading": "در حال دانلود…",
|
||||
"downloading-counter": "در حال دانلود {{current}}/{{total}}…",
|
||||
"downloading-playlist": "در حال دانلود فهرست پخش \"{{playlistTitle}}\" - {{playlistSize}} آهنگ ({{playlistId}})",
|
||||
"error-while-downloading": "خطا در دانلود \"{{author}} - {{title}}\": {{error}}",
|
||||
"folder-already-exists": "پوشه {{playlistFolder}} از قبل وجود دارد",
|
||||
"getting-playlist-info": "در حال دریافت اطلاعات فهرست پخش…",
|
||||
"loading": "در حال بارگذاری…",
|
||||
"playlist-has-only-one-song": "فهرست پخش فقط یک آیتم دارد، به طور مستقیم دانلود میشود",
|
||||
"playlist-id-not-found": "شناسه فهرست پخش یافت نشد"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
565
src/i18n/resources/fi.json
Normal file
565
src/i18n/resources/fi.json
Normal file
@ -0,0 +1,565 @@
|
||||
{
|
||||
"common": {
|
||||
"console": {
|
||||
"plugins": {
|
||||
"execute-failed": "Virhe pluginin lataamisessa: {{pluginName}}, koska {{contextName}}",
|
||||
"executed-at-ms": "Lisäosa: {{pluginName}} ja {{contextName}} on ladattu/liitetty {{ms}}",
|
||||
"initialize-failed": "Laajennuksen alustaminen epäonnistui kohteelle \"{{pluginName}}\"",
|
||||
"load-all": "Ladataan kaikkia lisäosia",
|
||||
"load-failed": "Virhe lisäosan lataamisessa kohteelle: {{pluginName}}",
|
||||
"loaded": "Lisäosa {{pluginName}} on ladattu",
|
||||
"unload-failed": "Laajennuksen purkaminen epäonnistui kohtelle: {{pluginName}}",
|
||||
"unloaded": "Lisäosa {{pluginName}} on purettu"
|
||||
}
|
||||
}
|
||||
},
|
||||
"language": {
|
||||
"code": "fi",
|
||||
"local-name": "Suomi",
|
||||
"name": "Finnish"
|
||||
},
|
||||
"main": {
|
||||
"console": {
|
||||
"did-finish-load": {
|
||||
"dev-tools": "Onnistuneesti ladattu. Devtools avautuu"
|
||||
},
|
||||
"i18n": {
|
||||
"loaded": "i18n ladattu"
|
||||
},
|
||||
"second-instance": {
|
||||
"receive-command": "Komento \"{{command}}\" on vastaanotettu"
|
||||
},
|
||||
"theme": {
|
||||
"css-file-not-found": "{{cssFile}} on jätetty väliin, koska tiedosto on virheellinen"
|
||||
},
|
||||
"unresponsive": {
|
||||
"details": "Reagoimaton virhe\n{{error}}"
|
||||
},
|
||||
"when-ready": {
|
||||
"clearing-cache-after-20s": "Puhdista välimuisti"
|
||||
},
|
||||
"window": {
|
||||
"tried-to-render-offscreen": "Näyttö yritti renderöidä näyttöäsi asetuksilla: {{windowSize}}, {{displaySize}} sekä {{position}}"
|
||||
}
|
||||
},
|
||||
"dialog": {
|
||||
"hide-menu-enabled": {
|
||||
"detail": "Valikko on piilotettu, avaa valikko uudestaan painamalla \"Alt\" näppäintä tai \"Escape\" näppäintä",
|
||||
"message": "Valikon piilotus on nyt päällä",
|
||||
"title": "Piilota valikko päällä"
|
||||
},
|
||||
"need-to-restart": {
|
||||
"buttons": {
|
||||
"later": "Myöhemmin",
|
||||
"restart-now": "Uudelleen käynnistä NYT"
|
||||
},
|
||||
"detail": "{{pluginName}} lisäosa vaatii uudelleen käynnistyksen YT musicille",
|
||||
"message": "{{pluginName}} vaatii uudelleen käynnistyksen YT musicille",
|
||||
"title": "Uudelleen käynnistä sovellus"
|
||||
},
|
||||
"unresponsive": {
|
||||
"buttons": {
|
||||
"quit": "Poistu",
|
||||
"relaunch": "Uudelleen käynnistä",
|
||||
"wait": "Odotas vähän"
|
||||
},
|
||||
"detail": "Pahoittelemme häiriötä! ole hyvä ja valitse mitä teet:",
|
||||
"message": "Sovellus ei ole saataville eli tapahtui virhe",
|
||||
"title": "Ikkuna ei vastaa"
|
||||
},
|
||||
"update-available": {
|
||||
"buttons": {
|
||||
"disable": "Poista päivitykset käytöstä",
|
||||
"download": "Lataa",
|
||||
"ok": "Selvä"
|
||||
},
|
||||
"detail": "Uusin versio sovelluksesta on nyt saatavilla, lataa se tästä {{downloadLink}}",
|
||||
"message": "Uusin versio on nyt saatavilla",
|
||||
"title": "Päivitys saatavilla"
|
||||
}
|
||||
},
|
||||
"menu": {
|
||||
"about": "Tietoa",
|
||||
"navigation": {
|
||||
"label": "Selaa",
|
||||
"submenu": {
|
||||
"copy-current-url": "Kopio URL osoite",
|
||||
"go-back": "Takaisin",
|
||||
"go-forward": "Eteenpäin",
|
||||
"quit": "Poistu alustalta",
|
||||
"restart": "Uudelleen käynnistä aplikaatio"
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"label": "Asetukset",
|
||||
"submenu": {
|
||||
"advanced-options": {
|
||||
"label": "Lisäasetukset",
|
||||
"submenu": {
|
||||
"auto-reset-app-cache": "Puhdista sovelluksen välimuisti aina sovelluksen käynnistyksen aikana",
|
||||
"disable-hardware-acceleration": "Poista laitteistokiihdytys käytöstä",
|
||||
"edit-config-json": "Muokkaa \"config.json\" tiedostoa",
|
||||
"override-user-agent": "Ohita käyttäjäagentti",
|
||||
"restart-on-config-changes": "Käynnistä uudelleen asetusten muuton jälkeen",
|
||||
"set-proxy": {
|
||||
"label": "Aseta välityspalvelin (proxy)",
|
||||
"prompt": {
|
||||
"label": "Aseta välityspalvelimen IP-osoite: (jos jätät tyhjäksi, palvelin ei käynnisty)",
|
||||
"placeholder": "Esimerkki osoite: penapertti://127.0.0.0:6969",
|
||||
"title": "Aseta välityspalvelin (proxy)"
|
||||
}
|
||||
},
|
||||
"toggle-dev-tools": "Ota DevTools käyttöön"
|
||||
}
|
||||
},
|
||||
"always-on-top": "Aina päällä",
|
||||
"auto-update": "Automaattisest päivitykset",
|
||||
"hide-menu": {
|
||||
"dialog": {
|
||||
"message": "Valikko piilotetaan seuraavan käynnistyksen yhteydessä. Saat sen päälle painamalla [Alt] näppäintä (tai merkitse takaisin [`], jos käytät sovelluksen sisäistä valikkoa)",
|
||||
"title": "Piilota valikko (päällä)"
|
||||
},
|
||||
"label": "Piilota valikko"
|
||||
},
|
||||
"language": {
|
||||
"dialog": {
|
||||
"message": "Kieli vaihtuu uudelleen käynnistyksen jälkeen (Language will be changed after restart)",
|
||||
"title": "Kieli vaihdettu (Language Changed)"
|
||||
},
|
||||
"label": "Kieli (languages)",
|
||||
"submenu": {
|
||||
"to-help-translate": "Haluatko kääntää puuttuvan kielen? Klkkaa tästä! (Want to help translate? Click here)"
|
||||
}
|
||||
},
|
||||
"resume-on-start": "Jatka kappaleesta, johon jäin aikaisemmin",
|
||||
"single-instance-lock": "Yhden instanssin lukko",
|
||||
"start-at-login": "Aloita kirjautuminen",
|
||||
"starting-page": {
|
||||
"label": "Etusivu",
|
||||
"unset": "Valitsematta"
|
||||
},
|
||||
"tray": {
|
||||
"label": "Suositukset",
|
||||
"submenu": {
|
||||
"disabled": "Pois päältä",
|
||||
"enabled-and-hide-app": "Suositukset ovat käytössä ja piilota valikko",
|
||||
"enabled-and-show-app": "Päällä ja sovellus näkyvissä",
|
||||
"play-pause-on-click": "Soita/pysäytä klikkaamalla"
|
||||
}
|
||||
},
|
||||
"visual-tweaks": {
|
||||
"label": "Visuaalisia tehosteita",
|
||||
"submenu": {
|
||||
"like-buttons": {
|
||||
"default": "Vakio",
|
||||
"force-show": "Pakota näyttämään",
|
||||
"hide": "Piilota",
|
||||
"label": "Tykkäys nappula"
|
||||
},
|
||||
"remove-upgrade-button": "Poista päivitys nappula",
|
||||
"theme": {
|
||||
"dialog": {
|
||||
"button": {
|
||||
"cancel": "Peruuta",
|
||||
"remove": "Poista"
|
||||
},
|
||||
"remove-theme": "Oletko aivan varma, että haluat poistaa kustomoidun teeman?",
|
||||
"remove-theme-message": "Tämä poistaa kustomoidun teeman"
|
||||
},
|
||||
"label": "Teema",
|
||||
"submenu": {
|
||||
"import-css-file": "Liitä kustomoitu CSS tiedosto",
|
||||
"no-theme": "Ei teemaa"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"plugins": {
|
||||
"enabled": "Päällä",
|
||||
"label": "Lisäosat",
|
||||
"new": "UUSI"
|
||||
},
|
||||
"view": {
|
||||
"label": "Katso",
|
||||
"submenu": {
|
||||
"force-reload": "pakota uudelleen lataamaan",
|
||||
"reload": "Uudelleen lataa",
|
||||
"reset-zoom": "Todellinen koko",
|
||||
"toggle-fullscreen": "Koko näyttö päälle/pois",
|
||||
"zoom-in": "Zoomaa lähemmäksi",
|
||||
"zoom-out": "Zoomaa kauemmaksi"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tray": {
|
||||
"next": "Seuraava",
|
||||
"play-pause": "Soita/pysäytä",
|
||||
"previous": "Edellinen",
|
||||
"quit": "Lähde pois",
|
||||
"restart": "Uudelleen käynnistä appi",
|
||||
"show": "Näytä ikkuna",
|
||||
"tooltip": {
|
||||
"default": "Youtube Music",
|
||||
"with-song-info": "Youtube Music {{artist}} - {{title}}"
|
||||
}
|
||||
}
|
||||
},
|
||||
"plugins": {
|
||||
"adblocker": {
|
||||
"description": "Estä kaikki mainokset ja seuranta",
|
||||
"menu": {
|
||||
"blocker": "Estäjät (blockerit)"
|
||||
},
|
||||
"name": "Mainos estäjä"
|
||||
},
|
||||
"album-actions": {
|
||||
"description": "Lisää tykkäysnappulat, joilla voit lisätä tai poistaa tykkäyksiä kerralla kaikille soittolistan tai albumin kappaleille",
|
||||
"name": "Albumin Toiminnot"
|
||||
},
|
||||
"album-color-theme": {
|
||||
"description": "Käyttää dynaamista teemaa ja visuaalisia tehosteita albumin väripaletin perusteella",
|
||||
"menu": {
|
||||
"color-mix-ratio": {
|
||||
"label": "Värien sekoitussuhde",
|
||||
"submenu": {
|
||||
"percent": "{{ratio}}%"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "Albumin Värinen Teema"
|
||||
},
|
||||
"ambient-mode": {
|
||||
"description": "Antaa valaistustehosteen heittämällä videosta lempeitä värejä näytön taustalle",
|
||||
"menu": {
|
||||
"blur-amount": {
|
||||
"label": "Sumennuksen voimakkuus",
|
||||
"submenu": {
|
||||
"pixels": "{{blurAmount}} pikseliä"
|
||||
}
|
||||
},
|
||||
"buffer": {
|
||||
"label": "Puskurointi",
|
||||
"submenu": {
|
||||
"buffer": "{{buffer}}"
|
||||
}
|
||||
},
|
||||
"opacity": {
|
||||
"label": "Läpinäkyvyys",
|
||||
"submenu": {
|
||||
"percent": "{{opacity}}%"
|
||||
}
|
||||
},
|
||||
"quality": {
|
||||
"label": "Laatu",
|
||||
"submenu": {
|
||||
"pixels": "{{quality}} pikseliä"
|
||||
}
|
||||
},
|
||||
"size": {
|
||||
"label": "Koko",
|
||||
"submenu": {
|
||||
"percent": "{{size}}%"
|
||||
}
|
||||
},
|
||||
"smoothness-transition": {
|
||||
"label": "Siirtymän sujuvuus",
|
||||
"submenu": {
|
||||
"during": "Kesto {{interpolationTime}} s"
|
||||
}
|
||||
},
|
||||
"use-fullscreen": {
|
||||
"label": "Käytetään koko näytön tilaa"
|
||||
}
|
||||
}
|
||||
},
|
||||
"audio-compressor": {
|
||||
"description": "Lisää äänen kompressointia (hiljentää voimakkaimpien äänien voimakkuutta ja tehostaa pehmeämpien äänien voimakkuutta)",
|
||||
"name": "Äänen Kompressoija"
|
||||
},
|
||||
"blur-nav-bar": {
|
||||
"description": "Tekee siirtymäpalkista läpikuultavan ja sumean",
|
||||
"name": "Sumenna Siirtymäpalkki"
|
||||
},
|
||||
"bypass-age-restrictions": {
|
||||
"description": "Ohita YouTuben iän vahvistus",
|
||||
"name": "Ohita Ikään Perustuvat Rajoitukset"
|
||||
},
|
||||
"captions-selector": {
|
||||
"description": "YouTube Music ääniraitojen tekstitysten valitsin",
|
||||
"menu": {
|
||||
"autoload": "Valitse automaattisesti viimeksi käytetty tekstitys",
|
||||
"disable-captions": "Tekstitys ei oletusarvoisesti käytössä"
|
||||
},
|
||||
"name": "Tekstitysten valinta",
|
||||
"prompt": {
|
||||
"selector": {
|
||||
"label": "Tekstitysten nykyinen kieli: {{language}}",
|
||||
"none": "Ei mitään",
|
||||
"title": "Valitse tekstitysten kieli"
|
||||
}
|
||||
},
|
||||
"templates": {
|
||||
"title": "Avaa tekstitysten valitsin"
|
||||
}
|
||||
},
|
||||
"compact-sidebar": {
|
||||
"description": "Asettaa sivupalkin aina kompaktiin tilaan",
|
||||
"name": "Kompakti sivupalkki"
|
||||
},
|
||||
"crossfade": {
|
||||
"description": "Ristihäivytä kappaleet",
|
||||
"menu": {
|
||||
"advanced": "Edistynyt"
|
||||
},
|
||||
"name": "Ristihäivytys [Beta]",
|
||||
"prompt": {
|
||||
"options": {
|
||||
"multi-input": {
|
||||
"fade-in-duration": "Sisään häivytyksen kesto (ms)",
|
||||
"fade-out-duration": "Ulos häivytyksen kesto (ms)",
|
||||
"fade-scaling": {
|
||||
"label": "Häivytyksen skaalaus",
|
||||
"linear": "Lineaarinen",
|
||||
"logarithmic": "Logaritminen"
|
||||
},
|
||||
"seconds-before-end": "Ristihäivytä N sekuntia ennen loppua"
|
||||
},
|
||||
"title": "Ristihäivytyksen asetukset"
|
||||
}
|
||||
}
|
||||
},
|
||||
"disable-autoplay": {
|
||||
"description": "Kappaleet alkavat \"pysäytetty\" tilassa",
|
||||
"name": "Poista automaattinen toisto käytöstä"
|
||||
},
|
||||
"discord": {
|
||||
"backend": {
|
||||
"already-connected": "Yritettiin yhdistää vaikka yhteys on jo aktiivinen",
|
||||
"connected": "Yhdistetty Discordiin",
|
||||
"disconnected": "Katkaistu yhteys Discordiin"
|
||||
},
|
||||
"description": "Näytä ystävillesi mitä kuuntelet \"Rich Presence\":n avulla",
|
||||
"menu": {
|
||||
"auto-reconnect": "Automaatinen uudelleenyhdistys",
|
||||
"clear-activity": "Nollaa toiminta",
|
||||
"clear-activity-after-timeout": "Nollaa toiminta aikakatkaisun jälkeen",
|
||||
"connected": "Yhdistetty",
|
||||
"disconnected": "Yhteys katkaistu",
|
||||
"hide-duration-left": "Piilota kappaleen jäljellä oleva kesto",
|
||||
"hide-github-button": "Piilota \"linkki GitHubiin\" -nappi",
|
||||
"play-on-youtube-music": "Kuuntele palvelussa YouTube Music",
|
||||
"set-inactivity-timeout": "Aseta toimettomuuden aikakatkaisu"
|
||||
},
|
||||
"name": "Discord Aktiviteetti (Rich Presence)",
|
||||
"prompt": {
|
||||
"set-inactivity-timeout": {
|
||||
"label": "Anna toimettomuuden aikakatkaisun aika sekunteina:",
|
||||
"title": "Aseta toimettomuuden aikakatkaisu"
|
||||
}
|
||||
}
|
||||
},
|
||||
"downloader": {
|
||||
"backend": {
|
||||
"dialog": {
|
||||
"error": {
|
||||
"buttons": {
|
||||
"ok": "OK"
|
||||
},
|
||||
"message": "Äh! Pahoittelut, lataus epäonnistui…",
|
||||
"title": "Virhe latauksessa!"
|
||||
},
|
||||
"start-download-playlist": {
|
||||
"buttons": {
|
||||
"ok": "OK"
|
||||
},
|
||||
"detail": "({{playlistSize}} kappaletta)",
|
||||
"message": "Lataa Soittolista {{playlistTitle}}",
|
||||
"title": "Lataus aloitettu"
|
||||
}
|
||||
},
|
||||
"feedback": {
|
||||
"conversion-progress": "Muunnetaan: {{percent}}%",
|
||||
"converting": "Muuntaa…",
|
||||
"done": "Valmis: {{filePath}}",
|
||||
"download-info": "Ladataan {{artist}} -{{title}} [{{videoId}}",
|
||||
"download-progress": "Latauksen edistyminen: {{percent}}%",
|
||||
"downloading": "Ladataan…",
|
||||
"downloading-counter": "Ladataan {{current}}/{{total}}…",
|
||||
"downloading-playlist": "Ladataan soittolistaa \"{{playlistTitle}}\" {{playlistSize}} kappaletta ({{playlistId}})",
|
||||
"error-while-downloading": "Virhe ladattaessa \"{{author}} - {{title}}\": {{error}}",
|
||||
"folder-already-exists": "Kansio {{playlistFolder}} on jo olemassa",
|
||||
"getting-playlist-info": "Haetaan soittolistan tietoja…",
|
||||
"loading": "Ladataan…",
|
||||
"playlist-has-only-one-song": "Soittolistalla on vain yksi kappale, se ladataan suoraan",
|
||||
"playlist-id-not-found": "Soittolistan tunnistetta ei löytynyt",
|
||||
"playlist-is-empty": "Soittolista on tyhjä",
|
||||
"playlist-is-mix-or-private": "Virhe haettaessa soittolista tietoja: varmista ettei soittolista ole yksityinen tai \"Miksattu sinulle\" soittolista\n\n{{error}}",
|
||||
"preparing-file": "Valmistellaan tiedostoa…",
|
||||
"saving": "Tallennetaan…",
|
||||
"trying-to-get-playlist-id": "Yritetään hakea soittolistan tunnistetta: {{playlistId}}",
|
||||
"video-id-not-found": "Videota ei löytynyt",
|
||||
"writing-id3": "Kirjoitetaan ID3-tunnisteita…"
|
||||
}
|
||||
},
|
||||
"description": "Lataa MP3- tai lähdetiedoston suoraan käyttöliittymästä",
|
||||
"menu": {
|
||||
"choose-download-folder": "Valitse latauskansio",
|
||||
"download-playlist": "Lataa soittolista",
|
||||
"presets": "Esiasetukset",
|
||||
"skip-existing": "Ohita olemassa olevat tiedostot"
|
||||
},
|
||||
"name": "Lataaja",
|
||||
"renderer": {
|
||||
"can-not-update-progress": "Edistystä ei voida päivittää"
|
||||
},
|
||||
"templates": {
|
||||
"button": "Lataa"
|
||||
}
|
||||
},
|
||||
"exponential-volume": {
|
||||
"description": "Tekee äänenvoimakkuuden säätimestä eksponentiaalisen, jotta matalampien äänenvoimakkuuksien valinta on helpompaa.",
|
||||
"name": "Eksponentiaalinen Äänenvoimakkuus"
|
||||
},
|
||||
"in-app-menu": {
|
||||
"description": "Antaa valikkopalkeille hienon tumman tai albumin värisen ulkonäön",
|
||||
"menu": {
|
||||
"hide-dom-window-controls": "Piilota ikkunan DOM ohjaimet"
|
||||
},
|
||||
"name": "Sovelluksen sisäinen valikko"
|
||||
},
|
||||
"lumiastream": {
|
||||
"description": "Lisää tuen Lumia Stream -palvelulle",
|
||||
"name": "Lumia Stream [Beta]"
|
||||
},
|
||||
"lyrics-genius": {
|
||||
"description": "Lisää tuen useimpien kappaleiden sanoituksille",
|
||||
"menu": {
|
||||
"romanized-lyrics": "Latinaistetut sanoitukset"
|
||||
},
|
||||
"name": "Lyrics Genius",
|
||||
"renderer": {
|
||||
"fetched-lyrics": "Sanoitukset haettu Geniukselle"
|
||||
}
|
||||
},
|
||||
"music-together": {
|
||||
"description": "Jaa soittolista muiden kanssa. Kun isäntä soittaa kappaleen, kaikki muut kuulevat saman kappaleen",
|
||||
"dialog": {
|
||||
"enter-host": "Anna Istunnon tunniste"
|
||||
},
|
||||
"internal": {
|
||||
"save": "Tallenna",
|
||||
"track-source": "Kappaleen lähde",
|
||||
"unknown-user": "Tuntematon käyttäjä"
|
||||
},
|
||||
"menu": {
|
||||
"click-to-copy-id": "Kopioi Istunnon tunniste",
|
||||
"close": "Sulje \"Music Together\"",
|
||||
"connected-users": "Yhdistetyt käyttäjät",
|
||||
"disconnect": "Katkaise yhteys \"Music Together\" -istuntoon",
|
||||
"empty-user": "Ei yhdistyneitä käyttäjiä",
|
||||
"host": "\"Music Together\" -istunnon isäntä",
|
||||
"join": "Yhdistä \"Music Together\" -istuntoon",
|
||||
"permission": {
|
||||
"all": "Salli vieraiden hallita soittolistaa ja soitinta",
|
||||
"host-only": "Vain isäntä voi hallita soittolistaa ja soitinta",
|
||||
"playlist": "Salli vieraiden hallita soittolistaa"
|
||||
},
|
||||
"set-permission": "Muuta hallintaoikeuksia",
|
||||
"status": {
|
||||
"disconnected": "Yhteys katkaistu",
|
||||
"guest": "Yhdistetty vieraana",
|
||||
"host": "Yhdistetty isäntänä"
|
||||
}
|
||||
},
|
||||
"name": "Music Together [Beta]",
|
||||
"toast": {
|
||||
"add-song-failed": "Kappaleen lisääminen epäonnistui",
|
||||
"closed": "Music Together suljettu",
|
||||
"disconnected": "\"Music Together\" yhteys katkaistu",
|
||||
"host-failed": "Music Together -istunnon isännöinti epäonnistui",
|
||||
"id-copied": "Istunnon tunnus kopioitu leikepöydälle",
|
||||
"id-copy-failed": "Istunnon tunnisteen kopioiminen epäonnistui",
|
||||
"join-failed": "Music Together -istuntoon liittyminen epäonnistui",
|
||||
"joined": "Liityttiin Music Together -istuntoon",
|
||||
"permission-changed": "Music Together -istunnon oikeuksia muutettiin \"{{permission}}\"",
|
||||
"remove-song-failed": "Kappaleen poistaminen epäonnistui",
|
||||
"user-connected": "{{name}} liittyi Music Together -istuntoon",
|
||||
"user-disconnected": "{{name}} poistui Music Together -istunnosta"
|
||||
}
|
||||
},
|
||||
"navigation": {
|
||||
"description": "Eteen- ja taaksepäin vievät nuolet suoraan integroituna käyttöliittymään. Juuri niin kuin lempiselaimessasi",
|
||||
"name": "Siirtyminen"
|
||||
},
|
||||
"no-google-login": {
|
||||
"description": "Poista Googlen kirjautumispainikkeet ja linkit käyttöliittymästä",
|
||||
"name": "Ei Google kirjautumista"
|
||||
},
|
||||
"notifications": {
|
||||
"description": "Näytä ilmoitus, kun kappale alkaa soida (interaktiiviset ilmoitukset ovat käytettävissä Windowsilla)",
|
||||
"menu": {
|
||||
"interactive": "Interaktiiviset Ilmoitukset",
|
||||
"interactive-settings": {
|
||||
"label": "Interaktiiviset Asetukset",
|
||||
"submenu": {
|
||||
"hide-button-text": "Piilota painikkeen teksti",
|
||||
"refresh-on-play-pause": "Päivitä Toistamisen/Tauottamisen yhteydessä",
|
||||
"tray-controls": "Avaa/Sulje tehtäväpalkista"
|
||||
}
|
||||
},
|
||||
"priority": "Ilmoitusten tärkeys",
|
||||
"unpause-notification": "Näytä ilmoitus toistamisen yhteydessä"
|
||||
},
|
||||
"name": "Ilmoitukset"
|
||||
},
|
||||
"picture-in-picture": {
|
||||
"description": "Sallii sovelluksen vaihtamisen \"kuva kuvassa\" tilaan",
|
||||
"menu": {
|
||||
"always-on-top": "Aina päällimmäisenä",
|
||||
"hotkey": {
|
||||
"label": "Pikanäppäin",
|
||||
"prompt": {
|
||||
"keybind-options": {
|
||||
"hotkey": "Pikanäppäin"
|
||||
},
|
||||
"label": "Valitse pikanäppäin \"kuva kuvassa\" -tilan kytkemiseksi",
|
||||
"title": "\"Kuva kuvassa\" -tilan pikanäppäin"
|
||||
}
|
||||
},
|
||||
"save-window-position": "Tallenna ikkunan sijainti",
|
||||
"save-window-size": "Tallenna ikkunan koko",
|
||||
"use-native-pip": "Käytä selaimen natiivia \"Kuva kuvassa\" -tilaa"
|
||||
},
|
||||
"name": "Kuva kuvassa",
|
||||
"templates": {
|
||||
"button": "Kuva kuvassa"
|
||||
}
|
||||
},
|
||||
"playback-speed": {
|
||||
"description": "Kuuntele nopeasti, kuuntele hitaasti! Lisää säätimen, jolla voit säätää kappaleen toistonopeutta",
|
||||
"name": "Toistonopeus",
|
||||
"templates": {
|
||||
"button": "Nopeus"
|
||||
}
|
||||
},
|
||||
"precise-volume": {
|
||||
"description": "Säädä äänenvoimakkuutta tarkasti hiiren rullaa tai pikanäppäimiä käyttäen. Kustomoidulla käyttöliittymällä ja säädettävällä äänenvoimakkuuden porrastuksella",
|
||||
"menu": {
|
||||
"custom-volume-steps": "Aseta mukautettu äänenvoimakkuuden porrastus",
|
||||
"global-shortcuts": "Yleiset pikanäppäimet"
|
||||
},
|
||||
"name": "Tarkka äänenvoimakkuus",
|
||||
"prompt": {
|
||||
"global-shortcuts": {
|
||||
"keybind-options": {
|
||||
"decrease": "Vähennä äänenvoimakkuutta",
|
||||
"increase": "Lisää äänenvoimakkuutta"
|
||||
},
|
||||
"label": "Valitse yleiset äänenvoimakkuuden pikanäppäimet:"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
760
src/i18n/resources/fil.json
Normal file
760
src/i18n/resources/fil.json
Normal file
@ -0,0 +1,760 @@
|
||||
{
|
||||
"common": {
|
||||
"console": {
|
||||
"plugins": {
|
||||
"execute-failed": "Nabigong patakbuin ang plugin {{pluginName}}::{{contextName}}",
|
||||
"executed-at-ms": "Ang plugin na {{pluginName}}::{{contextName}} ay pinatakbo sa loob ng {{ms}}ms",
|
||||
"initialize-failed": "Nabigo ang pagsimula ng plugin na \"{{pluginName}}\"",
|
||||
"load-all": "Nilo-load lahat ng mga plugin",
|
||||
"load-failed": "Nabigong i-load ang plugin na \"{{pluginName}}\"",
|
||||
"loaded": "Na-load ang \"{{pluginName}}\" na plugin",
|
||||
"unload-failed": "Nabigong i-unload ang plugin na \"{{pluginName}}\"",
|
||||
"unloaded": "Na-unload ang \"{{pluginName}}\" na plugin"
|
||||
}
|
||||
}
|
||||
},
|
||||
"language": {
|
||||
"code": "fil",
|
||||
"local-name": "Tagalog",
|
||||
"name": "Filipino"
|
||||
},
|
||||
"main": {
|
||||
"console": {
|
||||
"did-finish-load": {
|
||||
"dev-tools": "Natapos ang pag-load. Nabuksan ang DevTools"
|
||||
},
|
||||
"i18n": {
|
||||
"loaded": "na-load ang i18n"
|
||||
},
|
||||
"second-instance": {
|
||||
"receive-command": "Natanggap ang command sa pamamagitan ng protocol: \"{{command}}\""
|
||||
},
|
||||
"theme": {
|
||||
"css-file-not-found": "Ang CSS file na \"{{cssFile}}\" ay hindi umiiral, hindi papansin"
|
||||
},
|
||||
"unresponsive": {
|
||||
"details": "Hindi tumutugon na Error!\n{{error}}"
|
||||
},
|
||||
"when-ready": {
|
||||
"clearing-cache-after-20s": "Naglilinis ng app cache"
|
||||
},
|
||||
"window": {
|
||||
"tried-to-render-offscreen": "Nasubukan ng window na mag-render sa labas ng screen, windowSize={{windowSize}}, displaySize={{displaySize}}, position={{position}}"
|
||||
}
|
||||
},
|
||||
"dialog": {
|
||||
"hide-menu-enabled": {
|
||||
"detail": "Nakatago ang menu, gamitin ang 'Alt' para makita ito (o 'Escape' kung gagamitin ang In-App na Menu)",
|
||||
"message": "Ang Pagtatago ng Menu ay napagana na",
|
||||
"title": "Napagana ang Pagtatago ng Menu"
|
||||
},
|
||||
"need-to-restart": {
|
||||
"buttons": {
|
||||
"later": "Mamaya",
|
||||
"restart-now": "Mag-restart na"
|
||||
},
|
||||
"detail": "Ang plugin na \"{{pluginName}}\" ay kinakailangan ng restart para gumana ito",
|
||||
"message": "Kinakailangan ng \"{{pluginName}}\" na mag-restart",
|
||||
"title": "Kinakailangan ng Restart"
|
||||
},
|
||||
"unresponsive": {
|
||||
"buttons": {
|
||||
"quit": "Umalis",
|
||||
"relaunch": "Muling patakbuhin",
|
||||
"wait": "Maghintay"
|
||||
},
|
||||
"detail": "Ikinalulungkot namin ang abala! piliin kung ano ang gagawin:",
|
||||
"message": "Ang Application ay Hindi Tumutugon",
|
||||
"title": "Di tumutugon ang Window"
|
||||
},
|
||||
"update-available": {
|
||||
"buttons": {
|
||||
"disable": "Di-paganahin ang mga Update",
|
||||
"download": "I-download",
|
||||
"ok": "OK"
|
||||
},
|
||||
"detail": "Ang isang bagong bersyon ay available at maaaring i-download sa {{downloadLink}}",
|
||||
"message": "Mayroong bagong version ay available",
|
||||
"title": "Available ang Update"
|
||||
}
|
||||
},
|
||||
"menu": {
|
||||
"about": "Patungkol",
|
||||
"navigation": {
|
||||
"label": "Nabigasyon",
|
||||
"submenu": {
|
||||
"copy-current-url": "Kopyahin ang kasalukuyang URL",
|
||||
"go-back": "Bumalik",
|
||||
"go-forward": "Pasulong",
|
||||
"quit": "Lumabas",
|
||||
"restart": "I-restart ang App"
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"label": "Mga Opsyon",
|
||||
"submenu": {
|
||||
"advanced-options": {
|
||||
"label": "Mga advance na opsyon",
|
||||
"submenu": {
|
||||
"auto-reset-app-cache": "I-reset ang app cache kapag nagsisimula ang app",
|
||||
"disable-hardware-acceleration": "Di paganahin ang pagpapabilis ng hardware",
|
||||
"edit-config-json": "I-edit ang config.json",
|
||||
"override-user-agent": "I-override ang User-Agent",
|
||||
"restart-on-config-changes": "I-restart kada may pagbabago sa config",
|
||||
"set-proxy": {
|
||||
"label": "I-set ang proxy",
|
||||
"prompt": {
|
||||
"label": "Ilagay ang Proxy Address: (iwanang walang laman para di-paganahin)",
|
||||
"placeholder": "Halimbawa: SOCKS5://127.0.0.1:9999",
|
||||
"title": "I-set ang proxy"
|
||||
}
|
||||
},
|
||||
"toggle-dev-tools": "I-toggle ang DevTools"
|
||||
}
|
||||
},
|
||||
"always-on-top": "Laging nasa ibabaw",
|
||||
"auto-update": "Awto Update",
|
||||
"hide-menu": {
|
||||
"dialog": {
|
||||
"message": "Ang menu ay itatago sa susunod na pag-launch, gamitin ang [Alt] upang ipakita ito (o backtick [`] kung gumagamit ng in-app-menu)",
|
||||
"title": "Pinagana ang Pagtatago ng Menu"
|
||||
},
|
||||
"label": "Pagtatago ng Menu"
|
||||
},
|
||||
"language": {
|
||||
"dialog": {
|
||||
"message": "Ang wika ay mababago pagkatapos mag-restart",
|
||||
"title": "Napalitan ang Wika"
|
||||
},
|
||||
"label": "Wika",
|
||||
"submenu": {
|
||||
"to-help-translate": "Gusto mong tumulong sa pagsasalin? Mag-click dito"
|
||||
}
|
||||
},
|
||||
"resume-on-start": "Ipagpatuloy ang huling kanta kapag nagsisimula ang app",
|
||||
"single-instance-lock": "I-lock sa isang Instance",
|
||||
"start-at-login": "Magsimula sa pag-login",
|
||||
"starting-page": {
|
||||
"label": "Simulang page",
|
||||
"unset": "I-unset"
|
||||
},
|
||||
"tray": {
|
||||
"label": "Tray",
|
||||
"submenu": {
|
||||
"disabled": "Di-napagana",
|
||||
"enabled-and-hide-app": "Napagana at natago ang app",
|
||||
"enabled-and-show-app": "Napagana at napakita ang app",
|
||||
"play-pause-on-click": "Mag play/pause kada click"
|
||||
}
|
||||
},
|
||||
"visual-tweaks": {
|
||||
"label": "Mga Biswal na Tweak",
|
||||
"submenu": {
|
||||
"like-buttons": {
|
||||
"default": "Default",
|
||||
"force-show": "Pilitang ipakita",
|
||||
"hide": "Itago",
|
||||
"label": "Mga Like na button"
|
||||
},
|
||||
"remove-upgrade-button": "Tanggalin ang upgrade na button",
|
||||
"theme": {
|
||||
"dialog": {
|
||||
"button": {
|
||||
"cancel": "Kanselahin",
|
||||
"remove": "Tanggalin"
|
||||
},
|
||||
"remove-theme": "Sigurado ka bang gusto mong alisin ang custom na tema?",
|
||||
"remove-theme-message": "Aalisin nito ang custom na tema"
|
||||
},
|
||||
"label": "Tema",
|
||||
"submenu": {
|
||||
"import-css-file": "Mag-import ng custom na CSS file",
|
||||
"no-theme": "Walang tema"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"plugins": {
|
||||
"enabled": "Napagana",
|
||||
"label": "Mga Plugin",
|
||||
"new": "BAGO"
|
||||
},
|
||||
"view": {
|
||||
"label": "View",
|
||||
"submenu": {
|
||||
"force-reload": "Pilitang I-reload",
|
||||
"reload": "I-reload",
|
||||
"reset-zoom": "Aktuwal na Size",
|
||||
"toggle-fullscreen": "I-toggle ang Full Screen",
|
||||
"zoom-in": "Mag-zoom in",
|
||||
"zoom-out": "Mag-zoom out"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tray": {
|
||||
"next": "Susunod",
|
||||
"play-pause": "Mag-play/Mag-pause",
|
||||
"previous": "Nakaraan",
|
||||
"quit": "Lumabas",
|
||||
"restart": "I-restart ang App",
|
||||
"show": "Ipakita ang window",
|
||||
"tooltip": {
|
||||
"default": "YouTube Music",
|
||||
"with-song-info": "YouTube Music: {{artist}} - {{title}}"
|
||||
}
|
||||
}
|
||||
},
|
||||
"plugins": {
|
||||
"ad-speedup": {
|
||||
"description": "Pag mag-play ng ad, I-mute ang audio at i-set ang bilis ng playback ng 16x",
|
||||
"name": "Pagbilis ng Ad"
|
||||
},
|
||||
"adblocker": {
|
||||
"description": "I-block ang lahat ng ad at tracking",
|
||||
"menu": {
|
||||
"blocker": "Blocker"
|
||||
},
|
||||
"name": "Pag-block ng Ad"
|
||||
},
|
||||
"album-actions": {
|
||||
"description": "Idadagdag ang Undislike, Dislike, Like, at Unlike na button para ilapat ito sa lahat ng kanta sa isang playlist o album",
|
||||
"name": "Mga aksyon sa Album"
|
||||
},
|
||||
"album-color-theme": {
|
||||
"description": "Naglalapat ng dynamic na tema at visual effect batay sa color palette ng album",
|
||||
"menu": {
|
||||
"color-mix-ratio": {
|
||||
"label": "Ratio ng paghahalo ng kulay",
|
||||
"submenu": {
|
||||
"percent": "{{ratio}}%"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "Tema ng Kulay ng Album"
|
||||
},
|
||||
"ambient-mode": {
|
||||
"description": "Naglalapat ng lighting effect sa pamamagitan ng pag-cast ng mga magiliw na kulay mula sa video, sa background ng iyong screen",
|
||||
"menu": {
|
||||
"blur-amount": {
|
||||
"label": "Dami ng blur",
|
||||
"submenu": {
|
||||
"pixels": "{{blurAmount}} na pixel"
|
||||
}
|
||||
},
|
||||
"buffer": {
|
||||
"label": "Buffer",
|
||||
"submenu": {
|
||||
"buffer": "{{buffer}}"
|
||||
}
|
||||
},
|
||||
"opacity": {
|
||||
"label": "Kalabuan (Opacity)",
|
||||
"submenu": {
|
||||
"percent": "{{opacity}}%"
|
||||
}
|
||||
},
|
||||
"quality": {
|
||||
"label": "Kalidad",
|
||||
"submenu": {
|
||||
"pixels": "{{quality}} na pixel"
|
||||
}
|
||||
},
|
||||
"size": {
|
||||
"label": "Laki",
|
||||
"submenu": {
|
||||
"percent": "{{size}}%"
|
||||
}
|
||||
},
|
||||
"smoothness-transition": {
|
||||
"label": "Ayos ng Transisyon",
|
||||
"submenu": {
|
||||
"during": "Habang {{interpolationTime}} s"
|
||||
}
|
||||
},
|
||||
"use-fullscreen": {
|
||||
"label": "Gumamit ng fullscreen"
|
||||
}
|
||||
},
|
||||
"name": "Ambient Mode"
|
||||
},
|
||||
"api-server": {
|
||||
"description": "Nagdadagdag ng API Server upang kontrolin ang player",
|
||||
"dialog": {
|
||||
"request": {
|
||||
"buttons": {
|
||||
"allow": "Payagan",
|
||||
"deny": "Tanggihan"
|
||||
},
|
||||
"message": "Payagan ang {{ID}} ({{origin}}) upang ma-access ang API?",
|
||||
"title": "Awtorisasyon ng API request"
|
||||
}
|
||||
},
|
||||
"menu": {
|
||||
"auth-strategy": {
|
||||
"label": "Estratehiya ng awtorisasyon",
|
||||
"submenu": {
|
||||
"auth-at-first": {
|
||||
"label": "Mag-autorisa sa unang request"
|
||||
},
|
||||
"none": {
|
||||
"label": "Walang awtorisasyon"
|
||||
}
|
||||
}
|
||||
},
|
||||
"hostname": {
|
||||
"label": "Hostname"
|
||||
},
|
||||
"port": {
|
||||
"label": "Port"
|
||||
}
|
||||
},
|
||||
"name": "API Server [Beta]",
|
||||
"prompt": {
|
||||
"hostname": {
|
||||
"label": "Itala ang hostname (tulad ng 0.0.0.0) para sa API server:",
|
||||
"title": "Hostname"
|
||||
},
|
||||
"port": {
|
||||
"label": "Itala ang port para sa API server:",
|
||||
"title": "Port"
|
||||
}
|
||||
}
|
||||
},
|
||||
"audio-compressor": {
|
||||
"description": "Ilapat ang compression sa audio (pinababa ang volume ng pinakamalakas na bahagi ng signal at pinapataas ang volume ng pinakamalambot na bahagi)",
|
||||
"name": "Compressor ng Audio"
|
||||
},
|
||||
"blur-nav-bar": {
|
||||
"description": "Gawing transparent at malabo ang bar ng nabigasyon",
|
||||
"name": "Palabuin ang Bar ng Nabigasyon"
|
||||
},
|
||||
"bypass-age-restrictions": {
|
||||
"description": "I-bypass ang pag-verify ng edad ng YouTube",
|
||||
"name": "I-bypass ang Restriksyon sa Edad"
|
||||
},
|
||||
"captions-selector": {
|
||||
"description": "Tagapili ng caption para sa mga audio track ng YouTube Music",
|
||||
"menu": {
|
||||
"autoload": "Awtomatikong piliin ang huling ginamit na caption",
|
||||
"disable-captions": "Walang mga caption bilang default"
|
||||
},
|
||||
"name": "Tagapili ng Caption",
|
||||
"prompt": {
|
||||
"selector": {
|
||||
"label": "Kasalukuyang wika ng caption:{{language}}",
|
||||
"none": "Wala",
|
||||
"title": "Pumili ng wika ng caption"
|
||||
}
|
||||
},
|
||||
"templates": {
|
||||
"title": "Bumukas ng pagpilian ng caption"
|
||||
}
|
||||
},
|
||||
"compact-sidebar": {
|
||||
"description": "Laging i-set ang sidebar sa compact mode",
|
||||
"name": "Pinaliit na Sidebar"
|
||||
},
|
||||
"crossfade": {
|
||||
"description": "I-crossfade kada kanta",
|
||||
"prompt": {
|
||||
"options": {
|
||||
"multi-input": {
|
||||
"fade-in-duration": "Tagal ng pag-fade in (ms)",
|
||||
"fade-out-duration": "Tagal ng pag-fade out (ms)",
|
||||
"fade-scaling": {
|
||||
"label": "Scaling ng pag-fade"
|
||||
},
|
||||
"seconds-before-end": "I-crossfade sa loob ng N segundo bago ang katapusan"
|
||||
},
|
||||
"title": "Pagpipilian sa crossfade"
|
||||
}
|
||||
}
|
||||
},
|
||||
"disable-autoplay": {
|
||||
"description": "Gawing simulan ang kanta sa \"naka-pause\" na mode",
|
||||
"menu": {
|
||||
"apply-once": "Nalalapat lamang sa startup"
|
||||
},
|
||||
"name": "Patayin ang Pag-Autoplay"
|
||||
},
|
||||
"discord": {
|
||||
"backend": {
|
||||
"already-connected": "Sinubukang kumonekta sa aktibong koneksyon",
|
||||
"connected": "Nakakonekta sa Discord",
|
||||
"disconnected": "Nadiskonekta sa Discord"
|
||||
},
|
||||
"description": "Ipakita sa iyong mga kaibigan kung ano ang pinapakinggan mo gamit ang Rich Presence",
|
||||
"menu": {
|
||||
"auto-reconnect": "Awtomatikong kumonekta muli",
|
||||
"clear-activity": "I-clear ang aktibidad",
|
||||
"clear-activity-after-timeout": "I-clear ang aktibidad pagkatapos ng timeout",
|
||||
"connected": "Nakakonekta",
|
||||
"disconnected": "Nadiskonekta",
|
||||
"hide-duration-left": "Itago ang natitirang oras",
|
||||
"hide-github-button": "Itago ang button na GitHub link",
|
||||
"play-on-youtube-music": "Patugtugin sa YouTube Music",
|
||||
"set-inactivity-timeout": "I-set ang inactivity timeout"
|
||||
},
|
||||
"prompt": {
|
||||
"set-inactivity-timeout": {
|
||||
"label": "Ilagay ang inactivity timeout sa ilang segundo:",
|
||||
"title": "I-set ang inactivity timeout"
|
||||
}
|
||||
}
|
||||
},
|
||||
"downloader": {
|
||||
"backend": {
|
||||
"dialog": {
|
||||
"error": {
|
||||
"message": "Argh! Paumanhin, nabigo ang pag-download…",
|
||||
"title": "Nagkaroon ng error sa pag-download!"
|
||||
},
|
||||
"start-download-playlist": {
|
||||
"detail": "({{playlistSize}} na mga kanta)",
|
||||
"message": "Dina-download ang Playlist na {{playlistTitle}}",
|
||||
"title": "Nasimulan na ang pag-download"
|
||||
}
|
||||
},
|
||||
"feedback": {
|
||||
"conversion-progress": "Pag-convert: {{percent}}%",
|
||||
"converting": "Kino-convert…",
|
||||
"done": "Natapos na: {{filePath}}",
|
||||
"download-info": "Dina-download ang {{artist}} - {{title}} [{{videoId}}",
|
||||
"download-progress": "Dina-download: {{percent}}%",
|
||||
"downloading": "Dina-download…",
|
||||
"downloading-counter": "Dina-download {{current}}/{{total}}…",
|
||||
"downloading-playlist": "Dina-download ang playlist \"{{playlistTitle}}\" - {{playlistSize}} na mga kanta ({{playlistId}})",
|
||||
"error-while-downloading": "Error sa pag-download \"{{author}} - {{title}}\": {{error}}",
|
||||
"folder-already-exists": "Ang folder na {{playlistFolder}} ay umiiral na",
|
||||
"getting-playlist-info": "Kinukuha ang impo ng playlist…",
|
||||
"loading": "Naglo-load…",
|
||||
"playlist-has-only-one-song": "May isang aytem lang ang playlist, direktang dina-download na",
|
||||
"playlist-id-not-found": "Walang playlist ID na nahanap",
|
||||
"playlist-is-empty": "Walang laman ang playlist",
|
||||
"playlist-is-mix-or-private": "Error sa pagkuha ng impo ng playlist: tiyaking hindi ito pribado o \"Mixed para sa iyo\" na playlist\n\n{{error}}",
|
||||
"preparing-file": "Inihahanda ang file…",
|
||||
"saving": "Sine-save…",
|
||||
"trying-to-get-playlist-id": "Sinusubukang makuha ang playlist ID: {{playlistId}}",
|
||||
"video-id-not-found": "Hindi nahanap ang video",
|
||||
"writing-id3": "Sinusulat ang mga ID3 na tag…"
|
||||
}
|
||||
},
|
||||
"description": "Dina-download ang mga MP3 / source audio direkta mula sa interface",
|
||||
"menu": {
|
||||
"choose-download-folder": "Pumili ng download folder",
|
||||
"download-finish-settings": {
|
||||
"label": "Kung natapos ang download",
|
||||
"prompt": {
|
||||
"last-percent": "Tapos ng x na porsyento",
|
||||
"last-seconds": "Huling x na segundo",
|
||||
"title": "I-configure kung kailan magda-download"
|
||||
},
|
||||
"submenu": {
|
||||
"enabled": "Napagana na",
|
||||
"percent": "Porsyento",
|
||||
"seconds": "Segundo"
|
||||
}
|
||||
},
|
||||
"download-playlist": "Dina-download ang playlist",
|
||||
"presets": "Mga preset",
|
||||
"skip-existing": "Laktawan ang mga kasalukuyang file"
|
||||
},
|
||||
"renderer": {
|
||||
"can-not-update-progress": "Hindi ma-update ang progress"
|
||||
},
|
||||
"templates": {
|
||||
"button": "Mag download"
|
||||
}
|
||||
},
|
||||
"exponential-volume": {
|
||||
"description": "Ginagawang exponential ang volume slider para mas madaling pumili ng mas mababang volume."
|
||||
},
|
||||
"in-app-menu": {
|
||||
"description": "Nagbibigay sa mga menu-bar ng magarbo, madilim o kulay ng album",
|
||||
"menu": {
|
||||
"hide-dom-window-controls": "Itago ang mga DOM window control"
|
||||
}
|
||||
},
|
||||
"lumiastream": {
|
||||
"description": "Nabibigay suporta sa Lumia Stream",
|
||||
"name": "Lumia Stream [Beta]"
|
||||
},
|
||||
"lyrics-genius": {
|
||||
"description": "Nagdaragdag ng suporta sa lyrics para sa karamihan ng kanta",
|
||||
"renderer": {
|
||||
"fetched-lyrics": "Kinuha ang lyrics para sa Genius"
|
||||
}
|
||||
},
|
||||
"music-together": {
|
||||
"description": "Magbahagi ng playlist sa iba. Kapag nagpatugtog ang host ng isang kanta, maririnig ng lahat ang parehong kanta",
|
||||
"dialog": {
|
||||
"enter-host": "Ilagay ang Host ID"
|
||||
},
|
||||
"internal": {
|
||||
"save": "I-save",
|
||||
"unknown-user": "Di-kilalang User"
|
||||
},
|
||||
"menu": {
|
||||
"click-to-copy-id": "Kopyahin ang Host ID",
|
||||
"close": "Isara ang Music Together",
|
||||
"connected-users": "Nakakonektang (mga) User",
|
||||
"disconnect": "Mag-diskonekta sa Music Together",
|
||||
"empty-user": "Walang naka-konektang user",
|
||||
"host": "Host ng Music Together",
|
||||
"join": "Sumali sa Music Together",
|
||||
"permission": {
|
||||
"all": "Payagan ang mga guest na kontrolin ang playlist at player",
|
||||
"host-only": "Ang host lamang ang maka-kontrol ng playlist at player",
|
||||
"playlist": "Payagan ang mga guest na kontrolin ang playlist"
|
||||
},
|
||||
"set-permission": "Palitan ng permiso ng pag-control",
|
||||
"status": {
|
||||
"disconnected": "Nadiskonekta",
|
||||
"guest": "Nakakonekta bilang Guest",
|
||||
"host": "Nakakonekta bilang Host"
|
||||
}
|
||||
},
|
||||
"toast": {
|
||||
"add-song-failed": "Nabigong magdagdag ng kanta",
|
||||
"closed": "Nakasara ang Music Together",
|
||||
"disconnected": "Nakadiskonekta ang Music Together",
|
||||
"host-failed": "Nabigong mag-host ng Music Together",
|
||||
"id-copied": "Nakopya na ang Host ID sa clipboard",
|
||||
"id-copy-failed": "Nabigong nakopya ang Host ID sa clipboard",
|
||||
"join-failed": "Nabigong sumali sa Music Together",
|
||||
"joined": "Nakasali sa Music Together",
|
||||
"permission-changed": "Ang permiso ng Music Together ay nabago sa \"{{permission}}\"",
|
||||
"remove-song-failed": "Nabigong natanggal ang kanta",
|
||||
"user-connected": "{{name}} ay sumali sa Music Together",
|
||||
"user-disconnected": "{{name}} ay umalis sa Music Together"
|
||||
}
|
||||
},
|
||||
"navigation": {
|
||||
"description": "Ang Next/Back navigation na arrow ay direktang magamit sa interface, katulad sa iyong paboritong browser",
|
||||
"name": "Nabigasyon"
|
||||
},
|
||||
"no-google-login": {
|
||||
"description": "Tanggalin ang mga Google login na button at mga link mula sa interface",
|
||||
"name": "Walang Google na Login"
|
||||
},
|
||||
"notifications": {
|
||||
"description": "Magpakita ng notification kapag nagsimulang tumugtog ang kanta (magagamit ang mga interactive na notification sa Windows)",
|
||||
"menu": {
|
||||
"interactive": "Interactive na Notification",
|
||||
"interactive-settings": {
|
||||
"label": "Mga Interactive na Setting",
|
||||
"submenu": {
|
||||
"hide-button-text": "Itago ang button na texto",
|
||||
"refresh-on-play-pause": "I-refresh sa Pag-play/Pag-pause",
|
||||
"tray-controls": "Buksan/Isara sa pag-click sa tray"
|
||||
}
|
||||
},
|
||||
"priority": "Prioridad ng Notification",
|
||||
"toast-style": "Estilo ng toast",
|
||||
"unpause-notification": "Ipakita ang notification sa pag-unpause"
|
||||
},
|
||||
"name": "Mga Abiso"
|
||||
},
|
||||
"picture-in-picture": {
|
||||
"description": "Payagan ang pag-palit ng app sa picture-in-picture mode",
|
||||
"menu": {
|
||||
"always-on-top": "Laging sa itaas",
|
||||
"hotkey": {
|
||||
"prompt": {
|
||||
"label": "Pumili ng hotkey sa pag-toggle ng picture-in-picture",
|
||||
"title": "Hotkey ng Picture-in-picture"
|
||||
}
|
||||
},
|
||||
"save-window-position": "I-save ang posisyon ng window",
|
||||
"save-window-size": "I-save ang laki ng window",
|
||||
"use-native-pip": "Gamitin ang browser native na PiP"
|
||||
}
|
||||
},
|
||||
"playback-speed": {
|
||||
"description": "Makinig na mabilisan, makinig na mabagalan! Nagdaragdag ito ng slider upang makontrol ang bilis ng kanta",
|
||||
"name": "Bilis ng Playback",
|
||||
"templates": {
|
||||
"button": "Bilis"
|
||||
}
|
||||
},
|
||||
"precise-volume": {
|
||||
"description": "Kontrolin nang wasto ang volume gamit ang mousewheel/mga hotkey, na may custom HUD at customizable na volume step",
|
||||
"menu": {
|
||||
"arrows-shortcuts": "Lokal na Arrow-key na Kontrol",
|
||||
"custom-volume-steps": "I-set ang custom na Volume Step"
|
||||
},
|
||||
"prompt": {
|
||||
"global-shortcuts": {
|
||||
"keybind-options": {
|
||||
"decrease": "Bawasan ang Volume",
|
||||
"increase": "Dagdagan ang Volume"
|
||||
},
|
||||
"label": "Pumili ng Keybind para sa Global Volume:"
|
||||
},
|
||||
"volume-steps": {
|
||||
"label": "Pumili ng Dagdagan/Bawasan ang volume step"
|
||||
}
|
||||
}
|
||||
},
|
||||
"quality-changer": {
|
||||
"backend": {
|
||||
"dialog": {
|
||||
"quality-changer": {
|
||||
"detail": "Kasalukuyang Kalidad: {{quality}}",
|
||||
"message": "Pumili ng Kalidad ng Video:",
|
||||
"title": "Pumili ng Kalidad ng Video"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": "Payagang mapapalitan ang kalidad ng video na may button sa video overlay"
|
||||
},
|
||||
"scrobbler": {
|
||||
"description": "Idagdag ang scrobbling support (last.fm, Listenbrains, atbp.)",
|
||||
"dialog": {
|
||||
"lastfm": {
|
||||
"auth-failed": {
|
||||
"message": "Nabigong mag-authenticate sa Last.fm\nItago ang popup hanggang sa susunod na pag-restart.",
|
||||
"title": "Nabigo ang Authentication"
|
||||
}
|
||||
}
|
||||
},
|
||||
"menu": {
|
||||
"lastfm": {
|
||||
"api-settings": "Mga setting ng API para sa Last.fm"
|
||||
},
|
||||
"listenbrainz": {
|
||||
"token": "Ilagay ang user token ng ListenBrainz"
|
||||
},
|
||||
"scrobble-other-media": "Mag-Scrobble ng ibang media"
|
||||
},
|
||||
"prompt": {
|
||||
"lastfm": {
|
||||
"api-key": "API key ng Last.fm",
|
||||
"api-secret": "API secret ng Last.fm"
|
||||
},
|
||||
"listenbrainz": {
|
||||
"token": {
|
||||
"label": "Ilagay ang ListenBrainz user token:",
|
||||
"title": "Token ng ListenBrainz"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"shortcuts": {
|
||||
"description": "Nagbibigay-daan sa pagtatakda ng mga global hotkey para sa playback (play/pause/susunod/nakaraan) at pag-off ng media OSD sa pamamagitan ng pag-override sa mga media key, pag-on sa Ctrl/CMD + F para maghanap, pag-on sa suporta ng Linux MPRIS para sa mga media key, at mga custom na hotkey para sa mga advanced na user",
|
||||
"menu": {
|
||||
"override-media-keys": "I-override ang mga Media Key",
|
||||
"set-keybinds": "I-set ang Global Song Control"
|
||||
},
|
||||
"name": "Mga shortcut (at MPRIS)",
|
||||
"prompt": {
|
||||
"keybind": {
|
||||
"keybind-options": {
|
||||
"next": "Susunod",
|
||||
"play-pause": "Mag-play / Mag-pause",
|
||||
"previous": "Nakaraan"
|
||||
},
|
||||
"label": "Pumili ng Global na Keybind para sa Songs Control:"
|
||||
}
|
||||
}
|
||||
},
|
||||
"skip-disliked-songs": {
|
||||
"description": "Laktawan ang na-dislike na kanta",
|
||||
"name": "I-skip ang mga Na-dislike na Kanta"
|
||||
},
|
||||
"skip-silences": {
|
||||
"description": "Automatikong laktawan ang mga tahimik na mga seksyon sa kanta",
|
||||
"name": "I-skip ang mga Katahimikan"
|
||||
},
|
||||
"sponsorblock": {
|
||||
"description": "Automatikong Laktawan ang di part ng kanta tulad ng intro/outro o part ng mga music video na ang kanta ay di nagple-play"
|
||||
},
|
||||
"synced-lyrics": {
|
||||
"description": "Nagbibigay ng naka-sync na lyrics sa mga kanta, gamit ang mga provider tulad ng LRClib.",
|
||||
"errors": {
|
||||
"fetch": "⚠️ - Nagkaroon ng error habang kinukuha ang lyrics. Subukang muli mamaya.",
|
||||
"not-found": "⚠️ - Walang nakitang lyrics para sa kantang ito."
|
||||
},
|
||||
"menu": {
|
||||
"default-text-string": {
|
||||
"label": "Default na character sa pagitan ng lyrics",
|
||||
"tooltip": "Pumili ng default na character na gagamitin sa pagitan ng lyrics"
|
||||
},
|
||||
"line-effect": {
|
||||
"label": "Effect ng Linya",
|
||||
"submenu": {
|
||||
"focus": {
|
||||
"tooltip": "Gawing puti lamang ang kasalukuyang linya"
|
||||
},
|
||||
"offset": {
|
||||
"tooltip": "I-offset sa kanan ang kasalukuyang linya"
|
||||
},
|
||||
"scale": {
|
||||
"tooltip": "I-scale ang kasalukuyang linya"
|
||||
}
|
||||
},
|
||||
"tooltip": "Pumili ng effect na ilalapat sa kasalukuyang linya"
|
||||
},
|
||||
"precise-timing": {
|
||||
"label": "Gawing perpektong naka-sync ang lyrics",
|
||||
"tooltip": "Kalkulahin sa millisecond ang pagpapakita ng susunod na linya (maaaring magkaroon ng maliit na epekto sa performance)"
|
||||
},
|
||||
"show-lyrics-even-if-inexact": {
|
||||
"label": "Ipakita ang lyrics kahit di-eksakto",
|
||||
"tooltip": "Kung hindi matagpuan ang kanta, susubukan muli ng plugin gamit ang ibang query sa paghahanap.\nAng resulta mula sa pangalawang pagsubok ay maaaring hindi eksakto."
|
||||
},
|
||||
"show-time-codes": {
|
||||
"label": "Ipakita ang mga time code",
|
||||
"tooltip": "Ipakita ang mga time code kasunod sa lyrics"
|
||||
}
|
||||
},
|
||||
"refetch-btn": {
|
||||
"fetching": "Nag-fe-fetch...",
|
||||
"normal": "I-fetch muli ang lyrics"
|
||||
},
|
||||
"warnings": {
|
||||
"duration-mismatch": "⚠️ - Maaaring hindi naka-sync ang lyrics dahil sa hindi pagkakatugma ng duration.",
|
||||
"inexact": "⚠️ - Maaaring hindi eksakto ang lyrics para sa kantang ito",
|
||||
"instrumental": "⚠️ - Ito ay isang instrumental na kanta"
|
||||
}
|
||||
},
|
||||
"taskbar-mediacontrol": {
|
||||
"description": "Kontrolin ang pag-play mula sa iyong taskbar ng Windows"
|
||||
},
|
||||
"touchbar": {
|
||||
"description": "Idaragdag ang TouchBar na widget para sa mga user ng macOS"
|
||||
},
|
||||
"tuna-obs": {
|
||||
"description": "Integrasyon kasama ang Tuna na OBS plugin"
|
||||
},
|
||||
"video-toggle": {
|
||||
"description": "Idaragdag ng button na magpalit sa Video/Kanta na mode. maaari ding opsyonal na alisin ang tab ng video",
|
||||
"menu": {
|
||||
"align": {
|
||||
"submenu": {
|
||||
"left": "Kaliwa",
|
||||
"middle": "Gitna",
|
||||
"right": "Kanan"
|
||||
}
|
||||
},
|
||||
"force-hide": "Piliting tanggalin ang video tab",
|
||||
"mode": {
|
||||
"submenu": {
|
||||
"disabled": "Naka-disable"
|
||||
}
|
||||
}
|
||||
},
|
||||
"templates": {
|
||||
"button": "Kanta"
|
||||
}
|
||||
},
|
||||
"visualizer": {
|
||||
"description": "Idaragdag ng visualizer sa player",
|
||||
"menu": {
|
||||
"visualizer-type": "Uri ng Visualizer"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -59,7 +59,7 @@
|
||||
},
|
||||
"unresponsive": {
|
||||
"buttons": {
|
||||
"quit": "Quitté",
|
||||
"quit": "Quitter",
|
||||
"relaunch": "Relancer",
|
||||
"wait": "Attendre"
|
||||
},
|
||||
@ -105,7 +105,7 @@
|
||||
"label": "Définir un proxy",
|
||||
"prompt": {
|
||||
"label": "Entrez l'adresse proxy : (laissez vide pour désactiver)",
|
||||
"placeholder": "Exemple: SOCKS5://127.0.0.1:9999",
|
||||
"placeholder": "Exemple : SOCKS5://127.0.0.1:9999",
|
||||
"title": "Définir un proxy"
|
||||
}
|
||||
},
|
||||
@ -158,6 +158,14 @@
|
||||
},
|
||||
"remove-upgrade-button": "Supprimer le bouton de mise à niveau",
|
||||
"theme": {
|
||||
"dialog": {
|
||||
"button": {
|
||||
"cancel": "Annuler",
|
||||
"remove": "Supprimer"
|
||||
},
|
||||
"remove-theme": "Êtes-vous sûr de supprimer le thème personnalisé ?",
|
||||
"remove-theme-message": "Cela va supprimer le thème personnalisé"
|
||||
},
|
||||
"label": "Thème",
|
||||
"submenu": {
|
||||
"import-css-file": "Importer fichier CSS personnalisé",
|
||||
@ -171,7 +179,7 @@
|
||||
"plugins": {
|
||||
"enabled": "Activé",
|
||||
"label": "Extensions",
|
||||
"new": "NOUVELLE"
|
||||
"new": "NOUVEAU"
|
||||
},
|
||||
"view": {
|
||||
"label": "Vue",
|
||||
@ -199,6 +207,10 @@
|
||||
}
|
||||
},
|
||||
"plugins": {
|
||||
"ad-speedup": {
|
||||
"description": "Si une publicité apparaît, le son est coupé et la vitesse de lecture est réglée sur 16x",
|
||||
"name": "Accélérer les publicités"
|
||||
},
|
||||
"adblocker": {
|
||||
"description": "Bloquer toutes les annonces et le suivi par défaut",
|
||||
"menu": {
|
||||
@ -402,6 +414,21 @@
|
||||
"description": "Télécharge les fichiers MP3/source audio directement depuis l'interface",
|
||||
"menu": {
|
||||
"choose-download-folder": "Choisissez le dossier de téléchargement",
|
||||
"download-finish-settings": {
|
||||
"label": "Télécharger une fois terminé",
|
||||
"prompt": {
|
||||
"last-percent": "Après x pour cent",
|
||||
"last-seconds": "Dernières x secondes",
|
||||
"title": "Configurer quand télécharger"
|
||||
},
|
||||
"submenu": {
|
||||
"advanced": "Avancé",
|
||||
"enabled": "Activé",
|
||||
"mode": "Mode de temps",
|
||||
"percent": "Pourcent",
|
||||
"seconds": "Secondes"
|
||||
}
|
||||
},
|
||||
"download-playlist": "Télécharger la liste de lecture",
|
||||
"presets": "Préconfigurations",
|
||||
"skip-existing": "Passer les fichiers existants"
|
||||
@ -521,7 +548,7 @@
|
||||
"keybind-options": {
|
||||
"hotkey": "Raccourci clavier"
|
||||
},
|
||||
"label": "Choisissez un raccourci clavier pour activer l'image dans l'image",
|
||||
"label": "Choisissez un raccourci clavier pour activer le mode Image dans l'image",
|
||||
"title": "Touche de raccourci Image dans l'image"
|
||||
}
|
||||
},
|
||||
@ -641,6 +668,59 @@
|
||||
"description": "Saute automatiquement les parties non musicales comme l'intro/outro ou les parties de clips vidéo où la chanson n'est pas lue",
|
||||
"name": "SponsorBlock"
|
||||
},
|
||||
"synced-lyrics": {
|
||||
"description": "Ajoute des paroles synchronisées aux chansons, grâce à LRClib par exemple.",
|
||||
"errors": {
|
||||
"fetch": "⚠️ - Une erreur s'est produite en allant chercher les paroles. Merci de réessayer plus tard.",
|
||||
"not-found": "⚠️ - Aucune paroles trouvées pour cette musique."
|
||||
},
|
||||
"menu": {
|
||||
"default-text-string": {
|
||||
"label": "Caractère par défaut entre les paroles",
|
||||
"tooltip": "Choisi le caractère par défaut à utiliser pour l'espace entre les paroles"
|
||||
},
|
||||
"line-effect": {
|
||||
"label": "Effet de ligne",
|
||||
"submenu": {
|
||||
"focus": {
|
||||
"label": "Focus",
|
||||
"tooltip": "Rend seulement la ligne actuelle blanche"
|
||||
},
|
||||
"offset": {
|
||||
"label": "Décalage",
|
||||
"tooltip": "Décale sur la droite la ligne actuelle"
|
||||
},
|
||||
"scale": {
|
||||
"label": "Grossissement",
|
||||
"tooltip": "Agrandis la ligne actuelle"
|
||||
}
|
||||
},
|
||||
"tooltip": "Choisi l'effet à appliquer sur la ligne actuelle"
|
||||
},
|
||||
"precise-timing": {
|
||||
"label": "Rend les paroles parfaitement synchronisées",
|
||||
"tooltip": "Calcul à la milliseconde près l'affichage de la ligne suivante (peut avoir un faible impact sur les performances)"
|
||||
},
|
||||
"show-lyrics-even-if-inexact": {
|
||||
"label": "Afficher les paroles même si inexactes",
|
||||
"tooltip": "Si la musique n'est pas trouvé, le plugin essaye à nouveau avec une différence requête.\nLe résultat du deuxième essais peut ne pas être exacte."
|
||||
},
|
||||
"show-time-codes": {
|
||||
"label": "Afficher les timecodes",
|
||||
"tooltip": "Affiche à côté de chaque paroles son timecode"
|
||||
}
|
||||
},
|
||||
"name": "Paroles Synchronisées",
|
||||
"refetch-btn": {
|
||||
"fetching": "Chargement...",
|
||||
"normal": "Rafraîchir les paroles"
|
||||
},
|
||||
"warnings": {
|
||||
"duration-mismatch": "⚠️ - Les paroles peuvent ne pas être synchronisées à cause d'une différence de durée.",
|
||||
"inexact": "⚠️ - Les paroles de cette chanson peuvent ne pas être exactes",
|
||||
"instrumental": "⚠️ - Cette musique n'a pas de paroles"
|
||||
}
|
||||
},
|
||||
"taskbar-mediacontrol": {
|
||||
"description": "Contrôlez la lecture depuis votre barre des tâches Windows",
|
||||
"name": "Contrôle multimédia de la barre des tâches"
|
||||
|
||||
@ -1 +1,59 @@
|
||||
{}
|
||||
{
|
||||
"common": {
|
||||
"console": {
|
||||
"plugins": {
|
||||
"execute-failed": "שגיאה בהרצת התוסף {{pluginName}}::{{contextName}}",
|
||||
"executed-at-ms": "התוסף {{pluginName}}:{{contextName}} בוצע ב {{ms}}ms",
|
||||
"initialize-failed": "טעינת התוסף \"{{pluginName}}\" נכשלה",
|
||||
"load-all": "טוען את כל התוספים",
|
||||
"load-failed": "לא ניתן לטעון את התוסף {{pluginName}}",
|
||||
"loaded": "התוסף \"{{pluginName}}\" נטען",
|
||||
"unload-failed": "הסרת התוסף \"{{pluginName}} נכשלה",
|
||||
"unloaded": "תוסף {{pluginName}} הורד"
|
||||
}
|
||||
}
|
||||
},
|
||||
"language": {
|
||||
"code": "he",
|
||||
"local-name": "עברית",
|
||||
"name": "Hebrew"
|
||||
},
|
||||
"main": {
|
||||
"console": {
|
||||
"did-finish-load": {
|
||||
"dev-tools": "הטעינה הסתיימה. הכלים לפמתחים נפתחו"
|
||||
},
|
||||
"i18n": {
|
||||
"loaded": "i18n נטען"
|
||||
},
|
||||
"second-instance": {
|
||||
"receive-command": "התקבלה פקודה מעבר פרוטוקל: {{command}}"
|
||||
},
|
||||
"theme": {
|
||||
"css-file-not-found": "קובץ ה-CSS \"{{cssFile}}\" לא קיים. מדלג"
|
||||
},
|
||||
"unresponsive": {
|
||||
"details": "שגיאה ללא תגובה\n{{error}}"
|
||||
},
|
||||
"when-ready": {
|
||||
"clearing-cache-after-20s": "מוחק קבצי מתמון"
|
||||
},
|
||||
"window": {
|
||||
"tried-to-render-offscreen": "ווינדוס ניסה להציג תוכן מחוץ למסך, גודל חלון={{windowSize}}, גודל מסך={{displaySize}}, מיקום={{position}}"
|
||||
}
|
||||
},
|
||||
"dialog": {
|
||||
"hide-menu-enabled": {
|
||||
"detail": "התפריט מוחבא, השתמש \"Alt\" על להציג אותו (או \"Esacpe\" אם משתמשים בתפריט בתוך האפליקציה)",
|
||||
"message": "הסתרת התפריט מופעלת",
|
||||
"title": "הסתרת התפריט הופעלה"
|
||||
},
|
||||
"need-to-restart": {
|
||||
"buttons": {
|
||||
"later": "אחר כך",
|
||||
"restart-now": "מתחיל את התוכנה מחדש עכשיו"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
15
src/i18n/resources/hr.json
Normal file
15
src/i18n/resources/hr.json
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"common": {
|
||||
"console": {
|
||||
"plugins": {
|
||||
"execute-failed": "Neuspjelo izvršenje plugina {{pluginName}}::{{contextName}}",
|
||||
"executed-at-ms": "Plugin{{pluginName}}::{{contextName}}{{je izvršen za {{ms}}ms"
|
||||
}
|
||||
}
|
||||
},
|
||||
"language": {
|
||||
"code": "hr",
|
||||
"local-name": "Hrvatski",
|
||||
"name": "Croatian"
|
||||
}
|
||||
}
|
||||
@ -3,13 +3,13 @@
|
||||
"console": {
|
||||
"plugins": {
|
||||
"execute-failed": "Nem sikerült futtatni a plugint {{pluginName}}::{{contextName}}",
|
||||
"executed-at-ms": "Plugin {{pluginName}}::{{contextName}} a {{ms}}ms időpontban végrehajtott",
|
||||
"executed-at-ms": "Plugin {{pluginName}}::{{contextName}} a {{ms}}ms időpontban lefutott",
|
||||
"initialize-failed": "Nem sikerült inicializálni a \"{{pluginName}}\" plugint",
|
||||
"load-all": "Összes bővítmény betöltése",
|
||||
"load-failed": "Nem sikerült betölteni a \"{{pluginName}}\" plugint",
|
||||
"loaded": "Plugin \"{{pluginName}}\" betöltve",
|
||||
"unload-failed": "Nem sikerült a \"{{pluginName}}\" bővítményt letölteni",
|
||||
"unloaded": "A \"{{pluginName}}\" bővítményt nem töltötték be"
|
||||
"loaded": "\"{{pluginName}}\" plugin betöltve",
|
||||
"unload-failed": "Nem sikerült a \"{{pluginName}}\" bővítményt kikapcsolni",
|
||||
"unloaded": "A \"{{pluginName}}\" bővítmény kikapcsolva"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -39,7 +39,7 @@
|
||||
"clearing-cache-after-20s": "Alkalmazás gyorsítótárának törlése"
|
||||
},
|
||||
"window": {
|
||||
"tried-to-render-offscreen": "Az ablak a képernyőn kívül próbált renderelni, windowSize={{windowSize}}, displaySize={{displaySize}}, position={{position}}"
|
||||
"tried-to-render-offscreen": "Az ablak a képernyőn kívül próbált betölteni, windowSize={{windowSize}}, displaySize={{displaySize}}, position={{position}}"
|
||||
}
|
||||
},
|
||||
"dialog": {
|
||||
@ -53,8 +53,8 @@
|
||||
"later": "Később",
|
||||
"restart-now": "Újraindítás most"
|
||||
},
|
||||
"detail": "A \"{{pluginName}}\" plugin újraindítást igényel a hatálybalépéshez",
|
||||
"message": "\"{{pluginName}}\" újra kell indítani",
|
||||
"detail": "A \"{{pluginName}}\" plugin újraindítást igényel a bekapcsoláshoz",
|
||||
"message": "\"{{pluginName}}\" nevű plugin-t újra kell indítani",
|
||||
"title": "Újraindítás szükséges"
|
||||
},
|
||||
"unresponsive": {
|
||||
@ -62,39 +62,681 @@
|
||||
"quit": "Kilépés",
|
||||
"relaunch": "Újraindítás",
|
||||
"wait": "Várj"
|
||||
}
|
||||
},
|
||||
"detail": "Elnézést a kellemetlenségért! Válaszdd ki mi történjen:",
|
||||
"message": "Az alkalmazás nem válaszol",
|
||||
"title": "Az ablak nem válaszol"
|
||||
},
|
||||
"update-available": {
|
||||
"buttons": {
|
||||
"disable": "Frissítések letiltása",
|
||||
"disable": "Frissítések kikapcsolása",
|
||||
"download": "Letöltés",
|
||||
"ok": "OK"
|
||||
},
|
||||
"detail": "Az új verzió elérhető, és letölthető a {{downloadLink}}",
|
||||
"detail": "Az új verzió elérhető, és letölthető az alábbi linken {{downloadLink}}",
|
||||
"message": "Új verzió áll rendelkezésre",
|
||||
"title": "Elérhető frissítés"
|
||||
"title": "Frissítés elérhető"
|
||||
}
|
||||
},
|
||||
"menu": {
|
||||
"about": "Névjegy",
|
||||
"navigation": {
|
||||
"label": "Navigálás",
|
||||
"label": "Navigáció",
|
||||
"submenu": {
|
||||
"copy-current-url": "Jelenlegi URL másolása",
|
||||
"go-back": "Vissza",
|
||||
"go-forward": "Előre",
|
||||
"quit": "Kilépés",
|
||||
"restart": "App újraindítása"
|
||||
"restart": "Alkalmazás újraindítása"
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"label": "Beállítások",
|
||||
"submenu": {
|
||||
"advanced-options": {
|
||||
"label": "Speciális beállítások"
|
||||
"label": "Speciális beállítások",
|
||||
"submenu": {
|
||||
"auto-reset-app-cache": "Az alkalmazás gyorsítótárának törlése indításkor",
|
||||
"disable-hardware-acceleration": "Hardveres gyorsítás kikapcsolása",
|
||||
"edit-config-json": "config.json szerkesztése",
|
||||
"override-user-agent": "Kliens felülírása",
|
||||
"restart-on-config-changes": "Újraindítás a konfigurációs változtatás után",
|
||||
"set-proxy": {
|
||||
"label": "Proxy beállítása",
|
||||
"prompt": {
|
||||
"label": "Proxy cím megadása: (Hagyja üresen a kikapcsoláshoz)",
|
||||
"placeholder": "Példa: SOCKS5://127.0.0.1:9999",
|
||||
"title": "Proxy beállítása"
|
||||
}
|
||||
},
|
||||
"toggle-dev-tools": "Fejlesztőeszközök BE/KI"
|
||||
}
|
||||
},
|
||||
"always-on-top": "Mindig látható",
|
||||
"auto-update": "Automatikus frissítés",
|
||||
"hide-menu": {
|
||||
"dialog": {
|
||||
"message": "A menü a következő indításnál rejtve lesz, használja az [Alt] billentyűt a megjelenítéséhez (vagy a backtick [`] billentyűt, ha az alkalmazás belső menüjét használja)",
|
||||
"title": "Menü elrejtés engedélyezve"
|
||||
},
|
||||
"label": "Menü elrejtése"
|
||||
},
|
||||
"language": {
|
||||
"dialog": {
|
||||
"message": "Az Újraindítást követően változik meg a nyelv",
|
||||
"title": "Megváltozott a nyelv"
|
||||
},
|
||||
"label": "Nyelv",
|
||||
"submenu": {
|
||||
"to-help-translate": "Szeretne a fordításban segíteni? Kattintson ide"
|
||||
}
|
||||
},
|
||||
"resume-on-start": "Indításkor az utolsó zene folytatása",
|
||||
"single-instance-lock": "Csak egy példány engedélyezése",
|
||||
"start-at-login": "Futtatás rendszerindításkor",
|
||||
"starting-page": {
|
||||
"label": "Indítási hely",
|
||||
"unset": "Visszaállítás"
|
||||
},
|
||||
"tray": {
|
||||
"label": "Tálca",
|
||||
"submenu": {
|
||||
"disabled": "Letiltva",
|
||||
"enabled-and-hide-app": "Aktív és az alkalmazás elrejtve",
|
||||
"enabled-and-show-app": "Aktív és az alkalmazás megjelenítve",
|
||||
"play-pause-on-click": "Lejátszás/Szünet az ikonra kattintással"
|
||||
}
|
||||
},
|
||||
"visual-tweaks": {
|
||||
"label": "Kinézeti beállítások",
|
||||
"submenu": {
|
||||
"like-buttons": {
|
||||
"default": "Alapértelmezett",
|
||||
"force-show": "Megjelenítés kényszerítése",
|
||||
"hide": "Elrejtése",
|
||||
"label": "Kedvelés gombok"
|
||||
},
|
||||
"remove-upgrade-button": "Előfizetés gombjának eltávolítása",
|
||||
"theme": {
|
||||
"dialog": {
|
||||
"button": {
|
||||
"cancel": "Mégse",
|
||||
"remove": "Eltávolít"
|
||||
},
|
||||
"remove-theme": "Biztos, hogy el akarja távolítani az egyéni témát?",
|
||||
"remove-theme-message": "Ez el fogja távolítani az egyéni témát"
|
||||
},
|
||||
"label": "Téma",
|
||||
"submenu": {
|
||||
"import-css-file": "Egyéni CSS fájl importálása",
|
||||
"no-theme": "Nincs téma"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"plugins": {
|
||||
"enabled": "Bekapcsolva",
|
||||
"label": "Bővítmények",
|
||||
"new": "ÚJ"
|
||||
},
|
||||
"view": {
|
||||
"label": "Nézet",
|
||||
"submenu": {
|
||||
"force-reload": "Kényszerített újratöltés",
|
||||
"reload": "Újratöltés",
|
||||
"reset-zoom": "Valós méret",
|
||||
"toggle-fullscreen": "Teljes képernyő be/ki",
|
||||
"zoom-in": "Nagyítás",
|
||||
"zoom-out": "Kicsinyítés"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tray": {
|
||||
"next": "Következő",
|
||||
"play-pause": "Lejátszás/Szünet",
|
||||
"previous": "Előző",
|
||||
"quit": "Kilépés",
|
||||
"restart": "YT Music újraindítása",
|
||||
"show": "Ablak megjelenítése",
|
||||
"tooltip": {
|
||||
"default": "YouTube Music",
|
||||
"with-song-info": "YouTube Music: {{artist}} - {{title}}"
|
||||
}
|
||||
}
|
||||
},
|
||||
"plugins": {
|
||||
"ad-speedup": {
|
||||
"description": "Ha reklám szól, elnémítja a hangot és a lejátszási sebességet 16x-ra állítja",
|
||||
"name": "Gyorsítás hozzáadása"
|
||||
},
|
||||
"adblocker": {
|
||||
"description": "Alapértelmezés szerint blokkolja az összes hirdetést és nyomkövetést",
|
||||
"menu": {
|
||||
"blocker": "Blokkoló"
|
||||
},
|
||||
"name": "Reklámblokkoló"
|
||||
},
|
||||
"album-actions": {
|
||||
"description": "Dislike, Undislike, Like, Unlike gombok hozzáadása, amivel ezt a lejátszási listán vagy albumon lévő összes dalra alkalmazza",
|
||||
"name": "Album műveletek"
|
||||
},
|
||||
"album-color-theme": {
|
||||
"description": "Dinamikus téma és vizuális effektek alkalmazása az album színpalettája alapján",
|
||||
"menu": {
|
||||
"color-mix-ratio": {
|
||||
"label": "Szín keverés aránya",
|
||||
"submenu": {
|
||||
"percent": "{{ratio}}%"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "Album színtéma"
|
||||
},
|
||||
"ambient-mode": {
|
||||
"description": "Fényhatás alkalmazása a videóból származó lágy színek vetítésével a képernyő hátterére",
|
||||
"menu": {
|
||||
"blur-amount": {
|
||||
"label": "Elmosódás mértéke",
|
||||
"submenu": {
|
||||
"pixels": "{{blurAmount}} képpontok"
|
||||
}
|
||||
},
|
||||
"buffer": {
|
||||
"label": "Puffer",
|
||||
"submenu": {
|
||||
"buffer": "{{buffer}}"
|
||||
}
|
||||
},
|
||||
"opacity": {
|
||||
"label": "Átlátszóság",
|
||||
"submenu": {
|
||||
"percent": "{{opacity}}%"
|
||||
}
|
||||
},
|
||||
"quality": {
|
||||
"label": "Minőség",
|
||||
"submenu": {
|
||||
"pixels": "{{quality}} képpont"
|
||||
}
|
||||
},
|
||||
"size": {
|
||||
"label": "Méret",
|
||||
"submenu": {
|
||||
"percent": "{{size}}%"
|
||||
}
|
||||
},
|
||||
"smoothness-transition": {
|
||||
"label": "Sima átmenet",
|
||||
"submenu": {
|
||||
"during": "{{interpolationTime}}s alatt"
|
||||
}
|
||||
},
|
||||
"use-fullscreen": {
|
||||
"label": "Teljes képernyő használata"
|
||||
}
|
||||
},
|
||||
"name": "Természetes mód"
|
||||
},
|
||||
"audio-compressor": {
|
||||
"description": "Hang tömörítés alkalmazása (csökkenti a jel legzajosabb részeinek hangerősségét, és emeli a legcsendesebb részek hangerősségét)",
|
||||
"name": "Hangtömörítő"
|
||||
},
|
||||
"blur-nav-bar": {
|
||||
"description": "Átlátszóvá és elmosódottá teszi a navigációs sávot",
|
||||
"name": "Navigációs sáv elmosása"
|
||||
},
|
||||
"bypass-age-restrictions": {
|
||||
"description": "A YouTube korellenőrzését kihagyja, ezáltal nem kel meg erősíteni a zene meghallgatása elött. (Automatikusan megerősítve lesz.)",
|
||||
"name": "Korellenőrzés kihagyása"
|
||||
},
|
||||
"captions-selector": {
|
||||
"description": "Felirat választó a YouTube Music zenékhez",
|
||||
"menu": {
|
||||
"autoload": "Automatikusan kiválasztja az utoljára használt feliratot",
|
||||
"disable-captions": "Alapértelmezetten nincsenek feliratok"
|
||||
},
|
||||
"name": "Feliratválasztó",
|
||||
"prompt": {
|
||||
"selector": {
|
||||
"label": "Jelenlegi feliratnyelv: {{language}}",
|
||||
"none": "Nincs",
|
||||
"title": "Felirat nyelvének kiválasztása"
|
||||
}
|
||||
},
|
||||
"templates": {
|
||||
"title": "Feliratválasztó megnyitása"
|
||||
}
|
||||
},
|
||||
"compact-sidebar": {
|
||||
"description": "Mindig becsukva tartja a bal oldali savót, ahol a Kezdőlap. Felfedezés, Könyvtár és egyebek láthatók. (Amit bármikor ki lehet nyitni)",
|
||||
"name": "Kompakt oldalsáv"
|
||||
},
|
||||
"crossfade": {
|
||||
"description": "Áttünést biztosít a dalok között, ami folytonossá teszi a zenehallgatást anélkül, hogy érezhető lenne a váltás",
|
||||
"menu": {
|
||||
"advanced": "Haladó"
|
||||
},
|
||||
"name": "Áttünés [Béta]",
|
||||
"prompt": {
|
||||
"options": {
|
||||
"multi-input": {
|
||||
"fade-in-duration": "Áttünés időtartama (ms)",
|
||||
"fade-out-duration": "Fokozatos halkítás időtartama (ms)",
|
||||
"fade-scaling": {
|
||||
"label": "Áttünés értéke",
|
||||
"linear": "Lineáris",
|
||||
"logarithmic": "Logaritmikus"
|
||||
},
|
||||
"seconds-before-end": "Áttünés N másodperccel a vége előtt"
|
||||
},
|
||||
"title": "Áttünési beállítások"
|
||||
}
|
||||
}
|
||||
},
|
||||
"disable-autoplay": {
|
||||
"description": "A Zenék nem fognak maguktól elindulni, a bővítmény használata során kézileg kel indítani a zenéket",
|
||||
"menu": {
|
||||
"apply-once": "Csak induláskor alkalmazza"
|
||||
},
|
||||
"name": "Automatikus lejátszás letiltása"
|
||||
},
|
||||
"discord": {
|
||||
"backend": {
|
||||
"already-connected": "Kapcsolódás kísérlete aktív kapcsolattal",
|
||||
"connected": "Kapcsolódva a Discord-hoz",
|
||||
"disconnected": "Kapcsolat bontva a Discord-al"
|
||||
},
|
||||
"description": "Mutassa meg barátainak, hogy mit hallgat a Rich Presence segítségével. (Ehez a Discord-on is engedélyezve kel lennie a Tevékenységállapot megosztásának [DC Beállítások -> Tevékenyég-adatvédelem -> Megoszthatod az észlelt tevékenységeidet másokkal])",
|
||||
"menu": {
|
||||
"auto-reconnect": "Automatikus újracsatlakozás",
|
||||
"clear-activity": "Tevékenység törlése",
|
||||
"clear-activity-after-timeout": "Tevékenység törlése időkorlát után",
|
||||
"connected": "Kapcsolódva",
|
||||
"disconnected": "Nincs Kapcsolódva",
|
||||
"hide-duration-left": "Hátralévő idő elrejtése",
|
||||
"hide-github-button": "GitHub link gombjának elrejtése",
|
||||
"play-on-youtube-music": "Lejátszás a YouTube Music-on",
|
||||
"set-inactivity-timeout": "Inaktivitási időkorlát beállítása"
|
||||
},
|
||||
"name": "Discord Rich Presence",
|
||||
"prompt": {
|
||||
"set-inactivity-timeout": {
|
||||
"label": "Írja be az inaktivitási időkorlátot másodpercben:",
|
||||
"title": "Inaktivitási időkorlát beállítása"
|
||||
}
|
||||
}
|
||||
},
|
||||
"downloader": {
|
||||
"backend": {
|
||||
"dialog": {
|
||||
"error": {
|
||||
"buttons": {
|
||||
"ok": "Rendben"
|
||||
},
|
||||
"message": "Hoppá! Elnézést, a letöltés sikertelen volt…",
|
||||
"title": "A letöltés során hiba történt!"
|
||||
},
|
||||
"start-download-playlist": {
|
||||
"buttons": {
|
||||
"ok": "Rendben"
|
||||
},
|
||||
"detail": "({{playlistSize}} dal)",
|
||||
"message": "A(z) {{playlistTitle}} lejátszási lista letöltése",
|
||||
"title": "A letöltés elindult"
|
||||
}
|
||||
},
|
||||
"feedback": {
|
||||
"conversion-progress": "Konvetálás: {{percent}}%",
|
||||
"converting": "Konvertálás…",
|
||||
"done": "Kész: {{filePath}}",
|
||||
"download-info": "Letöltés: {{artist}} - {{title}} [{{videoId}}",
|
||||
"download-progress": "Letöltés: {{percent}}%",
|
||||
"downloading": "Letöltés folyamatban…",
|
||||
"downloading-counter": "Letöltés: {{current}}/{{total}}…",
|
||||
"downloading-playlist": "Letöltés a lejátszási listáról \"{{playlistTitle}}\" - {{playlistSize}} dal ({{playlistId}})",
|
||||
"error-while-downloading": "Hiba a \"{{author}} - {{title}}\" letöltésekor: {{error}}",
|
||||
"folder-already-exists": "A {{playlistFolder}} nevű mappa már létezik",
|
||||
"getting-playlist-info": "Lejátszási lista információinak lekérése…",
|
||||
"loading": "Betöltés…",
|
||||
"playlist-has-only-one-song": "A lejátszási listában csak egy elem van, letöltés közvetlenül",
|
||||
"playlist-id-not-found": "Nem található lejátszási lista azonosítója",
|
||||
"playlist-is-empty": "Lejátszási lista üres",
|
||||
"playlist-is-mix-or-private": "Hiba a lejátszási lista információinak lekérésekor: győződjön meg róla, hogy nem privát vagy \"Saját egyveleg\" lejátszási lista\n\n{{error}}",
|
||||
"preparing-file": "Fájl előkészítése…",
|
||||
"saving": "Mentés…",
|
||||
"trying-to-get-playlist-id": "Playlist ID lekérése: {{playlistId}}",
|
||||
"video-id-not-found": "Videó nem található",
|
||||
"writing-id3": "ID3 címkék írása…"
|
||||
}
|
||||
},
|
||||
"description": "MP3 / forrás hanganyag letöltése közvetlenül az interfészről",
|
||||
"menu": {
|
||||
"choose-download-folder": "Letöltési mappa kiválasztása",
|
||||
"download-finish-settings": {
|
||||
"label": "Letöltés befejezéskor",
|
||||
"prompt": {
|
||||
"last-percent": "x százalék után",
|
||||
"last-seconds": "Utolsó x másodperc"
|
||||
},
|
||||
"submenu": {
|
||||
"advanced": "Speciális",
|
||||
"enabled": "Engedélyezve",
|
||||
"mode": "Időmód",
|
||||
"percent": "Százalék",
|
||||
"seconds": "Másodpercek"
|
||||
}
|
||||
},
|
||||
"download-playlist": "Lejátszási lista letöltése",
|
||||
"presets": "Sablonok",
|
||||
"skip-existing": "Meglévő fájlok kihagyása"
|
||||
},
|
||||
"name": "Letöltő",
|
||||
"renderer": {
|
||||
"can-not-update-progress": "A haladást nem lehet frissíteni"
|
||||
},
|
||||
"templates": {
|
||||
"button": "Letöltés"
|
||||
}
|
||||
},
|
||||
"exponential-volume": {
|
||||
"description": "Az hangerő csúszka exponenciálissá tételével könnyebbé válik az alacsony hangerő kiválasztása.",
|
||||
"name": "Exponenciális hangerő"
|
||||
},
|
||||
"in-app-menu": {
|
||||
"description": "Menüsávok stílusos, sötét vagy album-színű megjelenítése",
|
||||
"menu": {
|
||||
"hide-dom-window-controls": "DOM ablakvezérlők elrejtése"
|
||||
},
|
||||
"name": "Alkalmazáson belüli menü"
|
||||
},
|
||||
"lumiastream": {
|
||||
"description": "Lumia Stream támogatás hozzáadása",
|
||||
"name": "Lumia Stream [Béta]"
|
||||
},
|
||||
"lyrics-genius": {
|
||||
"description": "Dalszöveg támogatást ad a legtöbb dalhoz",
|
||||
"menu": {
|
||||
"romanized-lyrics": "Latin betűs dalszövegek"
|
||||
},
|
||||
"name": "Lyrics Genius",
|
||||
"renderer": {
|
||||
"fetched-lyrics": "Dalszövegek lekérése a Genius-ról"
|
||||
}
|
||||
},
|
||||
"music-together": {
|
||||
"description": "Lehetővé teszi a lejátszási listák megosztását másokkal. Amikor a házigazda lejátszik egy dalt, mindenki más is ugyanazt a dalt fogja hallani",
|
||||
"dialog": {
|
||||
"enter-host": "Adja meg a házigazda azonosítóját"
|
||||
},
|
||||
"internal": {
|
||||
"save": "Mentés",
|
||||
"track-source": "Zeneszám forrása",
|
||||
"unknown-user": "Ismeretlen felhasználó"
|
||||
},
|
||||
"menu": {
|
||||
"click-to-copy-id": "Házigazda azonosítójának másolása",
|
||||
"close": "Zene együtt bezárása",
|
||||
"connected-users": "Csatlakozott felhasználók",
|
||||
"disconnect": "Zene együtt kapcsolatának megszakítása",
|
||||
"empty-user": "Nincs csatlakozva felhasználó",
|
||||
"host": "Music Together Házigazda",
|
||||
"join": "Csatlakozás a Zene együtt-höz",
|
||||
"permission": {
|
||||
"all": "Engedélyezi a vendégeknek a lejátszási lista és a lejátszó vezérlését",
|
||||
"host-only": "Csak a házigazda tudja vezérelni a lejátszási listát és a lejátszót",
|
||||
"playlist": "Engedélyezi a vendégeknek a lejátszási lista vezérlését"
|
||||
},
|
||||
"status": {
|
||||
"disconnected": "Kapcsolat bontva",
|
||||
"guest": "Csatlakozva vendégként",
|
||||
"host": "Csatlakozva házigazdaként"
|
||||
}
|
||||
},
|
||||
"name": "Zene együtt [Béta]",
|
||||
"toast": {
|
||||
"add-song-failed": "Sikertelen volt a dal hozzáadása",
|
||||
"closed": "Zene együtt bezárva",
|
||||
"disconnected": "Kapcsolat megszakadt a Music Together-el",
|
||||
"host-failed": "Sikertelen volt a Zene együtt indítása",
|
||||
"id-copied": "Házigazda azonosító a vágólapra másolva",
|
||||
"id-copy-failed": "Nem sikerült a Házigazda azonosítóját a vágólapra másolni",
|
||||
"join-failed": "Nem sikerült csatlakozni a Music Together-hez",
|
||||
"joined": "Csatlakozott a Music Together-hez",
|
||||
"permission-changed": "Music Together engedély megváltoztatva \"{{permission}}\" -re",
|
||||
"remove-song-failed": "A dal eltávolítása sikertelen",
|
||||
"user-connected": "{{name}} csatlakozott a Music Together-hez",
|
||||
"user-disconnected": "{{name}} elhagyta a Music Together-t"
|
||||
}
|
||||
},
|
||||
"navigation": {
|
||||
"description": "Következő/Vissza navigációs nyilak közvetlenül az interfészbe integrálva, mint a kedvenc böngésződben",
|
||||
"name": "Navigáció"
|
||||
},
|
||||
"no-google-login": {
|
||||
"description": "A Bejelentkezés gomb eltávolítása az interfészről (Jobb fentről eltünik a bejelentkezés gomb.)",
|
||||
"name": "Nincs Google bejelentkezés"
|
||||
},
|
||||
"notifications": {
|
||||
"description": "Értesítés megjelenítése, amikor egy dal elindul (interaktív értesítések elérhetők Windows-on)",
|
||||
"menu": {
|
||||
"interactive": "Interaktív Értesítések",
|
||||
"interactive-settings": {
|
||||
"label": "Interaktív beállítások",
|
||||
"submenu": {
|
||||
"hide-button-text": "Gombok szövegének elrejtése",
|
||||
"refresh-on-play-pause": "Frissítés lejátszás/szünet megnyomásakor",
|
||||
"tray-controls": "Megnyitás/Bezárás tálca ikonra kattintva"
|
||||
}
|
||||
},
|
||||
"priority": "Értesítési prioritás",
|
||||
"toast-style": "Értesítés stílusa",
|
||||
"unpause-notification": "Értesítés megjelenítése a lejátszás folytatásakor"
|
||||
},
|
||||
"name": "Értesítések"
|
||||
},
|
||||
"picture-in-picture": {
|
||||
"description": "Lehetővé teszi az alkalmazás kép a képben módra váltását",
|
||||
"menu": {
|
||||
"always-on-top": "Mindig látható",
|
||||
"hotkey": {
|
||||
"label": "Gyorsbillentyű",
|
||||
"prompt": {
|
||||
"keybind-options": {
|
||||
"hotkey": "Gyorsbillentyű"
|
||||
},
|
||||
"label": "Válassz egy gyorsbillentyűt a kép a képben mód váltásához",
|
||||
"title": "Kép a képben gyorsbillentyű"
|
||||
}
|
||||
},
|
||||
"save-window-position": "Ablakpozíciójának mentése",
|
||||
"save-window-size": "Ablakméretének mentése",
|
||||
"use-native-pip": "A böngésző natív PiP(Kép a képben) használata"
|
||||
},
|
||||
"name": "Kép a képben",
|
||||
"templates": {
|
||||
"button": "Kép a képben"
|
||||
}
|
||||
},
|
||||
"playback-speed": {
|
||||
"description": "Hallgass gyorsan, hallgass lassan! Hozzáad egy csúszkát, amely szabályozza a dal sebességét",
|
||||
"name": "Lejátszás sebessége",
|
||||
"templates": {
|
||||
"button": "Sebesség"
|
||||
}
|
||||
},
|
||||
"precise-volume": {
|
||||
"description": "A hangerő precíz szabályozása egérgörgővel/gyorsbillentyűkkel, egy egyedi HUD és testreszabható hangerő csuszka segítségével",
|
||||
"menu": {
|
||||
"arrows-shortcuts": "Helyi nyíl-billentyűkkel való vezérlés",
|
||||
"custom-volume-steps": "Egyedi hangerőléptetés beállítása",
|
||||
"global-shortcuts": "Globális Gyorsbillentyűk"
|
||||
},
|
||||
"name": "Precíz hangerő",
|
||||
"prompt": {
|
||||
"global-shortcuts": {
|
||||
"keybind-options": {
|
||||
"decrease": "Hangerő csökkentése",
|
||||
"increase": "Hangerő növelése"
|
||||
},
|
||||
"label": "Válaszd ki a globális hangerő gyorsbillentyűket:",
|
||||
"title": "Globális hangerő gyorsbillentyűk"
|
||||
},
|
||||
"volume-steps": {
|
||||
"label": "Hangerő növelés/csökkentés léptékének kiválasztása",
|
||||
"title": "Hangerő lépték"
|
||||
}
|
||||
}
|
||||
},
|
||||
"quality-changer": {
|
||||
"backend": {
|
||||
"dialog": {
|
||||
"quality-changer": {
|
||||
"detail": "Jelenlegi minőség: {{quality}}",
|
||||
"message": "Válaszd ki a videó minőségét:",
|
||||
"title": "Válaszd ki a videó minőségét"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": "Lehetővé teszi a videó minőségének megváltoztatását egy gombbal a videó fedvényen",
|
||||
"name": "Videóminőség modosító"
|
||||
},
|
||||
"scrobbler": {
|
||||
"description": "Scrobbling támogatás hozzáadása (pl. last.fm, ListenBrainz)",
|
||||
"dialog": {
|
||||
"lastfm": {
|
||||
"auth-failed": {
|
||||
"message": "Last.fm hitelesítése nem sikerült\nA felugró ablak elrejtése a következő újraindításig.",
|
||||
"title": "Hitelesítés sikertelen"
|
||||
}
|
||||
}
|
||||
},
|
||||
"menu": {
|
||||
"lastfm": {
|
||||
"api-settings": "Last.fm API beállítások"
|
||||
},
|
||||
"listenbrainz": {
|
||||
"token": "Add meg a ListenBrainz felhasználói tokenedet"
|
||||
}
|
||||
},
|
||||
"prompt": {
|
||||
"lastfm": {
|
||||
"api-key": "Last.fm API kulcs",
|
||||
"api-secret": "Last.fm titkos API kulcs"
|
||||
},
|
||||
"listenbrainz": {
|
||||
"token": {
|
||||
"label": "Add meg a ListenBrainz felhasználói tokenedet:",
|
||||
"title": "ListenBrainz kulcs"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"shortcuts": {
|
||||
"description": "Lehetővé teszi globális gyorsbillentyűk beállítását a lejátszáshoz (lejátszás/szünet/következő/előző), valamint a média OSD kikapcsolását a médiagombok felülírásával. Bekapcsolja a Ctrl/CMD + F billentyűkombinációt a kereséshez, a Linux MPRIS támogatását a médiagombokhoz, és egyedi gyorsbillentyűket a haladó felhasználók számára",
|
||||
"menu": {
|
||||
"override-media-keys": "Médiagombok felülírása",
|
||||
"set-keybinds": "Globális zenevezérlők beállítása"
|
||||
},
|
||||
"name": "Gyorsbillentyűk (& MPRIS)",
|
||||
"prompt": {
|
||||
"keybind": {
|
||||
"keybind-options": {
|
||||
"next": "Következő",
|
||||
"play-pause": "Lejátszás / Szünet",
|
||||
"previous": "Előző"
|
||||
},
|
||||
"label": "Globális billentyűparancsok választása a dalok vezérléséhez:",
|
||||
"title": "Globális gyorsbillentyűk"
|
||||
}
|
||||
}
|
||||
},
|
||||
"skip-disliked-songs": {
|
||||
"description": "Kihagyja a nem kedvelt dalokat",
|
||||
"name": "Nem kedvelt dal kihagyása"
|
||||
},
|
||||
"skip-silences": {
|
||||
"description": "Automatikusan kihagyja a csendes részeket a dalokban",
|
||||
"name": "Csend kihagyása"
|
||||
},
|
||||
"sponsorblock": {
|
||||
"description": "Automatikusan kihagyja a nem zenés részeket, mint például az intro/outro vagy a zenei videók olyan részeit, ahol a zene nem szól",
|
||||
"name": "SzponzorBlokk"
|
||||
},
|
||||
"synced-lyrics": {
|
||||
"description": "Szinkronizált dalszövegeket biztosít dalokhoz, LRClib-hez hasonló szolgáltatókat használva.",
|
||||
"errors": {
|
||||
"fetch": "⚠️ - Hiba történt a dalszövegek lekérése közben. Kérlek, próbáld újra később.",
|
||||
"not-found": "⚠️ - Nem található dalszöveg ehhez a zenéhez."
|
||||
},
|
||||
"menu": {
|
||||
"line-effect": {
|
||||
"submenu": {
|
||||
"scale": {
|
||||
"label": "Mérték"
|
||||
}
|
||||
}
|
||||
},
|
||||
"precise-timing": {
|
||||
"label": "Dalszöveg tökéletes szinkronizálása"
|
||||
}
|
||||
},
|
||||
"name": "Szinkronizált dalszövegek",
|
||||
"refetch-btn": {
|
||||
"fetching": "Lekérés folyamatban...",
|
||||
"normal": "Dalszöveg újra lekérése"
|
||||
},
|
||||
"warnings": {
|
||||
"duration-mismatch": "⚠️ - A dalszövegek időzítése eltérhet a zene hossza miatt.",
|
||||
"inexact": "⚠️ - Ennek a zenének a dalszövege pontatlan lehet",
|
||||
"instrumental": "⚠️ - Ez egy hangszerekkel játszott zene"
|
||||
}
|
||||
},
|
||||
"taskbar-mediacontrol": {
|
||||
"description": "Lejátszás vezérlése a Windows tálcáról",
|
||||
"name": "Médiavezérlés a tálcán"
|
||||
},
|
||||
"touchbar": {
|
||||
"description": "macOS felhasználók számára hozzáad egy widgetet a TouchBar-hoz",
|
||||
"name": "TouchBar"
|
||||
},
|
||||
"tuna-obs": {
|
||||
"description": "Integráció az OBS Tuna pluginjával",
|
||||
"name": "Tuna OBS"
|
||||
},
|
||||
"video-toggle": {
|
||||
"description": "Hozzáad egy gombot a Videó/Dal mód közötti váltáshoz. Opcionálisan teljesen eltávolíthatja a videó fület is",
|
||||
"menu": {
|
||||
"align": {
|
||||
"label": "Igazítás",
|
||||
"submenu": {
|
||||
"left": "Balra",
|
||||
"middle": "Középre",
|
||||
"right": "Jobbra"
|
||||
}
|
||||
},
|
||||
"force-hide": "Videó fül kényszeritett eltávolítása",
|
||||
"mode": {
|
||||
"label": "Mód",
|
||||
"submenu": {
|
||||
"custom": "Egyedi kapcsoló",
|
||||
"disabled": "Letiltva",
|
||||
"native": "Natív kapcsoló"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "Videó váltó",
|
||||
"templates": {
|
||||
"button": "Zeneszám"
|
||||
}
|
||||
},
|
||||
"visualizer": {
|
||||
"description": "Vizualizációt ad a lejátszóhoz",
|
||||
"menu": {
|
||||
"visualizer-type": "Vizualizáció típus"
|
||||
},
|
||||
"name": "Vizualizáció"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -30,7 +30,7 @@
|
||||
"receive-command": "Menerima instruksi lewat protokol: \"{{command}}\""
|
||||
},
|
||||
"theme": {
|
||||
"css-file-not-found": "CSS file \"{{cssFile}}\" tidak ada, mengabaikan"
|
||||
"css-file-not-found": "File CSS \"{{cssFile}}\" tidak ditemukan, mengabaikan"
|
||||
},
|
||||
"unresponsive": {
|
||||
"details": "Kesalahan Tidak Responsif!\n{{error}}"
|
||||
@ -45,17 +45,17 @@
|
||||
"dialog": {
|
||||
"hide-menu-enabled": {
|
||||
"detail": "Menu tersembunyi, gunakan 'Alt' untuk menampilkannya (atau 'Escape' jika menggunakan Menu Dalam Aplikasi)",
|
||||
"message": "Menu Sembunyikan diaktifkan",
|
||||
"message": "Sembunyikan Menu diaktifkan",
|
||||
"title": "Sembunyikan Menu Diaktifkan"
|
||||
},
|
||||
"need-to-restart": {
|
||||
"buttons": {
|
||||
"later": "Kemudian",
|
||||
"later": "Nanti",
|
||||
"restart-now": "Restart Sekarang"
|
||||
},
|
||||
"detail": "\"{{pluginName}}\" Plugin memerlukan pengaktifan ulang agar dapat diterapkan",
|
||||
"message": "\"{{pluginName}}\" harus dimulai ulang",
|
||||
"title": "Diperlukan Restart"
|
||||
"title": "Restart Diperlukan"
|
||||
},
|
||||
"unresponsive": {
|
||||
"buttons": {
|
||||
@ -158,6 +158,14 @@
|
||||
},
|
||||
"remove-upgrade-button": "Hapus tombol peningkatan",
|
||||
"theme": {
|
||||
"dialog": {
|
||||
"button": {
|
||||
"cancel": "Batalkan",
|
||||
"remove": "Hapus"
|
||||
},
|
||||
"remove-theme": "Apakah kamu yakin ingin menhapus tema ini?",
|
||||
"remove-theme-message": "Ini akan menghapus tema ini"
|
||||
},
|
||||
"label": "Tema",
|
||||
"submenu": {
|
||||
"import-css-file": "Impor file CSS khusus",
|
||||
@ -194,11 +202,15 @@
|
||||
"show": "Tampilkan jendela",
|
||||
"tooltip": {
|
||||
"default": "YouTube Musik",
|
||||
"with-song-info": "YouTube Music: {{artist}} - {{title}}"
|
||||
"with-song-info": "YouTube Musik: {{artist}} - {{title}}"
|
||||
}
|
||||
}
|
||||
},
|
||||
"plugins": {
|
||||
"ad-speedup": {
|
||||
"description": "Jika iklan diputar, audio akan dimatikan dan kecepatan pemutaran akan diatur ke 16x",
|
||||
"name": "Percepatan Iklan"
|
||||
},
|
||||
"adblocker": {
|
||||
"description": "Blokir semua iklan dan pelacakan di luar kotak",
|
||||
"menu": {
|
||||
@ -267,6 +279,49 @@
|
||||
},
|
||||
"name": "Mode ambient"
|
||||
},
|
||||
"api-server": {
|
||||
"description": "Menambahkan server API untuk mengontrol pemutar",
|
||||
"dialog": {
|
||||
"request": {
|
||||
"buttons": {
|
||||
"allow": "Izinkan",
|
||||
"deny": "Menolak"
|
||||
},
|
||||
"message": "Izinkan {{ID}} ({{origin}}) untuk mengakses API?",
|
||||
"title": "Permintaan otorisasi API"
|
||||
}
|
||||
},
|
||||
"menu": {
|
||||
"auth-strategy": {
|
||||
"label": "Strategi otorisasi",
|
||||
"submenu": {
|
||||
"auth-at-first": {
|
||||
"label": "Otorisasi pada permintaan pertama"
|
||||
},
|
||||
"none": {
|
||||
"label": "Tidak ada otorisasi"
|
||||
}
|
||||
}
|
||||
},
|
||||
"hostname": {
|
||||
"label": "Nama host"
|
||||
},
|
||||
"port": {
|
||||
"label": "Port"
|
||||
}
|
||||
},
|
||||
"name": "API Server [Beta]",
|
||||
"prompt": {
|
||||
"hostname": {
|
||||
"label": "Masukkan nama host (seperti 0.0.0.0) untuk server API:",
|
||||
"title": "Nama host"
|
||||
},
|
||||
"port": {
|
||||
"label": "Masukkan port untuk server API:",
|
||||
"title": "Port"
|
||||
}
|
||||
}
|
||||
},
|
||||
"audio-compressor": {
|
||||
"description": "Menerapkan kompresi pada audio (mengurangi volume pada bagian paling keras dari sinyal dan meningkatkan volume pada bagian paling lembut)",
|
||||
"name": "Kompresi suara"
|
||||
@ -402,6 +457,21 @@
|
||||
"description": "Unduh MP3 / sumber suara secara langsung via antarmuka",
|
||||
"menu": {
|
||||
"choose-download-folder": "Pilih folder unduhan",
|
||||
"download-finish-settings": {
|
||||
"label": "Unduh setelah selesai",
|
||||
"prompt": {
|
||||
"last-percent": "x persen terakhir",
|
||||
"last-seconds": "x detik terakhir",
|
||||
"title": "Konfigurasikan kapan akan mengunduh"
|
||||
},
|
||||
"submenu": {
|
||||
"advanced": "Lanjutan",
|
||||
"enabled": "Diaktifkan",
|
||||
"mode": "Mode waktu",
|
||||
"percent": "Persen",
|
||||
"seconds": "Detik"
|
||||
}
|
||||
},
|
||||
"download-playlist": "Unduh daftar putar",
|
||||
"presets": "Prasetel",
|
||||
"skip-existing": "Lewati berkas yang sudah ada"
|
||||
@ -641,6 +711,59 @@
|
||||
"description": "Otomatis Melewati bagian yang bukan musik seperti intro/outro atau bagian dari video musik di mana lagu tidak dimainkan",
|
||||
"name": "SponsorBlock"
|
||||
},
|
||||
"synced-lyrics": {
|
||||
"description": "Menyediakan lirik lagu yang disinkronkan, menggunakan penyedia seperti LRClib.",
|
||||
"errors": {
|
||||
"fetch": "⚠️ - Terjadi kesalahan saat mengambil lirik. Coba lagi nanti.",
|
||||
"not-found": "⚠️ - Tidak ada lirik yang ditemukan untuk lagu ini."
|
||||
},
|
||||
"menu": {
|
||||
"default-text-string": {
|
||||
"label": "Karakter default antara lirik",
|
||||
"tooltip": "Pilih karakter default yang akan digunakan untuk celah antar lirik"
|
||||
},
|
||||
"line-effect": {
|
||||
"label": "Efek garis",
|
||||
"submenu": {
|
||||
"focus": {
|
||||
"label": "Fokus",
|
||||
"tooltip": "Jadikan hanya baris saat ini berwarna putih"
|
||||
},
|
||||
"offset": {
|
||||
"label": "Offset",
|
||||
"tooltip": "Mengimbangi garis saat ini di sebelah kanan"
|
||||
},
|
||||
"scale": {
|
||||
"label": "Skala",
|
||||
"tooltip": "Skala garis saat ini"
|
||||
}
|
||||
},
|
||||
"tooltip": "Pilih efek yang akan diterapkan ke baris saat ini"
|
||||
},
|
||||
"precise-timing": {
|
||||
"label": "Buat liriknya tersinkronisasi dengan sempurna",
|
||||
"tooltip": "Hitung hingga milidetik tampilan baris berikutnya (dapat berdampak kecil pada kinerja)"
|
||||
},
|
||||
"show-lyrics-even-if-inexact": {
|
||||
"label": "Tampilkan lirik meskipun tidak tepat",
|
||||
"tooltip": "Jika lagu tidak ditemukan, plugin akan mencoba lagi dengan kueri pencarian yang berbeda.\nHasil dari percobaan kedua mungkin tidak tepat."
|
||||
},
|
||||
"show-time-codes": {
|
||||
"label": "Tampilkan kode waktu",
|
||||
"tooltip": "Tampilkan kode waktu di samping lirik"
|
||||
}
|
||||
},
|
||||
"name": "Lirik yang Disinkronkan",
|
||||
"refetch-btn": {
|
||||
"fetching": "Mengambil...",
|
||||
"normal": "Ambil ulang lirik"
|
||||
},
|
||||
"warnings": {
|
||||
"duration-mismatch": "⚠️ - Liriknya mungkin tidak sinkron karena ketidakcocokan durasi.",
|
||||
"inexact": "⚠️ - Lirik lagu ini mungkin tidak tepat",
|
||||
"instrumental": "⚠️ - Ini adalah lagu instrumental"
|
||||
}
|
||||
},
|
||||
"taskbar-mediacontrol": {
|
||||
"description": "Kendalikan pemutaran dari bilah alat Windows",
|
||||
"name": "Pengendali Media di Bilah Alat"
|
||||
|
||||
@ -2,14 +2,14 @@
|
||||
"common": {
|
||||
"console": {
|
||||
"plugins": {
|
||||
"execute-failed": "Tókst ekki að framkvæma viðbót {{pluginName}}::{{contextName}}",
|
||||
"executed-at-ms": "Viðbótin {{pluginName}}::{{contextName}} var framkvæmd í {{ms}}ms",
|
||||
"initialize-failed": "Tókst ekki að frumstilla viðbót \"{{pluginName}}\"",
|
||||
"load-all": "Er að hlaða öllum viðbótum",
|
||||
"load-failed": "Tókst ekki að hlaða viðbótinni \"{{pluginName}}\"",
|
||||
"loaded": "Viðbót \"{{pluginName}}\" hlaðið",
|
||||
"unload-failed": "Tókst ekki að afhlaða viðbótinni \"{{pluginName}}\"",
|
||||
"unloaded": "Viðbótin „{{pluginName}}“ óhlaðin"
|
||||
"execute-failed": "Tókst ekki að framkvæma tengiforrit {{pluginName}}::{{contextName}}",
|
||||
"executed-at-ms": "Tengiforrit {{pluginName}}::{{contextName}} var framkvæmd í {{ms}}ms",
|
||||
"initialize-failed": "Tókst ekki að frumstilla tengiforrit \"{{pluginName}}\"",
|
||||
"load-all": "Er að hlaða öllum tengiforritum",
|
||||
"load-failed": "Tókst ekki að hlaða tengiforritinu \"{{pluginName}}\"",
|
||||
"loaded": "Tengiforrit \"{{pluginName}}\" hlaðið",
|
||||
"unload-failed": "Tókst ekki að afhlaða tengiforritinu \"{{pluginName}}\"",
|
||||
"unloaded": "Tengiforrit „{{pluginName}}“ óhlaðin"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -53,7 +53,7 @@
|
||||
"later": "Seinna",
|
||||
"restart-now": "Endurræsa Núna"
|
||||
},
|
||||
"detail": "\"{{pluginName}}\" viðbótin þarfnast endurræsingar til að taka gildi",
|
||||
"detail": "\"{{pluginName}}\" tengiforrit þarfnast endurræsingar til að taka gildi",
|
||||
"message": "\"{{pluginName}}\" þarf að endurræsa",
|
||||
"title": "Endurræsa Krafist"
|
||||
},
|
||||
@ -158,6 +158,14 @@
|
||||
},
|
||||
"remove-upgrade-button": "Fjarlægja uppgræðartakkan",
|
||||
"theme": {
|
||||
"dialog": {
|
||||
"button": {
|
||||
"cancel": "Hætta við",
|
||||
"remove": "Fjarlægja"
|
||||
},
|
||||
"remove-theme": "Ertu viss um að þú viljir fjarlægja þetta sérsniðna þema?",
|
||||
"remove-theme-message": "Þetta mun fjarlægja sérsniðna þema"
|
||||
},
|
||||
"label": "Þema",
|
||||
"submenu": {
|
||||
"import-css-file": "Flytja inn sérsniðna CSS skrá",
|
||||
@ -170,7 +178,7 @@
|
||||
},
|
||||
"plugins": {
|
||||
"enabled": "Virkt",
|
||||
"label": "Viðbætur",
|
||||
"label": "Tengiforrit",
|
||||
"new": "NÝR"
|
||||
},
|
||||
"view": {
|
||||
@ -199,6 +207,10 @@
|
||||
}
|
||||
},
|
||||
"plugins": {
|
||||
"ad-speedup": {
|
||||
"description": "Ef auglýsing spilar slökknar hún á hljóðinu og stillir spilunarhraðann á 16x",
|
||||
"name": "Auglýsingahraða"
|
||||
},
|
||||
"adblocker": {
|
||||
"description": "Lokaðu fyrir allar auglýsingar og rakningar úr kassanum",
|
||||
"menu": {
|
||||
@ -220,7 +232,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "Albúmslitaþema"
|
||||
"name": "Albúmlitaþema"
|
||||
},
|
||||
"ambient-mode": {
|
||||
"description": "Beitir lýsingaráhrifum með því að varpa mildum litum úr myndbandinu í bakgrunn skjásins",
|
||||
@ -267,6 +279,49 @@
|
||||
},
|
||||
"name": "Umhverfishamur"
|
||||
},
|
||||
"api-server": {
|
||||
"description": "Bætir API netþjóni til að stjórna spilaranum",
|
||||
"dialog": {
|
||||
"request": {
|
||||
"buttons": {
|
||||
"allow": "Leyfa",
|
||||
"deny": "Óleyfa"
|
||||
},
|
||||
"message": "Leyfa {{ID}} ({{origin}}) að aðganga API-ið?",
|
||||
"title": "API heimildarbeiðni"
|
||||
}
|
||||
},
|
||||
"menu": {
|
||||
"auth-strategy": {
|
||||
"label": "Heimildarstefna",
|
||||
"submenu": {
|
||||
"auth-at-first": {
|
||||
"label": "Heimila á fyrst beiðni"
|
||||
},
|
||||
"none": {
|
||||
"label": "Nei heimild"
|
||||
}
|
||||
}
|
||||
},
|
||||
"hostname": {
|
||||
"label": "Hýsitölvunafn"
|
||||
},
|
||||
"port": {
|
||||
"label": "Tengi"
|
||||
}
|
||||
},
|
||||
"name": "API-Netþjónn [Beta]",
|
||||
"prompt": {
|
||||
"hostname": {
|
||||
"label": "Sláðu inn hýsitölvunafnið (eins og 0.0.0.0) fyrir API-netþjónninn:",
|
||||
"title": "Hýsitölvunafn"
|
||||
},
|
||||
"port": {
|
||||
"label": "Sláðu inn tengið fyrir API-netþjónninn:",
|
||||
"title": "Tengi"
|
||||
}
|
||||
}
|
||||
},
|
||||
"audio-compressor": {
|
||||
"description": "Notaðu þjöppun á hljóð (lækkar hljóðstyrk háværustu hluta merkis og hækkar hljóðstyrk í mýkstu hlutunum)",
|
||||
"name": "Hljóðþjöppu"
|
||||
@ -334,7 +389,7 @@
|
||||
"backend": {
|
||||
"already-connected": "Reyndi að tengja við virka tengingu",
|
||||
"connected": "Tengdur við Discord",
|
||||
"disconnected": "Aftengdur við Discord"
|
||||
"disconnected": "Aftengdur frá Discord"
|
||||
},
|
||||
"description": "Sýndu vinum þínum hvað þú hlustar á með Rík Nærvera",
|
||||
"menu": {
|
||||
@ -402,6 +457,21 @@
|
||||
"description": "Niðurhalar MP3 / upprunahljóði beint úr viðmótinu",
|
||||
"menu": {
|
||||
"choose-download-folder": "Veldu niðurhalsmöppu",
|
||||
"download-finish-settings": {
|
||||
"label": "Sækja þegar lokið",
|
||||
"prompt": {
|
||||
"last-percent": "Eftir x sekúndur",
|
||||
"last-seconds": "Síðustu x sekúndur",
|
||||
"title": "Stilla hvenær á að hlaða niður"
|
||||
},
|
||||
"submenu": {
|
||||
"advanced": "Ítarlegri",
|
||||
"enabled": "Virkt",
|
||||
"mode": "Tímastilling",
|
||||
"percent": "Hlutfall",
|
||||
"seconds": "Sekúndur"
|
||||
}
|
||||
},
|
||||
"download-playlist": "Sækja spilunarlista",
|
||||
"presets": "Forstillingar",
|
||||
"skip-existing": "Slepptu núverandi skrám"
|
||||
@ -641,6 +711,37 @@
|
||||
"description": "Sleppur sjálfkrafa hlutum sem ekki eru tónlist, eins og inngangur/lok eða hlutar af tónlistarmyndböndum þar sem lag er ekki að spila",
|
||||
"name": "Styrktarblokk"
|
||||
},
|
||||
"synced-lyrics": {
|
||||
"description": "Veitir samstillta texta við lög, með því að nota veitur eins og LRClib.",
|
||||
"errors": {
|
||||
"not-found": "⚠️ - Enginn texti fannst við þetta lag."
|
||||
},
|
||||
"menu": {
|
||||
"line-effect": {
|
||||
"label": "Línuafleiðing",
|
||||
"submenu": {
|
||||
"focus": {
|
||||
"label": "Brennidepill",
|
||||
"tooltip": "Gerðu aðeins núverandi línu hvíta"
|
||||
},
|
||||
"offset": {
|
||||
"label": "Fararbyrjun"
|
||||
},
|
||||
"scale": {
|
||||
"label": "Skali",
|
||||
"tooltip": "Skala núverandi línu"
|
||||
}
|
||||
}
|
||||
},
|
||||
"show-time-codes": {
|
||||
"label": "Sýna tímikóðar"
|
||||
}
|
||||
},
|
||||
"name": "Samstilltur texti",
|
||||
"warnings": {
|
||||
"instrumental": "⚠️ - Þetta er hljóðfærilegt lag"
|
||||
}
|
||||
},
|
||||
"taskbar-mediacontrol": {
|
||||
"description": "Stjórnaðu spilun frá Windows verkefnastikunni þinni",
|
||||
"name": "Miðlunarstýringarverkefnastikunnar"
|
||||
|
||||
@ -158,6 +158,14 @@
|
||||
},
|
||||
"remove-upgrade-button": "Rimuovi il pulsante aggiorna",
|
||||
"theme": {
|
||||
"dialog": {
|
||||
"button": {
|
||||
"cancel": "Cancella",
|
||||
"remove": "Rimuovi"
|
||||
},
|
||||
"remove-theme": "Sicuro di voler rimuovere il tema personalizzato?",
|
||||
"remove-theme-message": "Questo rimuoverà il tema personalizzato"
|
||||
},
|
||||
"label": "Tema",
|
||||
"submenu": {
|
||||
"import-css-file": "Importa file CSS personalizzato",
|
||||
@ -199,6 +207,10 @@
|
||||
}
|
||||
},
|
||||
"plugins": {
|
||||
"ad-speedup": {
|
||||
"description": "Se viene riprodotto un annuncio, l'audio viene disattivato e viene impostata la velocità di riproduzione su 16x",
|
||||
"name": "Accelerazione ad"
|
||||
},
|
||||
"adblocker": {
|
||||
"description": "Blocca tutti gli annunci e i tracker",
|
||||
"menu": {
|
||||
@ -402,6 +414,21 @@
|
||||
"description": "Download MP3 / sorgenti audio direttamente dall'interfaccia",
|
||||
"menu": {
|
||||
"choose-download-folder": "Scegli cartella download",
|
||||
"download-finish-settings": {
|
||||
"label": "Scarica al termine",
|
||||
"prompt": {
|
||||
"last-percent": "Dopo x percento",
|
||||
"last-seconds": "Ultimi x secondi",
|
||||
"title": "Configura quando scaricare"
|
||||
},
|
||||
"submenu": {
|
||||
"advanced": "Avanzato",
|
||||
"enabled": "Abilitato",
|
||||
"mode": "Modalità tempo",
|
||||
"percent": "Percentuale",
|
||||
"seconds": "Secondi"
|
||||
}
|
||||
},
|
||||
"download-playlist": "Scarica la playlist",
|
||||
"presets": "Preimpostazioni",
|
||||
"skip-existing": "Salta i file esistenti"
|
||||
@ -641,6 +668,59 @@
|
||||
"description": "Salta automaticamente le parti non musicali, come l'intro/outro delle canzoni o le parti dei video musicali in cui non viene riprodotto il brano",
|
||||
"name": "Blocco sponsor"
|
||||
},
|
||||
"synced-lyrics": {
|
||||
"description": "Fornisce testi sincronizzati alle canzoni, utilizzando provider come LRClib.",
|
||||
"errors": {
|
||||
"fetch": "⚠️ - Si è verificato un errore nel recuperare il testo. Per favore riprova più tardi.",
|
||||
"not-found": "⚠️ - Nessun testo trovato per questa canzone."
|
||||
},
|
||||
"menu": {
|
||||
"default-text-string": {
|
||||
"label": "Carattere predefinito tra i testi",
|
||||
"tooltip": "Scegliere il carattere predefinito da utilizzare per l'intervallo tra i testi"
|
||||
},
|
||||
"line-effect": {
|
||||
"label": "Effetto linea",
|
||||
"submenu": {
|
||||
"focus": {
|
||||
"label": "Focus",
|
||||
"tooltip": "Rendi bianca solo la riga corrente"
|
||||
},
|
||||
"offset": {
|
||||
"label": "Offset",
|
||||
"tooltip": "Offset a destra della riga corrente"
|
||||
},
|
||||
"scale": {
|
||||
"label": "Ingrandimento",
|
||||
"tooltip": "Ingrandisci la linea corrente"
|
||||
}
|
||||
},
|
||||
"tooltip": "Scegli l'effetto da applicare alla linea corrente"
|
||||
},
|
||||
"precise-timing": {
|
||||
"label": "Rendi i testi perfettamente sincronizzati",
|
||||
"tooltip": "Calcola al millisecondo la visualizzazione della riga successiva (può avere un piccolo impatto sulle prestazioni)"
|
||||
},
|
||||
"show-lyrics-even-if-inexact": {
|
||||
"label": "Mostra le lyric anche se incorrette",
|
||||
"tooltip": "Se il brano non viene trovato, il plugin riprova con un'altra query di ricerca.\nIl risultato del secondo tentativo potrebbe non essere esatto."
|
||||
},
|
||||
"show-time-codes": {
|
||||
"label": "Mostra time code",
|
||||
"tooltip": "Mostra i codici temporali accanto ai testi"
|
||||
}
|
||||
},
|
||||
"name": "Testi sincronizzati",
|
||||
"refetch-btn": {
|
||||
"fetching": "Sto recuperando...",
|
||||
"normal": "Recupera i testi"
|
||||
},
|
||||
"warnings": {
|
||||
"duration-mismatch": "⚠️ - I testi potrebbero non essere sincronizzati a causa di una mancata corrispondenza della durata.",
|
||||
"inexact": "⚠️ - Il testo di questa canzone potrebbe essere inesatto",
|
||||
"instrumental": "⚠️ - Questo è un brano strumentale"
|
||||
}
|
||||
},
|
||||
"taskbar-mediacontrol": {
|
||||
"description": "Controlla riproduzione dalla taskbar di Windows",
|
||||
"name": "Controlli multimediali sulla taskbar"
|
||||
|
||||
@ -2,11 +2,11 @@
|
||||
"common": {
|
||||
"console": {
|
||||
"plugins": {
|
||||
"execute-failed": "プラグイン・{{pluginName}}:{{contextName}}を実行できませんでした",
|
||||
"execute-failed": "プラグイン・{{pluginName}}:{{contextName}}の実行に失敗しました",
|
||||
"executed-at-ms": "プラグイン {{pluginName}}::{{contextName}} は {{ms}}ms で実行されました",
|
||||
"initialize-failed": "プラグイン \"{{pluginName}}\" の初期化に失敗",
|
||||
"load-all": "すべてのプラグインをロード中",
|
||||
"load-failed": "プラグイン”{{pluginName}}”のロードが失敗しました",
|
||||
"load-failed": "プラグイン”{{pluginName}}”のロードに失敗しました",
|
||||
"loaded": "プラグイン”{{pluginName}}”ロード完了",
|
||||
"unload-failed": "プラグインのアンロードに失敗 \"{{pluginName}}\"",
|
||||
"unloaded": "プラグイン {{pluginName}} がアンロードされました"
|
||||
@ -24,10 +24,10 @@
|
||||
"dev-tools": "ロード完了。デベロッパーツールが開きました"
|
||||
},
|
||||
"i18n": {
|
||||
"loaded": "翻訳ロード完了"
|
||||
"loaded": "i18n ロード完了"
|
||||
},
|
||||
"second-instance": {
|
||||
"receive-command": "プロトコルより命令を受けました:”{{command}}”"
|
||||
"receive-command": "プロトコルから命令を受けました:”{{command}}”"
|
||||
},
|
||||
"theme": {
|
||||
"css-file-not-found": "CSSファイル”{{cssFile}}”が存在しません。無視します"
|
||||
@ -51,7 +51,7 @@
|
||||
"need-to-restart": {
|
||||
"buttons": {
|
||||
"later": "あとで",
|
||||
"restart-now": "今すぐ再起動する"
|
||||
"restart-now": "今すぐ再起動"
|
||||
},
|
||||
"detail": "プラグイン ”{{pluginName}}” を有効にするには再起動が必要です",
|
||||
"message": "”{{pluginName}}”は再起動が必要です",
|
||||
@ -64,12 +64,12 @@
|
||||
"wait": "待つ"
|
||||
},
|
||||
"detail": "ご不便をおかけして申し訳ございません! 何をするか選んでください:",
|
||||
"message": "アプリケーションは応答しません",
|
||||
"title": "ウィンドウが応答しません"
|
||||
"message": "アプリケーションは応答していません",
|
||||
"title": "ウィンドウが応答していません"
|
||||
},
|
||||
"update-available": {
|
||||
"buttons": {
|
||||
"disable": "更新を無効化",
|
||||
"disable": "アップデートを無効化",
|
||||
"download": "ダウンロード",
|
||||
"ok": "OK"
|
||||
},
|
||||
@ -98,13 +98,13 @@
|
||||
"submenu": {
|
||||
"auto-reset-app-cache": "アプリの開始時にキャッシュをリセット",
|
||||
"disable-hardware-acceleration": "ハードウェアアクセラレーションの無効化",
|
||||
"edit-config-json": "config.json を編集する",
|
||||
"edit-config-json": "config.json を編集",
|
||||
"override-user-agent": "ユーザーエージェントの上書き",
|
||||
"restart-on-config-changes": "設定変更時に再起動",
|
||||
"set-proxy": {
|
||||
"label": "プロキシ",
|
||||
"label": "プロキシ設定",
|
||||
"prompt": {
|
||||
"label": "プロキシのアドレスを入力: (空にすると無効化)",
|
||||
"label": "プロキシのアドレスを入力: (空で無効化)",
|
||||
"placeholder": "例: SOCKS5://127.0.0.1:9999",
|
||||
"title": "プロキシ"
|
||||
}
|
||||
@ -158,6 +158,14 @@
|
||||
},
|
||||
"remove-upgrade-button": "アップグレードボタンを削除",
|
||||
"theme": {
|
||||
"dialog": {
|
||||
"button": {
|
||||
"cancel": "キャンセル",
|
||||
"remove": "削除"
|
||||
},
|
||||
"remove-theme": "本当にカスタムテーマを削除しますか?",
|
||||
"remove-theme-message": "カスタムテーマを削除します"
|
||||
},
|
||||
"label": "テーマ",
|
||||
"submenu": {
|
||||
"import-css-file": "CSSファイルをインポート",
|
||||
@ -199,6 +207,10 @@
|
||||
}
|
||||
},
|
||||
"plugins": {
|
||||
"ad-speedup": {
|
||||
"description": "広告が再生されると、自動的にミュートされ、再生速度が16倍に設定されます",
|
||||
"name": "広告のスピードを上げる"
|
||||
},
|
||||
"adblocker": {
|
||||
"description": "すべての広告とトラッカーをブロックj",
|
||||
"menu": {
|
||||
@ -402,6 +414,21 @@
|
||||
"description": "UIから直にMP3・ソースオーディオをダウンロードします",
|
||||
"menu": {
|
||||
"choose-download-folder": "ダウンロードフォルダ",
|
||||
"download-finish-settings": {
|
||||
"label": "完了時にダウンロード",
|
||||
"prompt": {
|
||||
"last-percent": "x パーセント後",
|
||||
"last-seconds": "最後の x 秒",
|
||||
"title": "保存するタイミング"
|
||||
},
|
||||
"submenu": {
|
||||
"advanced": "高度な設定",
|
||||
"enabled": "有効",
|
||||
"mode": "時間モード",
|
||||
"percent": "パーセント",
|
||||
"seconds": "秒"
|
||||
}
|
||||
},
|
||||
"download-playlist": "プレイリストをダウンロード",
|
||||
"presets": "プリセット",
|
||||
"skip-existing": "存在するファイルをスキップ"
|
||||
@ -451,15 +478,15 @@
|
||||
},
|
||||
"menu": {
|
||||
"click-to-copy-id": "ホストIDをコピー",
|
||||
"close": "一緒に音楽を閉じる",
|
||||
"connected-users": "接続されているユーザー",
|
||||
"disconnect": "一緒に音楽を切断する",
|
||||
"close": "Music Togetherを閉じる",
|
||||
"connected-users": "接続中のユーザー",
|
||||
"disconnect": "Music Togetherから切断",
|
||||
"empty-user": "接続中のユーザーはいません",
|
||||
"host": "Music Together ホスト",
|
||||
"join": "一緒に音楽に参加",
|
||||
"host": "Music Togetherをホスト",
|
||||
"join": "Music Togetherに参加",
|
||||
"permission": {
|
||||
"all": "ゲストがプレイリストとプレーヤーを制御できるようにする",
|
||||
"host-only": "ホストのみがプレイリストとプレーヤーを制御できます",
|
||||
"all": "ゲストの再生リストとプレーヤーを制御を許可",
|
||||
"host-only": "ホストのみがプレイリストとプレーヤーを制御",
|
||||
"playlist": "ゲストによるプレイリストの制御を許可する"
|
||||
},
|
||||
"set-permission": "制御権限を変更",
|
||||
@ -469,20 +496,20 @@
|
||||
"host": "ホストとして接続されています"
|
||||
}
|
||||
},
|
||||
"name": "一緒に音楽 [ベータ版]",
|
||||
"name": "Music Together [ベータ]",
|
||||
"toast": {
|
||||
"add-song-failed": "曲の追加に失敗しました",
|
||||
"closed": "一緒に音楽が閉じられました",
|
||||
"disconnected": "一緒に音楽が切断されました",
|
||||
"host-failed": "一緒に音楽のホストに失敗しました",
|
||||
"closed": "Music Together が閉じられました",
|
||||
"disconnected": "Music Together が切断されました",
|
||||
"host-failed": "Music Together のホストに失敗しました",
|
||||
"id-copied": "ホストIDがクリップボードにコピーされました",
|
||||
"id-copy-failed": "ホストIDをクリップボードにコピー出来ませんでした",
|
||||
"join-failed": "一緒に音楽に参加出来ませんでした",
|
||||
"joined": "一緒に音楽に参加しました",
|
||||
"permission-changed": "一緒に音楽の権限が \"{{permission}}\" に変更されました",
|
||||
"join-failed": "Music Together に参加出来ませんでした",
|
||||
"joined": "Music Together に参加しました",
|
||||
"permission-changed": "Music Togetherの権限が \"{{permission}}\" に変更されました",
|
||||
"remove-song-failed": "曲の削除に失敗しました",
|
||||
"user-connected": "{{name}} が一緒に音楽に参加しました",
|
||||
"user-disconnected": "{{name}} が一緒に音楽を退出しました"
|
||||
"user-connected": "{{name}} がMusic Togetherに参加しました",
|
||||
"user-disconnected": "{{name}} がMusic Togetherを退出しました"
|
||||
}
|
||||
},
|
||||
"navigation": {
|
||||
@ -641,6 +668,59 @@
|
||||
"description": "イントロ/アウトロなどの音楽以外の部分や、曲が再生されていないミュージック ビデオの部分を自動的にスキップします",
|
||||
"name": "SponsorBlock"
|
||||
},
|
||||
"synced-lyrics": {
|
||||
"description": "LRClibのようなプロバイダを使って、楽曲に同期した歌詞を使用する。",
|
||||
"errors": {
|
||||
"fetch": "⚠️ - 歌詞の取得中にエラーが発生しました。 後でもう一度お試しください。",
|
||||
"not-found": "⚠️ - この曲の歌詞は見つかりませんでした。"
|
||||
},
|
||||
"menu": {
|
||||
"default-text-string": {
|
||||
"label": "デフォルトの歌詞間の文字",
|
||||
"tooltip": "歌詞と歌詞の間に使用するデフォルトの文字を選択してください"
|
||||
},
|
||||
"line-effect": {
|
||||
"label": "歌詞表示のエフェクト",
|
||||
"submenu": {
|
||||
"focus": {
|
||||
"label": "フォーカス",
|
||||
"tooltip": "現在の行だけを白くする"
|
||||
},
|
||||
"offset": {
|
||||
"label": "オフセット",
|
||||
"tooltip": "オフセットを現在の行の右側にする"
|
||||
},
|
||||
"scale": {
|
||||
"label": "サイズ",
|
||||
"tooltip": "現在の行のサイズ変更をする"
|
||||
}
|
||||
},
|
||||
"tooltip": "現在の行に適用するエフェクトを選択"
|
||||
},
|
||||
"precise-timing": {
|
||||
"label": "歌詞を完璧に同期させる",
|
||||
"tooltip": "次の行の表示をミリ秒単位で計算する(パフォーマンスに若干の影響を与える可能性があります)"
|
||||
},
|
||||
"show-lyrics-even-if-inexact": {
|
||||
"label": "歌詞が不正確でも表示する",
|
||||
"tooltip": "曲が見つからなかった場合、プラグインは別の検索クエリで再試行します。\nただし、再試行の結果は正確でない可能性があります。"
|
||||
},
|
||||
"show-time-codes": {
|
||||
"label": "タイムコードを表示",
|
||||
"tooltip": "歌詞の横にタイムコードを表示"
|
||||
}
|
||||
},
|
||||
"name": "歌詞を同期",
|
||||
"refetch-btn": {
|
||||
"fetching": "取得中...",
|
||||
"normal": "歌詞を再取得"
|
||||
},
|
||||
"warnings": {
|
||||
"duration-mismatch": "⚠️ - タイミングが合わないため、歌詞が同期されていない可能性があります。",
|
||||
"inexact": "⚠️ - この曲の歌詞は正確ではないかもしれません",
|
||||
"instrumental": "⚠️ - これは演奏のみの曲です"
|
||||
}
|
||||
},
|
||||
"taskbar-mediacontrol": {
|
||||
"description": "Windowsタスクバーから再生をコントロール",
|
||||
"name": "タスクバーメディアコントロール"
|
||||
|
||||
@ -158,6 +158,14 @@
|
||||
},
|
||||
"remove-upgrade-button": "업그레이드 버튼 제거",
|
||||
"theme": {
|
||||
"dialog": {
|
||||
"button": {
|
||||
"cancel": "취소",
|
||||
"remove": "제거"
|
||||
},
|
||||
"remove-theme": "사용자 정의 테마를 제거하시겠습니까?",
|
||||
"remove-theme-message": "사용자 정의 테마가 제거됩니다. 계속하시겠습니까?"
|
||||
},
|
||||
"label": "테마",
|
||||
"submenu": {
|
||||
"import-css-file": "사용자 정의 CSS 파일 가져오기",
|
||||
@ -199,6 +207,10 @@
|
||||
}
|
||||
},
|
||||
"plugins": {
|
||||
"ad-speedup": {
|
||||
"description": "광고가 재생될 때, 오디오가 음소거되고 재생 속도가 16배로 설정됩니다",
|
||||
"name": "광고 배속"
|
||||
},
|
||||
"adblocker": {
|
||||
"description": "모든 광고와 트래커를 즉시 차단합니다",
|
||||
"menu": {
|
||||
@ -267,6 +279,49 @@
|
||||
},
|
||||
"name": "앰비언트 모드"
|
||||
},
|
||||
"api-server": {
|
||||
"description": "플레이어를 제어하기 위한 API 서버를 추가합니다",
|
||||
"dialog": {
|
||||
"request": {
|
||||
"buttons": {
|
||||
"allow": "허용",
|
||||
"deny": "거부"
|
||||
},
|
||||
"message": "{{ID}} ({{origin}})이(가) API에 액세스하도록 허용하시겠습니까?",
|
||||
"title": "API 권한 요청"
|
||||
}
|
||||
},
|
||||
"menu": {
|
||||
"auth-strategy": {
|
||||
"label": "인증 정책",
|
||||
"submenu": {
|
||||
"auth-at-first": {
|
||||
"label": "첫 번째 요청 시 인증"
|
||||
},
|
||||
"none": {
|
||||
"label": "인증 없음"
|
||||
}
|
||||
}
|
||||
},
|
||||
"hostname": {
|
||||
"label": "호스트 명"
|
||||
},
|
||||
"port": {
|
||||
"label": "포트"
|
||||
}
|
||||
},
|
||||
"name": "API 서버 [베타]",
|
||||
"prompt": {
|
||||
"hostname": {
|
||||
"label": "API 서버가 사용할 호스트 명(예: 0.0.0.0)을 입력하세요:",
|
||||
"title": "호스트 명"
|
||||
},
|
||||
"port": {
|
||||
"label": "API 서버가 사용할 포트를 입력하세요:",
|
||||
"title": "포트"
|
||||
}
|
||||
}
|
||||
},
|
||||
"audio-compressor": {
|
||||
"description": "오디오에 컴프레서를 적용합니다 (신호에서 가장 시끄러운 부분의 음량을 낮추고 가장 조용한 부분의 음량을 높임)",
|
||||
"name": "오디오 컴프레서"
|
||||
@ -402,6 +457,21 @@
|
||||
"description": "UI에서 직접 MP3/소스 오디오를 다운로드하세요",
|
||||
"menu": {
|
||||
"choose-download-folder": "다운로드 폴더 선택",
|
||||
"download-finish-settings": {
|
||||
"label": "노래가 끝날 때 자동 다운로드",
|
||||
"prompt": {
|
||||
"last-percent": "x 퍼센트 이후에",
|
||||
"last-seconds": "마지막 x 초에",
|
||||
"title": "다운로드 시기 구성"
|
||||
},
|
||||
"submenu": {
|
||||
"advanced": "고급",
|
||||
"enabled": "활성화",
|
||||
"mode": "시간 모드",
|
||||
"percent": "퍼센트 기준",
|
||||
"seconds": "초 기준"
|
||||
}
|
||||
},
|
||||
"download-playlist": "재생목록 다운로드",
|
||||
"presets": "프리셋",
|
||||
"skip-existing": "이미 존재하는 파일 넘기기"
|
||||
@ -641,6 +711,59 @@
|
||||
"description": "인트로/아웃트로와 같은 음악이 아닌 부분이나, 노래가 재생되지 않는 뮤직 비디오의 일부를 자동으로 건너뜁니다",
|
||||
"name": "SponsorBlock"
|
||||
},
|
||||
"synced-lyrics": {
|
||||
"description": "LRClib등의 가사 제공자에서 싱크 가사를 불러옵니다.",
|
||||
"errors": {
|
||||
"fetch": "⚠️ - 가사를 불러오는 동안 오류가 발생했습니다. 나중에 다시 시도해 주세요.",
|
||||
"not-found": "⚠️ - 이 노래의 가사를 찾을 수 없습니다."
|
||||
},
|
||||
"menu": {
|
||||
"default-text-string": {
|
||||
"label": "가사 사이에 표시할 문자",
|
||||
"tooltip": "가사 사이의 빈 공간에 사용할 문자를 선택합니다"
|
||||
},
|
||||
"line-effect": {
|
||||
"label": "줄 표시 효과",
|
||||
"submenu": {
|
||||
"focus": {
|
||||
"label": "포커스",
|
||||
"tooltip": "현재 줄만 하얀색으로 표시"
|
||||
},
|
||||
"offset": {
|
||||
"label": "오프셋",
|
||||
"tooltip": "현재 줄의 오른쪽에 오프셋 적용"
|
||||
},
|
||||
"scale": {
|
||||
"label": "스케일",
|
||||
"tooltip": "현재 줄에 스케일 적용"
|
||||
}
|
||||
},
|
||||
"tooltip": "현재 줄에 적용할 효과를 선택합니다"
|
||||
},
|
||||
"precise-timing": {
|
||||
"label": "가사를 최대한 정교하게 동기화",
|
||||
"tooltip": "다음 줄의 표시를 밀리초 단위로 계산합니다 (성능에 약간의 영향을 미칠 수 있음)"
|
||||
},
|
||||
"show-lyrics-even-if-inexact": {
|
||||
"label": "가사가 정확하지 않더라도 표시",
|
||||
"tooltip": "노래를 찾을 수 없는 경우, 플러그인이 다른 검색어로 다시 검색합니다.\n두번째 검색 결과는 정확하지 않을 수 있습니다."
|
||||
},
|
||||
"show-time-codes": {
|
||||
"label": "시간 코드 표시",
|
||||
"tooltip": "가사 옆에 시간 코드 표시"
|
||||
}
|
||||
},
|
||||
"name": "싱크 가사",
|
||||
"refetch-btn": {
|
||||
"fetching": "가져오는 중...",
|
||||
"normal": "가사 다시 가져오기"
|
||||
},
|
||||
"warnings": {
|
||||
"duration-mismatch": "⚠️ - 곡 길이 불일치로 인해 가사가 일치하지 않을 수 있습니다.",
|
||||
"inexact": "⚠️ - 이 노래의 가사는 정확하지 않을 수 있습니다",
|
||||
"instrumental": "⚠️ - 연주곡입니다"
|
||||
}
|
||||
},
|
||||
"taskbar-mediacontrol": {
|
||||
"description": "Windows 작업 표시줄에서 재생을 제어하세요",
|
||||
"name": "작업표시줄 미디어 컨트롤"
|
||||
|
||||
@ -158,6 +158,14 @@
|
||||
},
|
||||
"remove-upgrade-button": "Nerodyti \"Patobulinti\" mygtuko",
|
||||
"theme": {
|
||||
"dialog": {
|
||||
"button": {
|
||||
"cancel": "Atšaukti",
|
||||
"remove": "Pašalinti"
|
||||
},
|
||||
"remove-theme": "Ar tikrai norite pašalinti pasirinktinę temą?",
|
||||
"remove-theme-message": "Šis veiksmas pašalins pasirinktinę temą"
|
||||
},
|
||||
"label": "Tema",
|
||||
"submenu": {
|
||||
"import-css-file": "Įkelti pasirinktinį CSS failą",
|
||||
@ -191,7 +199,11 @@
|
||||
"previous": "Ankstesnis",
|
||||
"quit": "Išeiti",
|
||||
"restart": "Perkrauti programą",
|
||||
"show": "Rodyti langą"
|
||||
"show": "Rodyti langą",
|
||||
"tooltip": {
|
||||
"default": "Youtube Music",
|
||||
"with-song-info": "YouTube Music: {{artist}} - {{title}}"
|
||||
}
|
||||
}
|
||||
},
|
||||
"plugins": {
|
||||
@ -202,8 +214,19 @@
|
||||
},
|
||||
"name": "Reklamų blokuotojas"
|
||||
},
|
||||
"album-actions": {
|
||||
"name": "Albumo Veiksmai"
|
||||
},
|
||||
"album-color-theme": {
|
||||
"description": "Pritaiko dinamišką temą ir vizualinius efektus pagal albumo spalvų paletę",
|
||||
"menu": {
|
||||
"color-mix-ratio": {
|
||||
"label": "Spalvų maišymo santykis",
|
||||
"submenu": {
|
||||
"percent": "{{ratio}}%"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "Albumo Spalvų Tema"
|
||||
},
|
||||
"ambient-mode": {
|
||||
@ -423,6 +446,20 @@
|
||||
"fetched-lyrics": "Gauti žodžiai iš „Genius“"
|
||||
}
|
||||
},
|
||||
"music-together": {
|
||||
"description": "Pasidalinti grojaraščiu su kitais. Kai vedėjas paleis dainą, visi kiti girdės tą pačią dainą",
|
||||
"dialog": {
|
||||
"enter-host": "Įveskite vedėjo ID"
|
||||
},
|
||||
"internal": {
|
||||
"save": "Išsaugoti",
|
||||
"track-source": "Dainos kilmė",
|
||||
"unknown-user": "Nežinomas Naudotojas"
|
||||
},
|
||||
"menu": {
|
||||
"click-to-copy-id": "Kopijuoti Vedėjo ID"
|
||||
}
|
||||
},
|
||||
"navigation": {
|
||||
"description": "Kitas/Ankstenis navigacijos rodyklės tiesiogiai integruotos sąsajoje, kaip tavo mėgstamiausioje naršyklėje",
|
||||
"name": "Navigacija"
|
||||
|
||||
203
src/i18n/resources/ms.json
Normal file
203
src/i18n/resources/ms.json
Normal file
@ -0,0 +1,203 @@
|
||||
{
|
||||
"common": {
|
||||
"console": {
|
||||
"plugins": {
|
||||
"execute-failed": "Pelaksaan plugin gagal {{pluginName}}::{{contextName}}",
|
||||
"executed-at-ms": "Plugin {{pluginName}}::{{contextName}} dilaksanakan pada {{ms}}ms",
|
||||
"initialize-failed": "Gagal untuk memulakan plugin \"{{pluginName}}\"",
|
||||
"load-all": "Memuatkan semua plugin",
|
||||
"loaded": "Plugin \"{{pluginName}}\" dimuatkan",
|
||||
"unload-failed": "Gagal untuk memunggah plugin \"{{pluginName}}\"",
|
||||
"unloaded": "Plugin \"{{pluginName}}\" dipunggahkan"
|
||||
}
|
||||
}
|
||||
},
|
||||
"language": {
|
||||
"code": "ms",
|
||||
"local-name": "Bahasa Malaysia",
|
||||
"name": "Malay"
|
||||
},
|
||||
"main": {
|
||||
"console": {
|
||||
"did-finish-load": {
|
||||
"dev-tools": "Selesai memuat. DevTools dibuka"
|
||||
},
|
||||
"i18n": {
|
||||
"loaded": "i18n dimuatkan"
|
||||
},
|
||||
"second-instance": {
|
||||
"receive-command": "Menerima arahan atas protokol: \"{{command}}\""
|
||||
},
|
||||
"theme": {
|
||||
"css-file-not-found": "Fail CSS \"{{cssFile}}\" tidak wujud, mengabaikan"
|
||||
},
|
||||
"when-ready": {
|
||||
"clearing-cache-after-20s": "Membersihkan cache aplikasi"
|
||||
}
|
||||
},
|
||||
"dialog": {
|
||||
"hide-menu-enabled": {
|
||||
"detail": "Menu telah disembunyikan, guna 'Alt' untuk menunjukkannya (atau 'Escape' jika menggunakan In-App Menu)"
|
||||
},
|
||||
"need-to-restart": {
|
||||
"buttons": {
|
||||
"later": "Nanti",
|
||||
"restart-now": "Restart Sekarang"
|
||||
},
|
||||
"message": "\"{{pluginName}}\" perlu dimulakan semula",
|
||||
"title": "Mulakan Semula Diperlukan"
|
||||
},
|
||||
"unresponsive": {
|
||||
"buttons": {
|
||||
"quit": "Berhenti",
|
||||
"relaunch": "Lancar Semula",
|
||||
"wait": "Tunggu"
|
||||
},
|
||||
"detail": "Kami memohon maaf atas kesulitan! sila pilih apa yang perlu dilakukan:",
|
||||
"message": "Aplikasi Tidak Responsif",
|
||||
"title": "Window Tidak Responsif"
|
||||
},
|
||||
"update-available": {
|
||||
"buttons": {
|
||||
"download": "Muat Turun",
|
||||
"ok": "OK"
|
||||
},
|
||||
"detail": "Versi baharu kini tersedia dan boleh dimuat turun di {{downloadLink}}"
|
||||
}
|
||||
},
|
||||
"menu": {
|
||||
"about": "Mengenai",
|
||||
"navigation": {
|
||||
"label": "Navigasi",
|
||||
"submenu": {
|
||||
"copy-current-url": "Salin URL semasa",
|
||||
"go-back": "Belakang",
|
||||
"go-forward": "Depan",
|
||||
"quit": "Keluar"
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"label": "Tetapan",
|
||||
"submenu": {
|
||||
"advanced-options": {
|
||||
"label": "Tetapan Lanjutan",
|
||||
"submenu": {
|
||||
"set-proxy": {
|
||||
"prompt": {
|
||||
"placeholder": "Contoh: SOCKS5://127.0.0.1:9999",
|
||||
"title": "Set proksi"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"always-on-top": "Sentiasa di atas",
|
||||
"auto-update": "Kemas Kini Automatik",
|
||||
"hide-menu": {
|
||||
"dialog": {
|
||||
"message": "Menu akan disembunyikan pada pelancaran seterusnya, gunakan [Alt] untuk menunjukkannya (atau backtick [`] jika menggunakan dalam aplikasi-menu)"
|
||||
}
|
||||
},
|
||||
"language": {
|
||||
"dialog": {
|
||||
"message": "Bahasa akan ditukar selepas dimulakan semula",
|
||||
"title": "Bahasa Berubah"
|
||||
},
|
||||
"label": "Bahasa",
|
||||
"submenu": {
|
||||
"to-help-translate": "Ingin membantu menterjemah? Klik di sini"
|
||||
}
|
||||
},
|
||||
"resume-on-start": "Mulakan semula lagu terakhir apabila aplikasi dimulakan",
|
||||
"start-at-login": "Mulakan semasa log masuk",
|
||||
"starting-page": {
|
||||
"label": "Halaman Permulaan"
|
||||
},
|
||||
"tray": {
|
||||
"submenu": {
|
||||
"play-pause-on-click": "Main / Hentikan pada klik"
|
||||
}
|
||||
},
|
||||
"visual-tweaks": {
|
||||
"label": "Pembaikan Visual",
|
||||
"submenu": {
|
||||
"like-buttons": {
|
||||
"default": "Lalai",
|
||||
"hide": "Sembunyi"
|
||||
},
|
||||
"theme": {
|
||||
"dialog": {
|
||||
"button": {
|
||||
"cancel": "Batalkan",
|
||||
"remove": "Padam"
|
||||
}
|
||||
},
|
||||
"label": "Tema"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tray": {
|
||||
"next": "Seterusnya",
|
||||
"play-pause": "Main / Jeda",
|
||||
"previous": "Sebelumnya",
|
||||
"quit": "Keluar",
|
||||
"restart": "Mulakan Semula Aplikasi"
|
||||
}
|
||||
},
|
||||
"plugins": {
|
||||
"ambient-mode": {
|
||||
"menu": {
|
||||
"quality": {
|
||||
"label": "Kualiti"
|
||||
},
|
||||
"size": {
|
||||
"label": "Saiz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"captions-selector": {
|
||||
"prompt": {
|
||||
"selector": {
|
||||
"title": "Pilih bahasa kapsyen"
|
||||
}
|
||||
}
|
||||
},
|
||||
"synced-lyrics": {
|
||||
"menu": {
|
||||
"show-lyrics-even-if-inexact": {
|
||||
"label": "Tunjukkan lirik walaupun tidak tepat",
|
||||
"tooltip": "Jika lagu tidak ditemui, plugin cuba lagi dengan pertanyaan carian yang berbeza. \nHasil dari percubaan kedua mungkin tidak tepat."
|
||||
},
|
||||
"show-time-codes": {
|
||||
"tooltip": "Tunjukkan kod masa di sebelah lirik"
|
||||
}
|
||||
}
|
||||
},
|
||||
"taskbar-mediacontrol": {
|
||||
"description": "Kawalan main balik dari bar tugas Windows anda",
|
||||
"name": "Kawalan Media Bar Tugas"
|
||||
},
|
||||
"video-toggle": {
|
||||
"menu": {
|
||||
"align": {
|
||||
"submenu": {
|
||||
"left": "Kiri",
|
||||
"middle": "Tengah",
|
||||
"right": "Kanan"
|
||||
}
|
||||
},
|
||||
"force-hide": "Alih Keluar Tab Video",
|
||||
"mode": {
|
||||
"submenu": {
|
||||
"disabled": "Tidak Aktif"
|
||||
}
|
||||
}
|
||||
},
|
||||
"templates": {
|
||||
"button": "Lagu"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
698
src/i18n/resources/ne.json
Normal file
698
src/i18n/resources/ne.json
Normal file
@ -0,0 +1,698 @@
|
||||
{
|
||||
"common": {
|
||||
"console": {
|
||||
"plugins": {
|
||||
"execute-failed": "प्लगइन {{pluginName}}::{{contextName}} को कार्यान्वयन गर्न असफल भयो",
|
||||
"executed-at-ms": "प्लगइन {{pluginName}}::{{contextName}} {{ms}} मिलिसेकेण्डमा कार्यान्वित भयो",
|
||||
"initialize-failed": "प्लगइन \"{{pluginName}}\" आरम्भ गर्न मिलेन",
|
||||
"load-all": "सबै प्लगइनहरू लोड हुँदैछ",
|
||||
"load-failed": "प्लगइन \"{{pluginName}}\" लोड गर्न मिलेन",
|
||||
"loaded": "प्लगइन \"{{pluginName}}\" लोड भयो",
|
||||
"unload-failed": "प्लगइन \"{{pluginName}}\" अनलोड गर्न मिलेन",
|
||||
"unloaded": "प्लगइन \"{{pluginName}}\" अनलोड भयो"
|
||||
}
|
||||
}
|
||||
},
|
||||
"language": {
|
||||
"code": "ne",
|
||||
"local-name": "नेपाली",
|
||||
"name": "Nepali"
|
||||
},
|
||||
"main": {
|
||||
"console": {
|
||||
"did-finish-load": {
|
||||
"dev-tools": "लोडिंग समाप्त भयो। डेभटुल्स खोलियो"
|
||||
},
|
||||
"i18n": {
|
||||
"loaded": "i18n लोड भयो"
|
||||
},
|
||||
"second-instance": {
|
||||
"receive-command": "प्रोटोकल मार्फत कमान प्राप्त गरियो: \"{{command}}\""
|
||||
},
|
||||
"theme": {
|
||||
"css-file-not-found": "CSS फाइल \"{{cssFile}}\" मौजूद छैन, अनदेखी गर्दै छ"
|
||||
},
|
||||
"unresponsive": {
|
||||
"details": "अनाक्रियतामा त्रुटि!\n{{error}}"
|
||||
},
|
||||
"when-ready": {
|
||||
"clearing-cache-after-20s": "एप क्यास खाली गर्दै"
|
||||
},
|
||||
"window": {
|
||||
"tried-to-render-offscreen": "Windowले स्क्रीन बाहिर रेन्डर गर्न कोशिस गर्यो, windowSize={{windowSize}}, displaySize={{displaySize}}, position={{position}}"
|
||||
}
|
||||
},
|
||||
"dialog": {
|
||||
"hide-menu-enabled": {
|
||||
"detail": "मेनु लुकिएको छ, यसलाई देखाउन 'Alt' प्रयोग गर्नुहोस् (वा 'Escape' यदि इन-एप मेनु प्रयोग गर्नुहोस्)",
|
||||
"message": "हाइड मेनु सक्षम गरिएको छ",
|
||||
"title": "हाइड मेनु इनेबल गरियो"
|
||||
},
|
||||
"need-to-restart": {
|
||||
"buttons": {
|
||||
"later": "पछि",
|
||||
"restart-now": "अहिले पुन: सुरु गर्नुहोस्"
|
||||
},
|
||||
"detail": "{{pluginName}}\" प्लगइनले प्रभाव समेत गर्नका लागि पुन: सुरु गर्नुपर्दछ",
|
||||
"message": "{{pluginName}}\" पुनः सुरु गर्नुपर्छ",
|
||||
"title": "पुनः सुरु गर्नुपर्छ"
|
||||
},
|
||||
"unresponsive": {
|
||||
"buttons": {
|
||||
"quit": "बन्द गर्नुहोस्",
|
||||
"relaunch": "पुन: सुरु गर्नुहोस्",
|
||||
"wait": "प्रतीक्षा गर्नुहोस्"
|
||||
},
|
||||
"detail": "हामी असुविधाका लागि क्षमा गर्दछौं! कृपया के गर्नुहोस् छन् छान्नुहोस्:",
|
||||
"message": "अनुप्रयोग असार्थक छ",
|
||||
"title": "विन्डो संपर्क नाघेको छ"
|
||||
},
|
||||
"update-available": {
|
||||
"buttons": {
|
||||
"disable": "अपडेटहरू निष्क्रिय गर्नुहोस्",
|
||||
"download": "डाउनलोड गर्नुहोस्",
|
||||
"ok": "ठिक छ"
|
||||
},
|
||||
"detail": "नयाँ संस्करण उपलब्ध छ र यसलाई {{downloadLink}} बाट डाउनलोड गर्न सकिन्छ",
|
||||
"message": "नयाँ संस्करण उपलब्ध छ",
|
||||
"title": "अपडेट उपलब्ध छ"
|
||||
}
|
||||
},
|
||||
"menu": {
|
||||
"about": "बारेमा",
|
||||
"navigation": {
|
||||
"label": "नेभिगेसन",
|
||||
"submenu": {
|
||||
"copy-current-url": "हालको URL प्रतिलिपि गर्नुहोस्",
|
||||
"go-back": "पछाडि जानुहोस्",
|
||||
"go-forward": "अघि जानुहोस्",
|
||||
"quit": "बाहिर निस्कनुहोस्",
|
||||
"restart": "अनुप्रयोग पुनः सुरु गर्नुहोस्"
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"label": "विकल्पहरू",
|
||||
"submenu": {
|
||||
"advanced-options": {
|
||||
"label": "उन्नत विकल्पहरू",
|
||||
"submenu": {
|
||||
"auto-reset-app-cache": "एप सुरु हुँदा एप क्यास रिसेट गर्नुहोस्",
|
||||
"disable-hardware-acceleration": "हार्डवेयर तेजीगरी निष्क्रिय गर्नुहोस्",
|
||||
"edit-config-json": "config.json सम्पादन गर्नुहोस्",
|
||||
"override-user-agent": "प्रयोगकर्ता-एजेन्ट अधिलेखन गर्नुहोस्",
|
||||
"restart-on-config-changes": "कन्फिगरेसन परिवर्तनमा पुनः सुरु गर्नुहोस्",
|
||||
"set-proxy": {
|
||||
"label": "प्रोक्सी सेट गर्नुहोस्",
|
||||
"prompt": {
|
||||
"label": "प्रोक्सी ठेगाना प्रविष्टि: (निष्क्रिय गर्नका लागि खाली छोड्नुहोस्)",
|
||||
"placeholder": "उदाहरण: SOCKS5://127.0.0.1:9999",
|
||||
"title": "प्रोक्सी सेट गर्नुहोस्"
|
||||
}
|
||||
},
|
||||
"toggle-dev-tools": "डेभटुल्स परिस्थिति परिवर्तन गर्नुहोस्"
|
||||
}
|
||||
},
|
||||
"always-on-top": "सधैं माथिल्लोमा",
|
||||
"auto-update": "स्वत: अपडेट",
|
||||
"hide-menu": {
|
||||
"dialog": {
|
||||
"message": "मेनु अर्को लन्चमा लुकिनेछ, यसलाई देखाउनका लागि [Alt] प्रयोग गर्नुहोस् (वा इन-एप-मेनु प्रयोग गर्दा backtick [`])प्रयोग गर्नुहोस्",
|
||||
"title": "हाइड मेनु इनेबल गरियो"
|
||||
},
|
||||
"label": "हाइड मेनु"
|
||||
},
|
||||
"language": {
|
||||
"dialog": {
|
||||
"message": "भाषा पुनः सुरु गर्नपछि परिवर्तन गरिनेछ",
|
||||
"title": "भाषा परिवर्तित गरियो"
|
||||
},
|
||||
"label": "भाषा",
|
||||
"submenu": {
|
||||
"to-help-translate": "अनुवाद गर्न मद्दत गर्न चाहनुहुन्छ? यहाँ क्लिक गर्नुहोस्"
|
||||
}
|
||||
},
|
||||
"resume-on-start": "एप सुरु हुँदा अन्तिम गीत पुनः सुरु गर्नुहोस्",
|
||||
"single-instance-lock": "एकल उदाहरण तालिका",
|
||||
"start-at-login": "लगइनमा सुरु गर्नुहोस्",
|
||||
"starting-page": {
|
||||
"label": "सुरु गर्नुहोस्",
|
||||
"unset": "अनसेट"
|
||||
},
|
||||
"tray": {
|
||||
"label": "ट्रे(tray)",
|
||||
"submenu": {
|
||||
"disabled": "हाल बन्द",
|
||||
"enabled-and-hide-app": "ट्रे इनेबल गरिएको छ र एप बन्द गरिएको छ",
|
||||
"enabled-and-show-app": "एप देखाउनुहोस्",
|
||||
"play-pause-on-click": "क्लिकमा खेल्नुहोस्/रोक्नुहोस्"
|
||||
}
|
||||
},
|
||||
"visual-tweaks": {
|
||||
"label": "भिजुअल ट्वीक्स",
|
||||
"submenu": {
|
||||
"like-buttons": {
|
||||
"default": "पूर्वनिर्धारित",
|
||||
"force-show": "देखाउनुहोस",
|
||||
"hide": "लुकाउनुहोस",
|
||||
"label": "लाइक बटनहरू"
|
||||
},
|
||||
"remove-upgrade-button": "अपग्रेड बटन हटाउनुहोस्",
|
||||
"theme": {
|
||||
"dialog": {
|
||||
"button": {
|
||||
"cancel": "रद्द गर्नुहोस्",
|
||||
"remove": "हटाउनुहोस्"
|
||||
},
|
||||
"remove-theme": "के तपाईँ निश्चित हुनुहुन्छ कि तपाईँ कस्टम थिम हटाउन चाहनुहुन्छ?",
|
||||
"remove-theme-message": "यसले कस्टम थिम हटाउनेछ"
|
||||
},
|
||||
"label": "थिम",
|
||||
"submenu": {
|
||||
"import-css-file": "कस्टम CSS फाइल आयात गर्नुहोस्",
|
||||
"no-theme": "कुनै थिम छैन"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"plugins": {
|
||||
"enabled": "सक्षम गरियो",
|
||||
"label": "प्लगइनहरू",
|
||||
"new": "NEW"
|
||||
},
|
||||
"view": {
|
||||
"label": "हेर्नुहोस्",
|
||||
"submenu": {
|
||||
"force-reload": "फोर्स रिलोड",
|
||||
"reload": "पुनः लोड गर्नुहोस्",
|
||||
"reset-zoom": "वास्तविक आकार",
|
||||
"toggle-fullscreen": "पूर्ण स्क्रिन टगल गर्नुहोस्",
|
||||
"zoom-in": "जुम इन गर्नुहोस्",
|
||||
"zoom-out": "जुम आउट गर्नुहोस्"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tray": {
|
||||
"next": "अर्को",
|
||||
"play-pause": "खेल्नुहोस्/रोक्नुहोस्",
|
||||
"previous": "अघिल्ला",
|
||||
"quit": "बाहिर निस्कनुहोस्",
|
||||
"restart": "एप पुनः सुरु गर्नुहोस्",
|
||||
"show": "विन्डो देखाउनुहोस्",
|
||||
"tooltip": {
|
||||
"default": "युट्युब मिउजिक",
|
||||
"with-song-info": "युट्युब मिउजिक:{{artist}}-{{title}}"
|
||||
}
|
||||
}
|
||||
},
|
||||
"plugins": {
|
||||
"adblocker": {
|
||||
"description": "सबै विज्ञापन र ट्र्याकइंगहरू ब्लक गर्नुहोस्",
|
||||
"menu": {
|
||||
"blocker": "अवरोधक"
|
||||
},
|
||||
"name": "विज्ञापन अवरोधक"
|
||||
},
|
||||
"album-actions": {
|
||||
"description": "प्लेलिस्ट वा एल्बममा सबै गीतहरूमा यो लागू गर्न नचाहेको, मन नपरोस्, मनपर्यो, र विपरीत बटनहरू थप्दछ",
|
||||
"name": "एल्बम कार्यहरू"
|
||||
},
|
||||
"album-color-theme": {
|
||||
"description": "एल्बम रङ प्यालेटमा आधारित गतिशील विषयवस्तु र दृश्य प्रभावहरू लागू गर्दछ",
|
||||
"menu": {
|
||||
"color-mix-ratio": {
|
||||
"label": "रङ मिश्रण अनुपात",
|
||||
"submenu": {
|
||||
"percent": "{{ratio}}%"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "एल्बम रङ विषयवस्तु"
|
||||
},
|
||||
"ambient-mode": {
|
||||
"description": "तपाईँको स्क्रिनको पृष्ठभूमिमा भिडियोबाट कोमल रङहरू कास्ट गरेर प्रकाश प्रभाव लागू गर्दछ",
|
||||
"menu": {
|
||||
"blur-amount": {
|
||||
"label": "ब्लर रकम",
|
||||
"submenu": {
|
||||
"pixels": "{{blurAmount}} पिक्सेलमा"
|
||||
}
|
||||
},
|
||||
"buffer": {
|
||||
"label": "बफर",
|
||||
"submenu": {
|
||||
"buffer": "{{buffer}}"
|
||||
}
|
||||
},
|
||||
"opacity": {
|
||||
"label": "अपारदर्शिता",
|
||||
"submenu": {
|
||||
"percent": "{{opacity}}%"
|
||||
}
|
||||
},
|
||||
"quality": {
|
||||
"label": "गुणस्तर",
|
||||
"submenu": {
|
||||
"pixels": "{{quality}} पिक्सेलमा"
|
||||
}
|
||||
},
|
||||
"size": {
|
||||
"label": "आकार",
|
||||
"submenu": {
|
||||
"percent": "{{size}}%"
|
||||
}
|
||||
},
|
||||
"smoothness-transition": {
|
||||
"label": "सुगमता संक्रमण",
|
||||
"submenu": {
|
||||
"during": "{{interpolationTime}} सेकेन्ड को समयमा"
|
||||
}
|
||||
},
|
||||
"use-fullscreen": {
|
||||
"label": "फुलस्क्रिन प्रयोग गर्दै"
|
||||
}
|
||||
},
|
||||
"name": "परिवेश मोड"
|
||||
},
|
||||
"audio-compressor": {
|
||||
"description": "अडियोमा कम्प्रेसन लागू गर्नुहोस् (सङ्केतको सबैभन्दा चर्को भागहरूको भोल्युम कम गर्दछ र नरम भागहरूको भोल्युम बढाउँछ)",
|
||||
"name": "अडियो कम्प्रेसर"
|
||||
},
|
||||
"blur-nav-bar": {
|
||||
"description": "नेभिगेसन बारलाई पारदर्शी र धुवाँलो बनाउँछ",
|
||||
"name": "ब्लर नेभिगेसन बार"
|
||||
},
|
||||
"bypass-age-restrictions": {
|
||||
"description": "युट्युबको उमेर प्रमाणिकरणलाई बाइपास गर्नुहोस्",
|
||||
"name": "उमेरका प्रतिबन्धहरू बाइपास गर्नुहोस्"
|
||||
},
|
||||
"captions-selector": {
|
||||
"description": "युट्युब सङ्गीत अडियो ट्र्याकहरूका लागि क्याप्सन चयनकर्ता",
|
||||
"menu": {
|
||||
"autoload": "स्वचालित रूपमा अन्तिम प्रयोग गरिएको क्याप्सन चयन गर्नुहोस्",
|
||||
"disable-captions": "पूर्वनिर्धारित रूपमा कुनै क्याप्सनहरू छैनन्"
|
||||
},
|
||||
"name": "शीर्षक चयनकर्ता",
|
||||
"prompt": {
|
||||
"selector": {
|
||||
"label": "हालको शीर्षक भाषाः {{language}}",
|
||||
"none": "केही छैन",
|
||||
"title": "क्याप्सन भाषा चयन गर्नुहोस्"
|
||||
}
|
||||
},
|
||||
"templates": {
|
||||
"title": "क्याप्सन चयनकर्ता खोल्नुहोस्"
|
||||
}
|
||||
},
|
||||
"compact-sidebar": {
|
||||
"description": "सँधै साइडबारलाई कम्प्याक्ट मोडमा सेट गर्नुहोस्",
|
||||
"name": "कम्प्याक्ट साइडबार"
|
||||
},
|
||||
"crossfade": {
|
||||
"description": "गीतहरू बिच क्रसफेड",
|
||||
"menu": {
|
||||
"advanced": "उन्नत"
|
||||
},
|
||||
"name": "क्रसफेड [बीटा]",
|
||||
"prompt": {
|
||||
"options": {
|
||||
"multi-input": {
|
||||
"fade-in-duration": "फेड इन समय (ms)",
|
||||
"fade-out-duration": "फेड आउट समय (ms)",
|
||||
"fade-scaling": {
|
||||
"label": "फेड स्केलिङ",
|
||||
"linear": "रैखिक",
|
||||
"logarithmic": "लघुगणक"
|
||||
},
|
||||
"seconds-before-end": "अन्त्य हुनुभन्दा अघि क्रसफेड सेकेन्ड"
|
||||
},
|
||||
"title": "क्रसफेड विकल्पहरू"
|
||||
}
|
||||
}
|
||||
},
|
||||
"disable-autoplay": {
|
||||
"description": "\"रोकिएको\" स्मोथिथिमा गीत सुरु गराउँछ",
|
||||
"menu": {
|
||||
"apply-once": "स्टार्टअपमा मात्र लागु हुन्छ"
|
||||
},
|
||||
"name": "स्वतः खेल निष्क्रिय गर्नुहोस्"
|
||||
},
|
||||
"discord": {
|
||||
"backend": {
|
||||
"already-connected": "सक्रिय जडानसँग जडान गर्ने प्रयास गरियो",
|
||||
"connected": "डिस्कर्डमा जोडियो",
|
||||
"disconnected": "डिस्कोर्डबाट डिसकनेक्ट गरियो"
|
||||
},
|
||||
"description": "Rich Presence प्रयोग गरेर साथीहरुलाइ के सुन्दैछु देखाउने",
|
||||
"menu": {
|
||||
"auto-reconnect": "आफै रिकनेक्ट होस्",
|
||||
"clear-activity": "एकटिभिटी क्लियर गर",
|
||||
"clear-activity-after-timeout": "समय पछि एकटिभिटी क्लियर गर",
|
||||
"connected": "कनेक्टेड",
|
||||
"disconnected": "डिसकन्एक्टेड",
|
||||
"hide-duration-left": "बाकी समय लुकाऊ",
|
||||
"hide-github-button": "GitHub लिंक लुकाऊ",
|
||||
"play-on-youtube-music": "YouTube music मा बजाउ",
|
||||
"set-inactivity-timeout": "इनएक्टिभिटी टाइमआउट राख"
|
||||
},
|
||||
"name": "डिसकार्ड रिच प्रीसेंस",
|
||||
"prompt": {
|
||||
"set-inactivity-timeout": {
|
||||
"label": "इनएक्टिभिटी टाइमआउट सेकन्डमा लेख्नुहोस्:",
|
||||
"title": "इनएक्टिभिटी टाइमआउट राख्नुहोस्"
|
||||
}
|
||||
}
|
||||
},
|
||||
"downloader": {
|
||||
"backend": {
|
||||
"dialog": {
|
||||
"error": {
|
||||
"buttons": {
|
||||
"ok": "ओके"
|
||||
},
|
||||
"message": "अह:! माफ गर्नुहोस्, डाउनलोड सफलहुन सकेन…",
|
||||
"title": "डाउनलोडमा त्रुटि भयो!"
|
||||
},
|
||||
"start-download-playlist": {
|
||||
"buttons": {
|
||||
"ok": "ओके"
|
||||
},
|
||||
"detail": "({{playlistSize}}गाना)",
|
||||
"message": "प्लेलिस्ट {{playlistTitle}} डाउनलोड हुदै छ",
|
||||
"title": "डाउनलोड सुरुभयो"
|
||||
}
|
||||
},
|
||||
"feedback": {
|
||||
"conversion-progress": "रूपान्तरणः {{percent}}%",
|
||||
"converting": "रूपान्तरण हुदैछ…",
|
||||
"done": "गरियो: {{filePath}}",
|
||||
"download-info": "{{artist}}को - {{title}}{{videoId}}डाउनलोड हुदैछ",
|
||||
"download-progress": "डाउनलोड: {{percent}}%",
|
||||
"downloading": "डाउनलोड हुदैछ…",
|
||||
"downloading-counter": "{{current}}/{{total}} डाउनलोड गरिदै…",
|
||||
"downloading-playlist": "प्लेलिस्ट \"{{playlistTitle}}\" -{{playlistSize}} गाना {{playlistId}} डाउनलोड गरिदैछ",
|
||||
"error-while-downloading": "\"{{author}}\" - {{title}}\":{{error}} डाउनलोडमा समस्या आयो",
|
||||
"folder-already-exists": "{{playlistFolder}} नाम गरेको फोल्डर अघाडी देखि छ",
|
||||
"getting-playlist-info": "प्लेलिस्टको डाटा हासिल गरिदै छ…",
|
||||
"loading": "लोडिंग…",
|
||||
"playlist-has-only-one-song": "प्लेलिस्टमा एउता मात्रै गानाछ, तेस्लाई डाइरेक्ट डाउनलोड गर्नुहोस",
|
||||
"playlist-id-not-found": "प्लेलिस्ट ID भेटियेन",
|
||||
"playlist-is-empty": "प्लेलिस्ट खाली छ",
|
||||
"playlist-is-mix-or-private": "प्लेलिस्ट जानकारी प्राप्त गर्न त्रुटिः निश्चित गर्नुहोस् कि यो निजी वा \"तपाईँका लागि मिश्रित\" प्लेलिस्ट होइन\n\n{{error}}",
|
||||
"preparing-file": "फाइल तयार गरिदै छ…",
|
||||
"saving": "सेव गरिदै…",
|
||||
"trying-to-get-playlist-id": "प्लेलिस्ट आईडी: {{playlistId}} प्राप्त गर्ने प्रयास",
|
||||
"video-id-not-found": "भिडियो फेला परेन",
|
||||
"writing-id3": "ID3 ट्यागहरू लेखीदै…"
|
||||
}
|
||||
},
|
||||
"description": "इन्टरफेसबाट सिधै MP3/स्रोत अडियो डाउनलोड गर",
|
||||
"menu": {
|
||||
"choose-download-folder": "डाउनलोड फोल्डर चयन गर्नुहोस्",
|
||||
"download-playlist": "डाउनलोड प्लेलिस्ट",
|
||||
"presets": "प्रिसेटहरू",
|
||||
"skip-existing": "विद्यमान फाइलहरू स्किप गर्नुहोस्"
|
||||
},
|
||||
"name": "डाउनलोडर",
|
||||
"renderer": {
|
||||
"can-not-update-progress": "प्रगति अद्यावधिक गर्न सकिँदैन"
|
||||
},
|
||||
"templates": {
|
||||
"button": "डाउनलोड"
|
||||
}
|
||||
},
|
||||
"exponential-volume": {
|
||||
"description": "भोल्युम स्लाइडरलाई घातीय बनाउँछ त्यसैले कम भोल्युमहरू चयन गर्न सजिलो हुन्छ।",
|
||||
"name": "एक्सपोनेन्सियल भोल्युम"
|
||||
},
|
||||
"in-app-menu": {
|
||||
"description": "मेनु-बारहरूलाई फेन्सी, गाढा वा एल्बम-रङ्गको रूप दिन्छ",
|
||||
"menu": {
|
||||
"hide-dom-window-controls": "DOM विन्डो नियन्त्रणहरू लुकाउनुहोस्"
|
||||
},
|
||||
"name": "इन-एप मेनु"
|
||||
},
|
||||
"lumiastream": {
|
||||
"description": "लुमिया स्ट्रिम सपोर्ट थप्दछ",
|
||||
"name": "लुमिया स्ट्रिम [बिटा]"
|
||||
},
|
||||
"lyrics-genius": {
|
||||
"description": "धेरैजसो गीतहरूका लागि लिरिक्स थप्दछ",
|
||||
"menu": {
|
||||
"romanized-lyrics": "रोमनाइज्ड लिरिक्स"
|
||||
},
|
||||
"name": "लिरिक्स जिनियस",
|
||||
"renderer": {
|
||||
"fetched-lyrics": "लिरिक्स जिनियसबाट लिरिक्स प्राप्त गरियो"
|
||||
}
|
||||
},
|
||||
"music-together": {
|
||||
"description": "अरूसँग प्लेलिस्ट साझा गर्नुहोस्। जब होस्टले गीत बजाउँछ, अरू सबैले एउटै गीत सुन्नेछन्",
|
||||
"dialog": {
|
||||
"enter-host": "होस्ट आईडी प्रविष्ट गर्नुहोस्"
|
||||
},
|
||||
"internal": {
|
||||
"save": "सेभ गर्नुहोस्",
|
||||
"track-source": "गानाको स्रोत",
|
||||
"unknown-user": "अज्ञात प्रयोगकर्ता"
|
||||
},
|
||||
"menu": {
|
||||
"click-to-copy-id": "होस्ट आईडी कपी गर्नुहोस्",
|
||||
"close": "मिउजीक टुगेदर बन्द गर्नुहोस्",
|
||||
"connected-users": "जोडिएका प्रयोगकर्ताहरू",
|
||||
"disconnect": "मिउजीक टुगेदर डिस्कनेक्ट गर्नुहोस्",
|
||||
"empty-user": "कोही प्रयोगकर्ताहरू जोडिएका छैनन्",
|
||||
"host": "मिउजीक टुगेदर होस्ट",
|
||||
"join": "मिउजीक टुगेदर जोइन गनुहोस",
|
||||
"permission": {
|
||||
"all": "पाहुनाहरूलाई प्लेलिस्ट र प्लेयर नियन्त्रण गर्न अनुमति दिनुहोस्",
|
||||
"host-only": "केवल होस्टले प्लेलिस्ट र प्लेयर नियन्त्रण गर्न सक्छ",
|
||||
"playlist": "पाहुनाहरूलाई प्लेलिस्ट नियन्त्रण गर्न अनुमति दिनुहोस्"
|
||||
},
|
||||
"set-permission": "नियन्त्रण अनुमति परिवर्तन गर्नुहोस्",
|
||||
"status": {
|
||||
"disconnected": "विच्छेदित",
|
||||
"guest": "पाहुनाका रूपमा जोडियो",
|
||||
"host": "होस्टका रूपमा जोडियो"
|
||||
}
|
||||
},
|
||||
"name": "मिउजीक टुगेदर [बिटा]",
|
||||
"toast": {
|
||||
"add-song-failed": "गीत थप्न असफल",
|
||||
"closed": "मिउजीक टुगेदर बन्द गरियो",
|
||||
"disconnected": "मिउजीक टुगेदर डिसकनेक्टेड",
|
||||
"host-failed": "मिउजीक टुगेदर होस्ट गर्न असफल",
|
||||
"id-copied": "होस्ट आईडी क्लिपबोर्डमा कपी गरियो",
|
||||
"id-copy-failed": "होस्ट आईडी क्लिपबोर्डमा कपी गर्न असफल",
|
||||
"join-failed": "मिउजीक टुगेदर जोइन हुन असफल",
|
||||
"joined": "मिउजीक टुगेदरमा जोडियो",
|
||||
"permission-changed": "मिउजीक टुगेदर अनुमति \"{{permission}}\" मा परिवर्तन गरियो",
|
||||
"remove-song-failed": "गाना हटाउनमा समस्या आयो",
|
||||
"user-connected": "मिउजीक टुगेदरमा {{name}} जोडीनुभायो",
|
||||
"user-disconnected": "{{name}}ले मिउजीक टुगेदर छोडनु भयो"
|
||||
}
|
||||
},
|
||||
"navigation": {
|
||||
"description": "अर्को/पछाडि नेभिगेसन तपाईँको मनपर्ने ब्राउजरमा जस्तै सिधा इन्टरफेसमा एकीकृत तीरहरू",
|
||||
"name": "नेभिगेसन"
|
||||
},
|
||||
"no-google-login": {
|
||||
"description": "इन्टरफेसबाट गुगल लगइन बटन र लिङ्कहरू हटाउनुहोस्",
|
||||
"name": "गुगल लगइन छैन"
|
||||
},
|
||||
"notifications": {
|
||||
"description": "गीत बज्न थाल्दा सूचना देखाउनुहोस् (अन्तरक्रियात्मक सूचनाहरू Windowsमा उपलब्ध छन्)",
|
||||
"menu": {
|
||||
"interactive": "अन्तरक्रियात्मक सूचनाहरू",
|
||||
"interactive-settings": {
|
||||
"label": "अन्तरक्रियात्मक सेटिङहरू",
|
||||
"submenu": {
|
||||
"hide-button-text": "टेक्सट बटन लुकाउनुहोस्",
|
||||
"refresh-on-play-pause": "प्ले/पोजमा ताजा गर्नुहोस्",
|
||||
"tray-controls": "ट्रेमा क्लिक गर्दा खोल्नुहोस्/बन्द गर्नुहोस्"
|
||||
}
|
||||
},
|
||||
"priority": "अधिसूचना प्राथमिकता",
|
||||
"toast-style": "टोस्ट शैली",
|
||||
"unpause-notification": "अनपउसमा सूचना देखाउनुहोस्"
|
||||
},
|
||||
"name": "सूचनाहरू"
|
||||
},
|
||||
"picture-in-picture": {
|
||||
"description": "एपलाई पिक्चर-इन-पिक्चर मोडमा परिवर्तन गर्न अनुमति दिन्छ",
|
||||
"menu": {
|
||||
"always-on-top": "सधैँ शीर्षमा",
|
||||
"hotkey": {
|
||||
"label": "हटकी",
|
||||
"prompt": {
|
||||
"keybind-options": {
|
||||
"hotkey": "हटकी"
|
||||
},
|
||||
"label": "पिक्चर-इन-पिक्चर टगल गर्न हटकी छान्नुहोस्",
|
||||
"title": "पिक्चर-इन-पिक्चर हटकी"
|
||||
}
|
||||
},
|
||||
"save-window-position": "windowको स्थान सेव गर्नुहोस्",
|
||||
"save-window-size": "windowको आकार सेव गर्नुहोस्",
|
||||
"use-native-pip": "ब्राउजरको नेटिभ PiP प्रयोग गर्नुहोस्"
|
||||
},
|
||||
"name": "पिक्चर-इन-पिक्चर",
|
||||
"templates": {
|
||||
"button": "पिक्चर-इन-पिक्चर"
|
||||
}
|
||||
},
|
||||
"playback-speed": {
|
||||
"description": "छिटो सुन्नुहोस्, ढिलो सुन्नुहोस्! एसले गीतको गति नियन्त्रण गर्ने स्लाइडर थप्छ",
|
||||
"name": "प्लेब्याक स्पीड",
|
||||
"templates": {
|
||||
"button": "स्पीड"
|
||||
}
|
||||
},
|
||||
"precise-volume": {
|
||||
"description": "कस्टम HUD र अनुकूलन योग्य भोल्युम चरणहरूको साथ माउसव्हील/हटकीहरू प्रयोग गरेर भोल्युम नियन्त्रण गर्नुहोस्",
|
||||
"menu": {
|
||||
"arrows-shortcuts": "लोकल एरो-की नियन्त्रणहरू",
|
||||
"custom-volume-steps": "कस्टम भोल्युम चरणहरू सेट गर्नुहोस्",
|
||||
"global-shortcuts": "ग्लोबल हटकीहरू"
|
||||
},
|
||||
"name": "सटीक भोल्युम",
|
||||
"prompt": {
|
||||
"global-shortcuts": {
|
||||
"keybind-options": {
|
||||
"decrease": "भोल्युम घटाउनुहोस्",
|
||||
"increase": "भोल्युम बढाउनुहोस्"
|
||||
},
|
||||
"label": "ग्लोबल भोल्युम किबाइन्डहरू चयन गर्नुहोस्:",
|
||||
"title": "ग्लोबल भोल्युम किबाइन्डहरू"
|
||||
},
|
||||
"volume-steps": {
|
||||
"label": "भोल्युम वृद्धि/घटाउने चरणहरू चयन गर्नुहोस्",
|
||||
"title": "भोल्युमका चरणहरू"
|
||||
}
|
||||
}
|
||||
},
|
||||
"quality-changer": {
|
||||
"backend": {
|
||||
"dialog": {
|
||||
"quality-changer": {
|
||||
"detail": "हालको गुणस्तरः {{quality}}",
|
||||
"message": "भिडियो गुणस्तर चयन गर्नुहोस्:",
|
||||
"title": "भिडियोको गुणस्तर चयन गर्नुहोस्"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": "भिडियो ओभरलेमा बटनको साथ भिडियो गुणस्तर परिवर्तन गर्न अनुमति दिन्छ",
|
||||
"name": "भिडियो गुणस्तर परिवर्तनकर्ता"
|
||||
},
|
||||
"scrobbler": {
|
||||
"description": "स्क्रोब्लिङ समर्थन थप्नुहोस् (etc. last.fm, Listenbrainz)",
|
||||
"dialog": {
|
||||
"lastfm": {
|
||||
"auth-failed": {
|
||||
"message": "Last.fm सँग प्रमाणिकरण गर्न असफल\nअर्को पुनः सुरु नभएसम्म पपअप लुकाउनुहोस्।",
|
||||
"title": "प्रमाणीकरण असफल"
|
||||
}
|
||||
}
|
||||
},
|
||||
"menu": {
|
||||
"lastfm": {
|
||||
"api-settings": "Last.fm API सेटिङहरू"
|
||||
},
|
||||
"listenbrainz": {
|
||||
"token": "ListenBrainz प्रयोगकर्ता टोकन प्रविष्ट गर्नुहोस्"
|
||||
},
|
||||
"scrobble-other-media": "अन्य मिडियालाई स्क्रबल गर्नुहोस्"
|
||||
},
|
||||
"name": "स्क्रबबलर",
|
||||
"prompt": {
|
||||
"lastfm": {
|
||||
"api-key": "Last.fm API कुञ्जी",
|
||||
"api-secret": "Last.fm एपीआई गुप्त"
|
||||
},
|
||||
"listenbrainz": {
|
||||
"token": {
|
||||
"label": "आफ्नो ListenBrainz प्रयोगकर्ता टोकन प्रविष्ट गर्नुहोस्:",
|
||||
"title": "ListenBrainz टोकन"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"shortcuts": {
|
||||
"description": "प्लेब्याक (प्ले/विराम/अर्को/अघिल्लो) का लागि ग्लोबल हटकीहरू सेट गर्न र मिडिया कुञ्जीहरू ओभरराइड गरेर मिडिया ओएसडी बन्द गर्न अनुमति दिन्छ, खोजी गर्न Ctrl/CMD + F सक्रिय गर्दछ, मिडिया कुञ्जीहरूका लागि लिनक्स MPRIS र उन्नत प्रयोगकर्ताहरूका लागि कस्टम हटकीहरू समर्थन सक्रिय गर्दछ",
|
||||
"menu": {
|
||||
"override-media-keys": "मिडिया कुञ्जीहरूलाई ओभरराइड गर्नुहोस्",
|
||||
"set-keybinds": "विश्वव्यापी गीत नियन्त्रणहरू सेट गर्नुहोस्"
|
||||
},
|
||||
"name": "सर्टकटहरू (& MPRIS)",
|
||||
"prompt": {
|
||||
"keybind": {
|
||||
"keybind-options": {
|
||||
"next": "अर्को",
|
||||
"play-pause": "खेल्नुहोस् / रोक्नुहोस्",
|
||||
"previous": "अघिल्ला"
|
||||
},
|
||||
"label": "गीत नियन्त्रणका लागि ग्लोबल किबाइन्डहरू छान्नुहोस्:",
|
||||
"title": "ग्लोबल किबाइन्डहरू"
|
||||
}
|
||||
}
|
||||
},
|
||||
"skip-disliked-songs": {
|
||||
"description": "नापसन्द गरिएका गीतहरू छोड्नुहोस्",
|
||||
"name": "मन नपरेका गीतहरू छोड्नुहोस्"
|
||||
},
|
||||
"skip-silences": {
|
||||
"description": "गीतहरूमा मौन खण्डहरू स्वचालित रूपमा स्किप गर्नुहोस्",
|
||||
"name": "मौन छोड्नुहोस्"
|
||||
},
|
||||
"sponsorblock": {
|
||||
"description": "स्वचालित रूपमा गैर-सङ्गीत भागहरू जस्तै इन्ट्रो/आउट्रो वा सङ्गीत भिडियोका भागहरू छोड्नुहोस्",
|
||||
"name": "स्पन्सरब्लक"
|
||||
},
|
||||
"taskbar-mediacontrol": {
|
||||
"description": "तपाईँको विन्डोज टास्कबारबाट प्लेब्याक नियन्त्रण गर्नुहोस्",
|
||||
"name": "टास्कबार मेडिया कन्ट्रोल"
|
||||
},
|
||||
"touchbar": {
|
||||
"description": "MacOS प्रयोगकर्ताहरूका लागि टचबार विजेट थप्दछ",
|
||||
"name": "टचबार"
|
||||
},
|
||||
"tuna-obs": {
|
||||
"description": "OBS को टुना प्लगइनसँग एकीकरण",
|
||||
"name": "टुना OBS"
|
||||
},
|
||||
"video-toggle": {
|
||||
"description": "भिडियो/गीत मोड बीच स्विच गर्न बटन थप्दछ। वैकल्पिक रूपमा सम्पूर्ण भिडियो ट्याब हटाउन पनि सक्छ",
|
||||
"menu": {
|
||||
"align": {
|
||||
"label": "संरेखण",
|
||||
"submenu": {
|
||||
"left": "बायाँ",
|
||||
"middle": "बिचमा",
|
||||
"right": "दायाँ"
|
||||
}
|
||||
},
|
||||
"force-hide": "बलपूर्वक भिडियो ट्याब हटाउनुहोस्",
|
||||
"mode": {
|
||||
"label": "मोड",
|
||||
"submenu": {
|
||||
"custom": "कस्टम टगल",
|
||||
"disabled": "अक्षम",
|
||||
"native": "नेटिभ टगल"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "भिडियो टगल",
|
||||
"templates": {
|
||||
"button": "गीत"
|
||||
}
|
||||
},
|
||||
"visualizer": {
|
||||
"description": "प्लेयरमा भिजुअलाइजर थप्छ",
|
||||
"menu": {
|
||||
"visualizer-type": "भिजुअलाइजरको प्रकार"
|
||||
},
|
||||
"name": "भिजुअलाइजर"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2,50 +2,569 @@
|
||||
"common": {
|
||||
"console": {
|
||||
"plugins": {
|
||||
"execute-failed": "Kan plug-in {{pluginName}}::{{contextName}} niet uitvoeren",
|
||||
"executed-at-ms": "Plug-in {{pluginName}}::{{contextName}} uitgevoerd in {{ms}}ms",
|
||||
"initialize-failed": "Kan plug-in \"{{pluginName}}\" niet laden",
|
||||
"load-all": "Alle plug-ins laden",
|
||||
"load-failed": "Kan plug-in \"{{pluginName}}\" niet laden",
|
||||
"loaded": "Plug-in \"{{pluginName}}\" geladen",
|
||||
"unload-failed": "Kan plug-in \"{{pluginName}}\" niet verwijderen",
|
||||
"unloaded": "Plug-in \"{{pluginName}}\" geladen"
|
||||
"execute-failed": "Mislukt om plugin {{pluginName}}::{{contextName}} uit te voeren",
|
||||
"executed-at-ms": "Plugin {{pluginName}}::{{contextName}} uitgevoerd in {{ms}}ms",
|
||||
"initialize-failed": "Initialisatie van plugin \"{{pluginName}}\" mislukt",
|
||||
"load-all": "Alle plugins laden",
|
||||
"load-failed": "Mislukt om plugin \"{{pluginName}}\" te laden",
|
||||
"loaded": "Plugin \"{{pluginName}}\" geladen",
|
||||
"unload-failed": "Mislukt om plugin \"{{pluginName}}\" te lossen",
|
||||
"unloaded": "Plugin \"{{pluginName}}\" gelost"
|
||||
}
|
||||
}
|
||||
},
|
||||
"language": {
|
||||
"code": "nl",
|
||||
"local-name": "Nederlands",
|
||||
"name": "Dutch"
|
||||
"name": "Nederlands"
|
||||
},
|
||||
"main": {
|
||||
"console": {
|
||||
"did-finish-load": {
|
||||
"dev-tools": "Klaar met laden, DevTools geopend"
|
||||
"dev-tools": "Laden voltooid. DevTools geopend"
|
||||
},
|
||||
"i18n": {
|
||||
"loaded": "i18n geladen"
|
||||
},
|
||||
"second-instance": {
|
||||
"receive-command": "Ontvangen commando via protocol: \"{{command}}\""
|
||||
"receive-command": "Commando ontvangen via protocol: \"{{command}}\""
|
||||
},
|
||||
"theme": {
|
||||
"css-file-not-found": "CSS bestand \"{{cssFile}}\" niet gevonden"
|
||||
"css-file-not-found": "CSS-bestand \"{{cssFile}}\" bestaat niet, wordt genegeerd"
|
||||
},
|
||||
"unresponsive": {
|
||||
"details": "Niet reagerend door fout:\n{{error}}"
|
||||
"details": "Onverantwoordelijkheidsfout!\n{{error}}"
|
||||
},
|
||||
"when-ready": {
|
||||
"clearing-cache-after-20s": "App-cache wissen"
|
||||
},
|
||||
"window": {
|
||||
"tried-to-render-offscreen": "Venster probeerde buiten het scherm te renderen, venstergrootte={{windowSize}}, schermgrootte={{displaySize}}, positie={{position}}"
|
||||
"tried-to-render-offscreen": "Venster probeerde buiten het scherm te renderen, venstergrootte={{windowSize}}, weergavegrootte={{displaySize}}, positie={{position}}"
|
||||
}
|
||||
},
|
||||
"dialog": {
|
||||
"hide-menu-enabled": {
|
||||
"detail": "Menu is verborgen, gebruik 'Alt' om het te tonen (of 'Escape' als u het In-App Menu gebruikt)"
|
||||
"detail": "Menu is verborgen, gebruik 'Alt' om het weer te geven (of 'Escape' als u de In-App Menu gebruikt)",
|
||||
"message": "Menu verbergen is ingeschakeld",
|
||||
"title": "Menu Verbergen Ingeschakeld"
|
||||
},
|
||||
"need-to-restart": {
|
||||
"buttons": {
|
||||
"later": "Later",
|
||||
"restart-now": "Nu Opnieuw Opstarten"
|
||||
},
|
||||
"detail": "\"{{pluginName}}\" plugin vereist een herstart om van kracht te worden",
|
||||
"message": "\"{{pluginName}}\" moet opnieuw worden opgestart",
|
||||
"title": "Herstart Vereist"
|
||||
},
|
||||
"unresponsive": {
|
||||
"buttons": {
|
||||
"quit": "Stoppen",
|
||||
"relaunch": "Opnieuw starten",
|
||||
"wait": "Wachten"
|
||||
},
|
||||
"detail": "Het programma reageert niet! Kies wat u wilt doen:",
|
||||
"message": "De applicatie reageert niet",
|
||||
"title": "Venster Niet Reagerend"
|
||||
},
|
||||
"update-available": {
|
||||
"buttons": {
|
||||
"disable": "Updates uitschakelen",
|
||||
"download": "Downloaden",
|
||||
"ok": "OK"
|
||||
},
|
||||
"detail": "Er is een nieuwe versie beschikbaar en kan worden gedownload op {{downloadLink}}",
|
||||
"message": "Een nieuwe versie is beschikbaar",
|
||||
"title": "Update Beschikbaar"
|
||||
}
|
||||
},
|
||||
"menu": {
|
||||
"about": "Over",
|
||||
"navigation": {
|
||||
"label": "Navigatie",
|
||||
"submenu": {
|
||||
"copy-current-url": "Huidige URL kopiëren",
|
||||
"go-back": "Terug",
|
||||
"go-forward": "Vooruit",
|
||||
"quit": "Afsluiten",
|
||||
"restart": "Applicatie Opnieuw Opstarten"
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"label": "Opties",
|
||||
"submenu": {
|
||||
"advanced-options": {
|
||||
"label": "Geavanceerde opties",
|
||||
"submenu": {
|
||||
"auto-reset-app-cache": "App-cache resetten bij het starten van de app",
|
||||
"disable-hardware-acceleration": "Hardwareversnelling uitschakelen",
|
||||
"edit-config-json": "Config.json bewerken",
|
||||
"override-user-agent": "Gebruikersagent overschrijven",
|
||||
"restart-on-config-changes": "Herstarten bij configuratiewijzigingen",
|
||||
"set-proxy": {
|
||||
"label": "Proxy instellen",
|
||||
"prompt": {
|
||||
"label": "Proxy-adres invoeren: (leeg laten om uit te schakelen)",
|
||||
"placeholder": "Voorbeeld: SOCKS5://127.0.0.1:9999",
|
||||
"title": "Proxy instellen"
|
||||
}
|
||||
},
|
||||
"toggle-dev-tools": "DevTools schakelen"
|
||||
}
|
||||
},
|
||||
"always-on-top": "Altijd bovenop",
|
||||
"auto-update": "Automatisch bijwerken",
|
||||
"hide-menu": {
|
||||
"dialog": {
|
||||
"message": "Menu wordt verborgen bij de volgende start, gebruik [Alt] om het weer te geven (of backtick [`] als u de in-app-menu gebruikt)",
|
||||
"title": "Menu Verbergen Ingeschakeld"
|
||||
},
|
||||
"label": "Menu Verbergen"
|
||||
},
|
||||
"language": {
|
||||
"dialog": {
|
||||
"message": "Taal wordt gewijzigd na herstart",
|
||||
"title": "Taal Gewijzigd"
|
||||
},
|
||||
"label": "Taal",
|
||||
"submenu": {
|
||||
"to-help-translate": "Wil je helpen vertalen? Klik hier"
|
||||
}
|
||||
},
|
||||
"resume-on-start": "Hervat laatste liedje bij het opstarten van de app",
|
||||
"single-instance-lock": "Eenmalige instantievergrendeling",
|
||||
"start-at-login": "Starten bij het inloggen",
|
||||
"starting-page": {
|
||||
"label": "Startpagina",
|
||||
"unset": "Niet ingesteld"
|
||||
},
|
||||
"tray": {
|
||||
"label": "Systeemvak",
|
||||
"submenu": {
|
||||
"disabled": "Uitgeschakeld",
|
||||
"enabled-and-hide-app": "Ingeschakeld en applicatie verbergen",
|
||||
"enabled-and-show-app": "Ingeschakeld en applicatie weergeven",
|
||||
"play-pause-on-click": "Afspelen/Pauzeren bij klikken"
|
||||
}
|
||||
},
|
||||
"visual-tweaks": {
|
||||
"label": "Visuele Aanpassingen",
|
||||
"submenu": {
|
||||
"like-buttons": {
|
||||
"default": "Standaard",
|
||||
"force-show": "Forceren weergeven",
|
||||
"hide": "Verbergen",
|
||||
"label": "Vind ik leuk-knoppen"
|
||||
},
|
||||
"remove-upgrade-button": "Upgrade-knop verwijderen",
|
||||
"theme": {
|
||||
"dialog": {
|
||||
"button": {
|
||||
"cancel": "Annuleren",
|
||||
"remove": "Verwijderen"
|
||||
},
|
||||
"remove-theme": "Weet je zeker dat je het aangepaste thema wilt verwijderen?",
|
||||
"remove-theme-message": "Dit verwijderd het aangepaste thema"
|
||||
},
|
||||
"label": "Thema",
|
||||
"submenu": {
|
||||
"import-css-file": "Aangepast CSS-bestand importeren",
|
||||
"no-theme": "Geen thema"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"plugins": {
|
||||
"enabled": "Ingeschakeld",
|
||||
"label": "Plugins",
|
||||
"new": "NIEUW"
|
||||
},
|
||||
"view": {
|
||||
"label": "Weergave",
|
||||
"submenu": {
|
||||
"force-reload": "Forceer Herladen",
|
||||
"reload": "Herladen",
|
||||
"reset-zoom": "Ware Grootte",
|
||||
"toggle-fullscreen": "Volledig Scherm Wisselen",
|
||||
"zoom-in": "Inzoomen",
|
||||
"zoom-out": "Uitzoomen"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tray": {
|
||||
"next": "Volgende",
|
||||
"play-pause": "Afspelen/Pauzeren",
|
||||
"previous": "Vorige",
|
||||
"quit": "Afsluiten",
|
||||
"restart": "Applicatie Opnieuw Opstarten",
|
||||
"show": "Venster Weergeven",
|
||||
"tooltip": {
|
||||
"default": "YouTube Music",
|
||||
"with-song-info": "YouTube Music: {{artist}} - {{title}}"
|
||||
}
|
||||
}
|
||||
},
|
||||
"plugins": {
|
||||
"ad-speedup": {
|
||||
"description": "Wanneer een advertentie afspeelt, dempt het geluid en versnelt de playback naar 16x",
|
||||
"name": "Snellere advertenties"
|
||||
},
|
||||
"adblocker": {
|
||||
"description": "Blokkeer alle advertenties en tracking vanuit de doos",
|
||||
"menu": {
|
||||
"blocker": "Blokkeerder"
|
||||
},
|
||||
"name": "Advertentieblokkeerder"
|
||||
},
|
||||
"album-actions": {
|
||||
"description": "Voegt knoppen toe voor Ondisliken, Disliken, Liken en Ontliken om dit toe te passen op alle nummers in een afspeellijst of album",
|
||||
"name": "Albumacties"
|
||||
},
|
||||
"album-color-theme": {
|
||||
"description": "Past een dynamisch thema en visuele effecten toe op basis van het kleurenpalet van het album",
|
||||
"menu": {
|
||||
"color-mix-ratio": {
|
||||
"label": "Kleurmixverhouding",
|
||||
"submenu": {
|
||||
"percent": "{{ratio}}%"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "Albumkleurthema"
|
||||
},
|
||||
"ambient-mode": {
|
||||
"description": "Past een verlichtingseffect toe door zachte kleuren van de video op het achtergrondscherm te werpen",
|
||||
"menu": {
|
||||
"blur-amount": {
|
||||
"label": "Vervagingshoeveelheid",
|
||||
"submenu": {
|
||||
"pixels": "{{blurAmount}} pixels"
|
||||
}
|
||||
},
|
||||
"buffer": {
|
||||
"label": "Buffer",
|
||||
"submenu": {
|
||||
"buffer": "{{buffer}}"
|
||||
}
|
||||
},
|
||||
"opacity": {
|
||||
"label": "Dekking",
|
||||
"submenu": {
|
||||
"percent": "{{opacity}}%"
|
||||
}
|
||||
},
|
||||
"quality": {
|
||||
"label": "Kwaliteit",
|
||||
"submenu": {
|
||||
"pixels": "{{quality}} pixels"
|
||||
}
|
||||
},
|
||||
"size": {
|
||||
"label": "Formaat",
|
||||
"submenu": {
|
||||
"percent": "{{size}}%"
|
||||
}
|
||||
},
|
||||
"smoothness-transition": {
|
||||
"label": "Soepelheid overgang",
|
||||
"submenu": {
|
||||
"during": "Tijdens {{interpolationTime}} s"
|
||||
}
|
||||
},
|
||||
"use-fullscreen": {
|
||||
"label": "Volledig scherm gebruiken"
|
||||
}
|
||||
},
|
||||
"name": "Omgevingsmodus"
|
||||
},
|
||||
"audio-compressor": {
|
||||
"description": "Past compressie toe op audio (verlaagt het volume van de luidste delen van het signaal en verhoogt het volume van de zachtste delen)",
|
||||
"name": "Audiocompressor"
|
||||
},
|
||||
"blur-nav-bar": {
|
||||
"description": "Maakt de navigatiebalk transparant en wazig",
|
||||
"name": "Vervagen Navigatiebalk"
|
||||
},
|
||||
"bypass-age-restrictions": {
|
||||
"description": "Omzeil de leeftijdsverificatie van YouTube",
|
||||
"name": "Leeftijdsbeperkingen Omzeilen"
|
||||
},
|
||||
"captions-selector": {
|
||||
"description": "Ondertitelkeuze voor YouTube Music-audiotracks",
|
||||
"menu": {
|
||||
"autoload": "Automatisch de laatst gebruikte ondertitel selecteren",
|
||||
"disable-captions": "Standaard geen ondertitels"
|
||||
},
|
||||
"name": "Ondertitelkeuze",
|
||||
"prompt": {
|
||||
"selector": {
|
||||
"label": "Huidige ondertitel taal: {{language}}",
|
||||
"none": "Geen",
|
||||
"title": "Selecteer ondertitel taal"
|
||||
}
|
||||
},
|
||||
"templates": {
|
||||
"title": "Open ondertitelkeuze"
|
||||
}
|
||||
},
|
||||
"compact-sidebar": {
|
||||
"description": "Stel de zijbalk altijd in op compacte modus",
|
||||
"name": "Compacte Zijbalk"
|
||||
},
|
||||
"crossfade": {
|
||||
"description": "Vervagen tussen nummers",
|
||||
"menu": {
|
||||
"advanced": "Geavanceerd"
|
||||
},
|
||||
"name": "Crossfade [Beta]",
|
||||
"prompt": {
|
||||
"options": {
|
||||
"multi-input": {
|
||||
"fade-in-duration": "Fade-in-duur (ms)",
|
||||
"fade-out-duration": "Fade-out-duur (ms)",
|
||||
"fade-scaling": {
|
||||
"label": "Vervagingschaal",
|
||||
"linear": "Lineair",
|
||||
"logarithmic": "Logaritmisch"
|
||||
},
|
||||
"seconds-before-end": "Vervagen N seconden voor het einde"
|
||||
},
|
||||
"title": "Crossfade-opties"
|
||||
}
|
||||
}
|
||||
},
|
||||
"disable-autoplay": {
|
||||
"description": "Zorgt ervoor dat nummers starten in 'gepauzeerde' modus",
|
||||
"menu": {
|
||||
"apply-once": "Alleen toepassen bij opstarten"
|
||||
},
|
||||
"name": "Automatisch afspelen uitschakelen"
|
||||
},
|
||||
"discord": {
|
||||
"backend": {
|
||||
"already-connected": "Geprobeerd verbinding te maken met een actieve verbinding",
|
||||
"connected": "Verbonden met Discord",
|
||||
"disconnected": "Verbinding met Discord verbroken"
|
||||
},
|
||||
"description": "Laat je vrienden zien waar je naar luistert met Rich Presence",
|
||||
"menu": {
|
||||
"auto-reconnect": "Automatisch opnieuw verbinden",
|
||||
"clear-activity": "Activiteit wissen",
|
||||
"clear-activity-after-timeout": "Activiteit na time-out wissen",
|
||||
"connected": "Verbonden",
|
||||
"disconnected": "Verbinding verbroken",
|
||||
"hide-duration-left": "Verberg resterende tijd",
|
||||
"hide-github-button": "GitHub-knop verbergen",
|
||||
"play-on-youtube-music": "Afspelen op YouTube Music",
|
||||
"set-inactivity-timeout": "Inactiviteitstime-out instellen"
|
||||
},
|
||||
"name": "Discord Rich Presence",
|
||||
"prompt": {
|
||||
"set-inactivity-timeout": {
|
||||
"label": "Voer inactiviteitstime-out in seconden in:",
|
||||
"title": "Inactiviteitstime-out instellen"
|
||||
}
|
||||
}
|
||||
},
|
||||
"downloader": {
|
||||
"backend": {
|
||||
"dialog": {
|
||||
"error": {
|
||||
"buttons": {
|
||||
"ok": "Oke"
|
||||
},
|
||||
"message": "Excuses, de download is mislukt…",
|
||||
"title": "Er is een fout opgetreden tijdens het downloaden!"
|
||||
},
|
||||
"start-download-playlist": {
|
||||
"buttons": {
|
||||
"ok": "Oké"
|
||||
},
|
||||
"detail": "({{playlistSize}} nummers)",
|
||||
"message": "Afspeellijst \"{{playlistTitle}}\" aan het downloaden",
|
||||
"title": "Download is gestart"
|
||||
}
|
||||
},
|
||||
"feedback": {
|
||||
"conversion-progress": "Converteren: {{percent}}%",
|
||||
"converting": "Converteren…",
|
||||
"done": "Gereed: {{filePath}}",
|
||||
"download-info": "{{artist}} - {{title}} ([{{videoId}}) aan het downloaden",
|
||||
"download-progress": "Downloaden: {{percent}}%",
|
||||
"downloading": "Aan het downloaden…",
|
||||
"downloading-counter": "{{current}}/{{total}} aan het downloaden…",
|
||||
"downloading-playlist": "Afspeellijst \"{{playlistTitle}}\" {{playlistId}} aan het downloaden ({{playlistSize}} liederen)",
|
||||
"error-while-downloading": "Er is een fout opgetreden tijdens het downloaden van \"{{author}} - {{title}}\": {{error}}",
|
||||
"folder-already-exists": "De map \"{{playlistFolder}}\" bestaat al",
|
||||
"getting-playlist-info": "Afspeellijst informatie ophalen…",
|
||||
"loading": "Laden…",
|
||||
"playlist-has-only-one-song": "Afspeellijst heeft maar 1 item, item direct aan het downloaden",
|
||||
"playlist-id-not-found": "Geen playlist ID gevonden",
|
||||
"playlist-is-empty": "Afspeellijst is leeg",
|
||||
"playlist-is-mix-or-private": "Er is een fout opgetreden tijdens het ophalen van de afspeellijst informatie: zorg ervoor dat het geen verborgen of \"Mixed for you\" afspeellijst is\n\n{{error}}",
|
||||
"preparing-file": "Bestand voorbereiden…",
|
||||
"saving": "Opslaan…",
|
||||
"trying-to-get-playlist-id": "Proberen om het afspeellijst ID op te halen: {{playlistId}}",
|
||||
"video-id-not-found": "Video niet gevonden",
|
||||
"writing-id3": "ID3 tags aan het schrijven…"
|
||||
}
|
||||
},
|
||||
"description": "Download MP3 / bron-audio rechtstreeks vanuit de interface",
|
||||
"menu": {
|
||||
"choose-download-folder": "Kies de downloadmap",
|
||||
"download-finish-settings": {
|
||||
"label": "Downloaden bij voltooiing",
|
||||
"prompt": {
|
||||
"last-percent": "Na x procent",
|
||||
"last-seconds": "Laatste x seconden",
|
||||
"title": "Configureren wanneer te downloaden"
|
||||
},
|
||||
"submenu": {
|
||||
"advanced": "Geavanceerd",
|
||||
"enabled": "Ingeschakeld",
|
||||
"mode": "Tijd-modus",
|
||||
"percent": "Procent",
|
||||
"seconds": "Seconden"
|
||||
}
|
||||
},
|
||||
"download-playlist": "Afspeellijst downloaden",
|
||||
"presets": "Voorinstellingen",
|
||||
"skip-existing": "Bestaande bestanden overslaan"
|
||||
},
|
||||
"name": "Downloader",
|
||||
"renderer": {
|
||||
"can-not-update-progress": "Kan de voortgang niet bijwerken"
|
||||
},
|
||||
"templates": {
|
||||
"button": "Download"
|
||||
}
|
||||
},
|
||||
"exponential-volume": {
|
||||
"description": "Maakt de volumeschuif exponentieel zodat het gemakkelijker is om lagere volumes te selecteren.",
|
||||
"name": "Exponentieel Volume"
|
||||
},
|
||||
"in-app-menu": {
|
||||
"description": "Geeft menubalken een chique, donkere of albumkleurige uitstraling",
|
||||
"menu": {
|
||||
"hide-dom-window-controls": "Verberg DOM-vensterbedieningselementen"
|
||||
},
|
||||
"name": "In-App menu"
|
||||
},
|
||||
"lumiastream": {
|
||||
"description": "Voegt ondersteuning voor Lumia Stream toe",
|
||||
"name": "Lumia Stream [Beta]"
|
||||
},
|
||||
"lyrics-genius": {
|
||||
"description": "Voegt tekstondersteuning toe voor de meeste nummers",
|
||||
"menu": {
|
||||
"romanized-lyrics": "Geromaniseerde Teksten"
|
||||
},
|
||||
"name": "Lyrics Genius",
|
||||
"renderer": {
|
||||
"fetched-lyrics": "Teksten opgehaald voor Genius"
|
||||
}
|
||||
},
|
||||
"music-together": {
|
||||
"description": "Deel een afspeellijst met anderen. Wanneer de host een nummer afspeelt, hoort iedereen hetzelfde nummer",
|
||||
"dialog": {
|
||||
"enter-host": "Voer Host-ID in"
|
||||
},
|
||||
"internal": {
|
||||
"save": "Opslaan",
|
||||
"track-source": "Bron van nummers",
|
||||
"unknown-user": "Onbekende gebruiker"
|
||||
},
|
||||
"menu": {
|
||||
"click-to-copy-id": "Host-ID kopiëren",
|
||||
"close": "Sluit Music Samen",
|
||||
"connected-users": "Verbonden gebruikers",
|
||||
"disconnect": "Music Samen verbreken",
|
||||
"empty-user": "Geen verbonden gebruikers",
|
||||
"host": "Music Samen Host",
|
||||
"join": "Voeg Music Samen toe",
|
||||
"permission": {
|
||||
"all": "Gasten toestaan de afspeellijst en speler te bedienen",
|
||||
"host-only": "Alleen de host kan de afspeellijst en speler bedienen",
|
||||
"playlist": "Gasten toestaan de afspeellijst te bedienen"
|
||||
},
|
||||
"set-permission": "Bedieningsmachtiging wijzigen",
|
||||
"status": {
|
||||
"disconnected": "Verbroken",
|
||||
"guest": "Verbonden als Gast",
|
||||
"host": "Verbonden als Host"
|
||||
}
|
||||
},
|
||||
"name": "Music Samen [Beta]",
|
||||
"toast": {
|
||||
"add-song-failed": "Toevoegen van nummer mislukt",
|
||||
"closed": "Music Samen gesloten",
|
||||
"disconnected": "Music Samen verbroken",
|
||||
"host-failed": "Hosten van Music Samen mislukt",
|
||||
"id-copied": "Host-ID gekopieerd naar klembord",
|
||||
"id-copy-failed": "Kopiëren van Host-ID naar klembord mislukt",
|
||||
"join-failed": "Aansluiten bij Music Samen mislukt",
|
||||
"joined": "Music Samen toegetreden",
|
||||
"permission-changed": "Music Samen machtiging gewijzigd naar \"{{permission}}\"",
|
||||
"remove-song-failed": "Verwijderen van nummer mislukt",
|
||||
"user-connected": "{{name}} heeft Music Samen toegetreden",
|
||||
"user-disconnected": "{{name}} heeft Music Samen verlaten"
|
||||
}
|
||||
},
|
||||
"navigation": {
|
||||
"description": "Volgende/Vorige navigatiepijlen rechtstreeks geïntegreerd in de interface, zoals in je favoriete browser",
|
||||
"name": "Navigatie"
|
||||
},
|
||||
"no-google-login": {
|
||||
"description": "Verwijder Google aanmeldknoppen en -links uit de interface",
|
||||
"name": "Geen Google Aanmelding"
|
||||
},
|
||||
"notifications": {
|
||||
"description": "Toont een melding wanneer een nummer begint te spelen (interactieve meldingen zijn beschikbaar op Windows)",
|
||||
"menu": {
|
||||
"interactive": "Interactieve Meldingen",
|
||||
"interactive-settings": {
|
||||
"label": "Interactieve instellingen",
|
||||
"submenu": {
|
||||
"hide-button-text": "Verberg tekst op de knop",
|
||||
"refresh-on-play-pause": "Herlaad bij het afspelen/pauzeren"
|
||||
}
|
||||
},
|
||||
"unpause-notification": "Laat een notificatie zijn bij het depauzeren"
|
||||
},
|
||||
"name": "Meldingen"
|
||||
},
|
||||
"picture-in-picture": {
|
||||
"menu": {
|
||||
"always-on-top": "Altijd bovenaan",
|
||||
"hotkey": {
|
||||
"label": "Sneltoets",
|
||||
"prompt": {
|
||||
"keybind-options": {
|
||||
"hotkey": "Sneltoets"
|
||||
}
|
||||
}
|
||||
},
|
||||
"save-window-position": "Sla schermpositie op",
|
||||
"save-window-size": "Sla schermgrootte op"
|
||||
}
|
||||
},
|
||||
"video-toggle": {
|
||||
"menu": {
|
||||
"mode": {
|
||||
"submenu": {
|
||||
"disabled": "Uitgeschakeld"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"visualizer": {
|
||||
"description": "Voeg een visuele equalizer toe",
|
||||
"menu": {
|
||||
"visualizer-type": "Type visualisator"
|
||||
},
|
||||
"name": "Visualisator"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -104,7 +104,7 @@
|
||||
"set-proxy": {
|
||||
"label": "Ustaw proxy",
|
||||
"prompt": {
|
||||
"label": "Podaj adres Proxy: (zostaw pusty aby wyłączyć)",
|
||||
"label": "Podaj adres proxy: (zostaw pusty aby wyłączyć)",
|
||||
"placeholder": "Przykład: SOCKS5://127.0.0.1:9999",
|
||||
"title": "Ustaw proxy"
|
||||
}
|
||||
@ -158,6 +158,14 @@
|
||||
},
|
||||
"remove-upgrade-button": "Usuń przycisk subskrypcji premium",
|
||||
"theme": {
|
||||
"dialog": {
|
||||
"button": {
|
||||
"cancel": "Anuluj",
|
||||
"remove": "Usuń"
|
||||
},
|
||||
"remove-theme": "Czy na pewno chcesz usunąć niestandardowy motyw?",
|
||||
"remove-theme-message": "Spowoduje to usunięcie niestandarowego motywu"
|
||||
},
|
||||
"label": "Motyw",
|
||||
"submenu": {
|
||||
"import-css-file": "Importuj własny plik CSS",
|
||||
@ -199,6 +207,10 @@
|
||||
}
|
||||
},
|
||||
"plugins": {
|
||||
"ad-speedup": {
|
||||
"description": "Wycisza reklamę i przyśpiesza do 16x",
|
||||
"name": "Przyśpieszacz reklam"
|
||||
},
|
||||
"adblocker": {
|
||||
"description": "Blokuj wszystkie reklamy i śledzenie",
|
||||
"menu": {
|
||||
@ -226,7 +238,7 @@
|
||||
"description": "Stosuje efekt świetlny, rzucając delikatne kolory z wideo na tło ekranu",
|
||||
"menu": {
|
||||
"blur-amount": {
|
||||
"label": "Ilość rozmycia",
|
||||
"label": "Siła rozmycia",
|
||||
"submenu": {
|
||||
"pixels": "{{blurAmount}} pikseli"
|
||||
}
|
||||
@ -336,7 +348,7 @@
|
||||
"connected": "Połączono z Discordem",
|
||||
"disconnected": "Odłączono od Discorda"
|
||||
},
|
||||
"description": "Pokaż znajomym, czego słuchasz dzięki Rich Presence",
|
||||
"description": "Pokaż znajomym z Discorda czego słuchasz dzięki Rich Presence",
|
||||
"menu": {
|
||||
"auto-reconnect": "Automatyczne wznawianie połączenia",
|
||||
"clear-activity": "Wyczyść aktywność",
|
||||
@ -402,6 +414,21 @@
|
||||
"description": "Pobiera MP3/ źródło audio bezpośrednio z interfejsu",
|
||||
"menu": {
|
||||
"choose-download-folder": "Wybierz folder pobierania",
|
||||
"download-finish-settings": {
|
||||
"label": "Pobierz po zakończeniu",
|
||||
"prompt": {
|
||||
"last-percent": "Po x procentach",
|
||||
"last-seconds": "Ostatnie x sekund",
|
||||
"title": "Konfiguruj, kiedy pobierać"
|
||||
},
|
||||
"submenu": {
|
||||
"advanced": "Zaawansowane",
|
||||
"enabled": "Włączone",
|
||||
"mode": "Tryb czasowy",
|
||||
"percent": "Procenty",
|
||||
"seconds": "Sekundy"
|
||||
}
|
||||
},
|
||||
"download-playlist": "Pobierz playlistę",
|
||||
"presets": "Predefiniowane ustawienia",
|
||||
"skip-existing": "Pomiń istniejące pliki"
|
||||
@ -641,6 +668,59 @@
|
||||
"description": "Automatycznie pomija fragmenty niebędące muzyką, takie jak wstęp/zakończenie lub fragmenty teledysków, w których utwór nie jest odtwarzany",
|
||||
"name": "Pomiń nieistotne fragmenty"
|
||||
},
|
||||
"synced-lyrics": {
|
||||
"description": "Dodaje zsynchronizowane napisy do utworów używając między innymi LRClib.",
|
||||
"errors": {
|
||||
"fetch": "⚠️ - Wystąpił błąd podczas pobierania tekstu utworu. Spróbuj ponownie później.",
|
||||
"not-found": "⚠️ - Nie znaleziono napisów dla tego utworu."
|
||||
},
|
||||
"menu": {
|
||||
"default-text-string": {
|
||||
"label": "Standardowy znak luki",
|
||||
"tooltip": "Wybierz domyślny znak, który ma być wyświetlany jako pauza między słowami"
|
||||
},
|
||||
"line-effect": {
|
||||
"label": "Efekty linijki",
|
||||
"submenu": {
|
||||
"focus": {
|
||||
"label": "Fokus",
|
||||
"tooltip": "Spraw, aby tylko obecna linijka była biała"
|
||||
},
|
||||
"offset": {
|
||||
"label": "Przesunięcie",
|
||||
"tooltip": "Przesuń w prawo obecną linijkę"
|
||||
},
|
||||
"scale": {
|
||||
"label": "Skala",
|
||||
"tooltip": "Zmień skalę aktualnej linijki"
|
||||
}
|
||||
},
|
||||
"tooltip": "Wybierz efekt, by zastosować go do aktualnej linijki"
|
||||
},
|
||||
"precise-timing": {
|
||||
"label": "Zsynchronizuj tekst utworu do perfekcji",
|
||||
"tooltip": "Wylicz czas wyświetlania następnej linijki co do milisekundy (może mieć mały wpływ na wydajność systemu)"
|
||||
},
|
||||
"show-lyrics-even-if-inexact": {
|
||||
"label": "Pokaż teksty, mimo niezgodności",
|
||||
"tooltip": "Jeżeli nie znaleziono tekstu piosenki z bazy danych, wtyczka spróbuje ponownie przez wyszukanie przybliżonej frazy.\nNależy jednak pamiętać, że następne próby mogą nie być trafne co do oryginału."
|
||||
},
|
||||
"show-time-codes": {
|
||||
"label": "Pokaż znaczniki czasu",
|
||||
"tooltip": "Pokaż znaczniki czasu obok linijek"
|
||||
}
|
||||
},
|
||||
"name": "Napisy zsynchronizowane",
|
||||
"refetch-btn": {
|
||||
"fetching": "Pobieranie napisów...",
|
||||
"normal": "Odśwież napisy"
|
||||
},
|
||||
"warnings": {
|
||||
"duration-mismatch": "⚠️ - Napisy mogą nie być zsynchronizowane z powodu różnicy w czasie trwania utworu.",
|
||||
"inexact": "⚠️ - Tekst utworu może się różnić od oryginału",
|
||||
"instrumental": "⚠️ - To jest utwór instrumentalny"
|
||||
}
|
||||
},
|
||||
"taskbar-mediacontrol": {
|
||||
"description": "Steruj odtwarzaniem z paska zadań systemu Windows",
|
||||
"name": "Kontroler odtwarzania z paska zadań"
|
||||
|
||||
813
src/i18n/resources/pt-BR.json
Normal file
813
src/i18n/resources/pt-BR.json
Normal file
@ -0,0 +1,813 @@
|
||||
{
|
||||
"common": {
|
||||
"console": {
|
||||
"plugins": {
|
||||
"execute-failed": "Falha ao executar plugin {{pluginName}}::{{contextName}}",
|
||||
"executed-at-ms": "Plugin {{pluginName}}::{{contextName}} executado em {{ms}} ms",
|
||||
"initialize-failed": "Falha ao inicializar o plugin \"{{pluginName}}\"",
|
||||
"load-all": "Carregando todos os plugins",
|
||||
"load-failed": "Falha ao carregar o plugin \"{{pluginName}}\"",
|
||||
"loaded": "Plugin \"{{pluginName}}\" carregado",
|
||||
"unload-failed": "Falha ao descarregar o plugin \"{{pluginName}}\"",
|
||||
"unloaded": "Plugin \"{{pluginName}}\" descarregado"
|
||||
}
|
||||
}
|
||||
},
|
||||
"language": {
|
||||
"code": "pt-BR",
|
||||
"local-name": "Português (Brasil)",
|
||||
"name": "Portuguese (Brazil)"
|
||||
},
|
||||
"main": {
|
||||
"console": {
|
||||
"did-finish-load": {
|
||||
"dev-tools": "Carregamento concluído. DevTools aberto"
|
||||
},
|
||||
"i18n": {
|
||||
"loaded": "i18n carregado"
|
||||
},
|
||||
"second-instance": {
|
||||
"receive-command": "Comando recebido pelo protocolo: \"{{command}}\""
|
||||
},
|
||||
"theme": {
|
||||
"css-file-not-found": "Arquivo CSS \"{{cssFile}}\" não existe, ignorando"
|
||||
},
|
||||
"unresponsive": {
|
||||
"details": "Erro de falta de resposta!\n{{error}}"
|
||||
},
|
||||
"when-ready": {
|
||||
"clearing-cache-after-20s": "Limpando cache do aplicativo"
|
||||
},
|
||||
"window": {
|
||||
"tried-to-render-offscreen": "A janela tentou renderizar fora da tela, tamanho da janela={{windowSize}}, tamanho da tela={{displaySize}}, posição={{position}}"
|
||||
}
|
||||
},
|
||||
"dialog": {
|
||||
"hide-menu-enabled": {
|
||||
"detail": "O menu está oculto, use 'Alt' para mostrá-lo (ou 'Esc' ao usar o menu dentro do aplicativo)",
|
||||
"message": "Ocultar menu está ativado",
|
||||
"title": "Ocultar menu ativado"
|
||||
},
|
||||
"need-to-restart": {
|
||||
"buttons": {
|
||||
"later": "Depois",
|
||||
"restart-now": "Reiniciar agora"
|
||||
},
|
||||
"detail": "O plugin \"{{pluginName}}\" requer uma reinicialização para entrar em vigor",
|
||||
"message": "\"{{pluginName}}\" precisa reiniciar",
|
||||
"title": "Necessário reiniciar"
|
||||
},
|
||||
"unresponsive": {
|
||||
"buttons": {
|
||||
"quit": "Fechar",
|
||||
"relaunch": "Reiniciar",
|
||||
"wait": "Aguardar"
|
||||
},
|
||||
"detail": "Lamentamos o inconveniente! Por favor, escolha o que fazer:",
|
||||
"message": "O aplicativo não está respondendo",
|
||||
"title": "Janela não responde"
|
||||
},
|
||||
"update-available": {
|
||||
"buttons": {
|
||||
"disable": "Desativar atualizações",
|
||||
"download": "Baixar",
|
||||
"ok": "OK"
|
||||
},
|
||||
"detail": "Uma versão mais recente está disponível em {{downloadLink}}",
|
||||
"message": "Nova versão disponível",
|
||||
"title": "Atualização disponível"
|
||||
}
|
||||
},
|
||||
"menu": {
|
||||
"about": "Sobre",
|
||||
"navigation": {
|
||||
"label": "Navegação",
|
||||
"submenu": {
|
||||
"copy-current-url": "Copiar URL atual",
|
||||
"go-back": "Voltar",
|
||||
"go-forward": "Avançar",
|
||||
"quit": "Sair",
|
||||
"restart": "Reiniciar aplicativo"
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"label": "Opções",
|
||||
"submenu": {
|
||||
"advanced-options": {
|
||||
"label": "Opções avançadas",
|
||||
"submenu": {
|
||||
"auto-reset-app-cache": "Limpar cache ao iniciar aplicativo",
|
||||
"disable-hardware-acceleration": "Desativar aceleração de hardware",
|
||||
"edit-config-json": "Editar config.json",
|
||||
"override-user-agent": "Substituir User-Agent",
|
||||
"restart-on-config-changes": "Reiniciar ao alterar configurações",
|
||||
"set-proxy": {
|
||||
"label": "Definir proxy",
|
||||
"prompt": {
|
||||
"label": "Digite o endereço do proxy: (deixe em branco para desativar)",
|
||||
"placeholder": "Exemplo: SOCKS5://127.0.0.1:9999",
|
||||
"title": "Definir proxy"
|
||||
}
|
||||
},
|
||||
"toggle-dev-tools": "Alternar DevTools"
|
||||
}
|
||||
},
|
||||
"always-on-top": "Sempre no topo",
|
||||
"auto-update": "Atualização automática",
|
||||
"hide-menu": {
|
||||
"dialog": {
|
||||
"message": "O menu ficará oculto na próxima inicialização, use [Alt] para exibi-lo (ou a tecla de crase [`] se estiver usando o menu do aplicativo)",
|
||||
"title": "Ocultar menu ativado"
|
||||
},
|
||||
"label": "Ocultar menu"
|
||||
},
|
||||
"language": {
|
||||
"dialog": {
|
||||
"message": "O idioma será alterado depois de reiniciar",
|
||||
"title": "Idioma alterado"
|
||||
},
|
||||
"label": "Idioma",
|
||||
"submenu": {
|
||||
"to-help-translate": "Quer ajudar a traduzir? Clique aqui"
|
||||
}
|
||||
},
|
||||
"resume-on-start": "Continuar última música ao iniciar o aplicativo",
|
||||
"single-instance-lock": "Bloqueio de instância única",
|
||||
"start-at-login": "Iniciar com o sistema",
|
||||
"starting-page": {
|
||||
"label": "Página inicial",
|
||||
"unset": "Limpar"
|
||||
},
|
||||
"tray": {
|
||||
"label": "Área de Notificação",
|
||||
"submenu": {
|
||||
"disabled": "Desativado",
|
||||
"enabled-and-hide-app": "Ativado e aplicativo oculto",
|
||||
"enabled-and-show-app": "Ativado e mostrar aplicativo",
|
||||
"play-pause-on-click": "Reproduzir/Pausar ao clicar"
|
||||
}
|
||||
},
|
||||
"visual-tweaks": {
|
||||
"label": "Ajustes visuais",
|
||||
"submenu": {
|
||||
"like-buttons": {
|
||||
"default": "Padrão",
|
||||
"force-show": "Forçar exibir",
|
||||
"hide": "Ocultar",
|
||||
"label": "Botões de 'Curtir'"
|
||||
},
|
||||
"remove-upgrade-button": "Remover botão de atualização",
|
||||
"theme": {
|
||||
"dialog": {
|
||||
"button": {
|
||||
"cancel": "Cancelar",
|
||||
"remove": "Remover"
|
||||
},
|
||||
"remove-theme": "Deseja realmente remover o tema personalizado?",
|
||||
"remove-theme-message": "Isto removerá o tema personalizado"
|
||||
},
|
||||
"label": "Tema",
|
||||
"submenu": {
|
||||
"import-css-file": "Importar arquivo CSS personalizado",
|
||||
"no-theme": "Sem tema"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"plugins": {
|
||||
"enabled": "Ativado",
|
||||
"label": "Plugins",
|
||||
"new": "NOVO"
|
||||
},
|
||||
"view": {
|
||||
"label": "Visualização",
|
||||
"submenu": {
|
||||
"force-reload": "Forçar recarregar",
|
||||
"reload": "Recarregar",
|
||||
"reset-zoom": "Tamanho atual",
|
||||
"toggle-fullscreen": "Alternar tela cheia",
|
||||
"zoom-in": "Ampliar",
|
||||
"zoom-out": "Reduzir"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tray": {
|
||||
"next": "Próximo",
|
||||
"play-pause": "Reproduzir/Pausar",
|
||||
"previous": "Anterior",
|
||||
"quit": "Sair",
|
||||
"restart": "Reiniciar aplicativo",
|
||||
"show": "Mostrar janela",
|
||||
"tooltip": {
|
||||
"default": "YouTube Music",
|
||||
"with-song-info": "YouTube Music: {{artist}} - {{title}}"
|
||||
}
|
||||
}
|
||||
},
|
||||
"plugins": {
|
||||
"ad-speedup": {
|
||||
"description": "Se um anúncio for reproduzido, ele silencia o áudio e define a velocidade de reprodução para 16x",
|
||||
"name": "Acelerador de Anúncios"
|
||||
},
|
||||
"adblocker": {
|
||||
"description": "Bloqueio de todos os anúncios e rastreamentos imediatamente",
|
||||
"menu": {
|
||||
"blocker": "Bloqueador"
|
||||
},
|
||||
"name": "Bloqueador de Anúncios"
|
||||
},
|
||||
"album-actions": {
|
||||
"description": "Adiciona botões Remover Não curtir, Não curtir, Curtir e Remover Curtir para aplicar em todas as músicas em uma lista ou álbum",
|
||||
"name": "Ações do álbum"
|
||||
},
|
||||
"album-color-theme": {
|
||||
"description": "Aplica um tema dinâmico e efeitos visuais com base na paleta de cores do álbum",
|
||||
"menu": {
|
||||
"color-mix-ratio": {
|
||||
"label": "Proporção de mistura de cores",
|
||||
"submenu": {
|
||||
"percent": "{{ratio}}%"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "Tema da cor do álbum"
|
||||
},
|
||||
"ambient-mode": {
|
||||
"description": "Aplica um efeito de iluminação projetando cores suaves do vídeo no fundo da tela",
|
||||
"menu": {
|
||||
"blur-amount": {
|
||||
"label": "Quantidade de desfoque",
|
||||
"submenu": {
|
||||
"pixels": "{{blurAmount}} pixels"
|
||||
}
|
||||
},
|
||||
"buffer": {
|
||||
"label": "Buffer",
|
||||
"submenu": {
|
||||
"buffer": "{{buffer}}"
|
||||
}
|
||||
},
|
||||
"opacity": {
|
||||
"label": "Opacidade",
|
||||
"submenu": {
|
||||
"percent": "{{opacity}}%"
|
||||
}
|
||||
},
|
||||
"quality": {
|
||||
"label": "Qualidade",
|
||||
"submenu": {
|
||||
"pixels": "{{quality}} pixels"
|
||||
}
|
||||
},
|
||||
"size": {
|
||||
"label": "Tamanho",
|
||||
"submenu": {
|
||||
"percent": "{{size}}%"
|
||||
}
|
||||
},
|
||||
"smoothness-transition": {
|
||||
"label": "Transição suave",
|
||||
"submenu": {
|
||||
"during": "Durante {{interpolationTime}} s"
|
||||
}
|
||||
},
|
||||
"use-fullscreen": {
|
||||
"label": "Usando tela cheia"
|
||||
}
|
||||
},
|
||||
"name": "Modo ambiente"
|
||||
},
|
||||
"api-server": {
|
||||
"description": "Adiciona um servidor API para controlar o player",
|
||||
"dialog": {
|
||||
"request": {
|
||||
"buttons": {
|
||||
"allow": "Permitir",
|
||||
"deny": "Negar"
|
||||
},
|
||||
"message": "Permitir que {{ID}} {{origin}} acesse o API?",
|
||||
"title": "Pedido de autorização API"
|
||||
}
|
||||
},
|
||||
"menu": {
|
||||
"auth-strategy": {
|
||||
"label": "Estratégia de autorização",
|
||||
"submenu": {
|
||||
"auth-at-first": {
|
||||
"label": "Autorizar na primeira solicitação"
|
||||
},
|
||||
"none": {
|
||||
"label": "Não autorizar"
|
||||
}
|
||||
}
|
||||
},
|
||||
"hostname": {
|
||||
"label": "Nome do anfitrião"
|
||||
},
|
||||
"port": {
|
||||
"label": "Porta"
|
||||
}
|
||||
},
|
||||
"name": "Servidor API [Beta]",
|
||||
"prompt": {
|
||||
"hostname": {
|
||||
"label": "Entre o nome do host (como 0.0.0.0) para o servidor API:",
|
||||
"title": "Nome do anfitrião"
|
||||
},
|
||||
"port": {
|
||||
"label": "Entre a porta do servidor API:",
|
||||
"title": "Porta"
|
||||
}
|
||||
}
|
||||
},
|
||||
"audio-compressor": {
|
||||
"description": "Aplicar compressão ao áudio (reduz o volume das partes mais altas e aumenta o volume das partes mais baixas)",
|
||||
"name": "Compressor de áudio"
|
||||
},
|
||||
"blur-nav-bar": {
|
||||
"description": "Torna a barra de navegação transparente e desfocada",
|
||||
"name": "Desfocar barra de navegação"
|
||||
},
|
||||
"bypass-age-restrictions": {
|
||||
"description": "Pular a verificação de idade do YouTube",
|
||||
"name": "Ignorar restrições de idade"
|
||||
},
|
||||
"captions-selector": {
|
||||
"description": "Seletor de legendas para faixas de áudio do YouTube Music",
|
||||
"menu": {
|
||||
"autoload": "Selecionar automaticamente a última legenda usada",
|
||||
"disable-captions": "Sem legendas por padrão"
|
||||
},
|
||||
"name": "Seletor de legendas",
|
||||
"prompt": {
|
||||
"selector": {
|
||||
"label": "Idioma atual da legenda: {{language}}",
|
||||
"none": "Nenhum",
|
||||
"title": "Selecionar idioma da legenda"
|
||||
}
|
||||
},
|
||||
"templates": {
|
||||
"title": "Abrir seletor de legendas"
|
||||
}
|
||||
},
|
||||
"compact-sidebar": {
|
||||
"description": "Sempre definir a barra lateral no modo compacto",
|
||||
"name": "Barra lateral compacta"
|
||||
},
|
||||
"crossfade": {
|
||||
"description": "Crossfade entre músicas",
|
||||
"menu": {
|
||||
"advanced": "Avançado"
|
||||
},
|
||||
"name": "Crossfade [Beta]",
|
||||
"prompt": {
|
||||
"options": {
|
||||
"multi-input": {
|
||||
"fade-in-duration": "Duração do fade (ms)",
|
||||
"fade-out-duration": "Duração do fade out (ms)",
|
||||
"fade-scaling": {
|
||||
"label": "Escala do fade",
|
||||
"linear": "Linear",
|
||||
"logarithmic": "Logarítmico"
|
||||
},
|
||||
"seconds-before-end": "Crossfade N segundos antes do fim"
|
||||
},
|
||||
"title": "Opções de crossfade"
|
||||
}
|
||||
}
|
||||
},
|
||||
"disable-autoplay": {
|
||||
"description": "Faz a música começar no modo \"pausado\"",
|
||||
"menu": {
|
||||
"apply-once": "Aplicar somente ao iniciar"
|
||||
},
|
||||
"name": "Desativar reprodução automática"
|
||||
},
|
||||
"discord": {
|
||||
"backend": {
|
||||
"already-connected": "Tentativa de conectar-se com conexão ativa",
|
||||
"connected": "Conectado no Discord",
|
||||
"disconnected": "Desconectado do Discord"
|
||||
},
|
||||
"description": "Mostre aos seus amigos o que você ouve com Rich Presence",
|
||||
"menu": {
|
||||
"auto-reconnect": "Reconexão automática",
|
||||
"clear-activity": "Limpar atividades",
|
||||
"clear-activity-after-timeout": "Limpar atividades após tempo limite",
|
||||
"connected": "Conectado",
|
||||
"disconnected": "Desconectado",
|
||||
"hide-duration-left": "Ocultar duração restante",
|
||||
"hide-github-button": "Ocultar botão do GitHub",
|
||||
"play-on-youtube-music": "Reproduzir no YouTube Music",
|
||||
"set-inactivity-timeout": "Definir tempo limite de inatividade"
|
||||
},
|
||||
"name": "Rich Presence do Discord",
|
||||
"prompt": {
|
||||
"set-inactivity-timeout": {
|
||||
"label": "Digite o tempo de inatividade em segundos:",
|
||||
"title": "Definir tempo limite de inatividade"
|
||||
}
|
||||
}
|
||||
},
|
||||
"downloader": {
|
||||
"backend": {
|
||||
"dialog": {
|
||||
"error": {
|
||||
"buttons": {
|
||||
"ok": "OK"
|
||||
},
|
||||
"message": "Ah! Desculpe, o download falhou…",
|
||||
"title": "Erro no download!"
|
||||
},
|
||||
"start-download-playlist": {
|
||||
"buttons": {
|
||||
"ok": "OK"
|
||||
},
|
||||
"detail": "({{playlistSize}} músicas)",
|
||||
"message": "Baixando lista de reprodução {{playlistTitle}}",
|
||||
"title": "Download iniciado"
|
||||
}
|
||||
},
|
||||
"feedback": {
|
||||
"conversion-progress": "Convertendo: {{percent}}%",
|
||||
"converting": "Convertendo…",
|
||||
"done": "Concluído: {{filePath}}",
|
||||
"download-info": "Baixando {{artist}} - {{title}} [{{videoId}}",
|
||||
"download-progress": "Download: {{percent}}%",
|
||||
"downloading": "Baixando…",
|
||||
"downloading-counter": "Baixando {{current}}/{{total}}…",
|
||||
"downloading-playlist": "Baixando lista de reprodução \"{{playlistTitle}}\" - {{playlistSize}} músicas ({{playlistId}})",
|
||||
"error-while-downloading": "Erro ao baixar \"{{author}} - {{title}}\": {{error}}",
|
||||
"folder-already-exists": "A pasta {{playlistFolder}} já existe",
|
||||
"getting-playlist-info": "Obtendo informações da playlist…",
|
||||
"loading": "Carregando…",
|
||||
"playlist-has-only-one-song": "Playlist possui apenas um item, baixando diretamente",
|
||||
"playlist-id-not-found": "Nenhum playlist ID encontrado",
|
||||
"playlist-is-empty": "Playlist está vazia",
|
||||
"playlist-is-mix-or-private": "Erro ao obter informações da playlist: verifique se não é uma playlist privada ou “”Mixada para você”\n\n{{error}}",
|
||||
"preparing-file": "Preparando arquivo…",
|
||||
"saving": "Salvando…",
|
||||
"trying-to-get-playlist-id": "Tentando obter playlist ID: {{playlistId}}",
|
||||
"video-id-not-found": "Vídeo não encontrado",
|
||||
"writing-id3": "Salvando tags ID3…"
|
||||
}
|
||||
},
|
||||
"description": "Faça download do MP3 / fonte de áudio diretamente da interface",
|
||||
"menu": {
|
||||
"choose-download-folder": "Escolha a pasta de download",
|
||||
"download-finish-settings": {
|
||||
"label": "Baixar ao finalizar",
|
||||
"prompt": {
|
||||
"last-percent": "Após x %",
|
||||
"last-seconds": "Últimos x segundos",
|
||||
"title": "Configurar quando baixar"
|
||||
},
|
||||
"submenu": {
|
||||
"advanced": "Avançado",
|
||||
"enabled": "Ativado",
|
||||
"mode": "Modo de tempo",
|
||||
"percent": "Porcento",
|
||||
"seconds": "Segundos"
|
||||
}
|
||||
},
|
||||
"download-playlist": "Baixar playlist",
|
||||
"presets": "Predefinições",
|
||||
"skip-existing": "Pular arquivos existentes"
|
||||
},
|
||||
"name": "Downloader",
|
||||
"renderer": {
|
||||
"can-not-update-progress": "Não é possível atualizar o progresso"
|
||||
},
|
||||
"templates": {
|
||||
"button": "Baixar"
|
||||
}
|
||||
},
|
||||
"exponential-volume": {
|
||||
"description": "Torna o controle deslizante de volume exponencial para que seja mais fácil selecionar volumes mais baixos.",
|
||||
"name": "Volume Exponencial"
|
||||
},
|
||||
"in-app-menu": {
|
||||
"description": "Dá às barras de menu uma aparência elegante, escura ou com a cor do álbum",
|
||||
"menu": {
|
||||
"hide-dom-window-controls": "Ocultar controles da janela DOM"
|
||||
},
|
||||
"name": "Menu no aplicativo"
|
||||
},
|
||||
"lumiastream": {
|
||||
"description": "Adiciona suporte ao Lumia Stream",
|
||||
"name": "Lumia Stream [Beta]"
|
||||
},
|
||||
"lyrics-genius": {
|
||||
"description": "Adiciona suporte a letras para a maioria das músicas",
|
||||
"menu": {
|
||||
"romanized-lyrics": "Letras Romanizadas"
|
||||
},
|
||||
"name": "Letras Genius",
|
||||
"renderer": {
|
||||
"fetched-lyrics": "Letras buscadas por Genius"
|
||||
}
|
||||
},
|
||||
"music-together": {
|
||||
"description": "Compartilhe uma playlist com outras pessoas. Quando o anfitrião toca uma música, todos os outros ouvirão",
|
||||
"dialog": {
|
||||
"enter-host": "Insira o ID do host"
|
||||
},
|
||||
"internal": {
|
||||
"save": "Salvar",
|
||||
"track-source": "Fonte da Faixa",
|
||||
"unknown-user": "Usuário Desconhecido"
|
||||
},
|
||||
"menu": {
|
||||
"click-to-copy-id": "Copiar ID do host",
|
||||
"close": "Fechar Music Together",
|
||||
"connected-users": "Usuários Conectados",
|
||||
"disconnect": "Desconectar Music Together",
|
||||
"empty-user": "Nenhum usuário conectado",
|
||||
"host": "Anfitrião do Music Together",
|
||||
"join": "Entrar no Music Together",
|
||||
"permission": {
|
||||
"all": "Permitir que os convidados controlem a lista de reprodução e o player",
|
||||
"host-only": "Somente o host pode controlar a lista de reprodução e o player",
|
||||
"playlist": "Permitir que os convidados controlem a lista de reprodução"
|
||||
},
|
||||
"set-permission": "Mudar Permissões de Controle",
|
||||
"status": {
|
||||
"disconnected": "Desconectado",
|
||||
"guest": "Conectado como convidado",
|
||||
"host": "Conectado como Anfitrião"
|
||||
}
|
||||
},
|
||||
"name": "Music Together [Beta]",
|
||||
"toast": {
|
||||
"add-song-failed": "Falha ao adicionar música",
|
||||
"closed": "Music Together fechado",
|
||||
"disconnected": "Music Together desconectado",
|
||||
"host-failed": "Falha ao hospedar o Music Together",
|
||||
"id-copied": "ID do anfitrião copiado para a área de transferência",
|
||||
"id-copy-failed": "Falha ao copiar o ID do anfitrião para a área de transferência",
|
||||
"join-failed": "Falha ao ingressar no Music Together",
|
||||
"joined": "Entrou no Music Together",
|
||||
"permission-changed": "A permissão do Music Together foi alterada para \"{{permission}}\"",
|
||||
"remove-song-failed": "Falha ao remover música",
|
||||
"user-connected": "{{name}} juntou-se ao Music Together",
|
||||
"user-disconnected": "{{name}} saiu do Music Together"
|
||||
}
|
||||
},
|
||||
"navigation": {
|
||||
"description": "Setas de navegação para avançar/retornar diretamente integradas na interface, como no seu navegador favorito",
|
||||
"name": "Navegação"
|
||||
},
|
||||
"no-google-login": {
|
||||
"description": "Remova os botões e links de login do Google da interface",
|
||||
"name": "Sem login do Google"
|
||||
},
|
||||
"notifications": {
|
||||
"description": "Exibir uma notificação quando uma música começar a tocar (notificações interativas estão disponíveis no Windows)",
|
||||
"menu": {
|
||||
"interactive": "Notificações interativas",
|
||||
"interactive-settings": {
|
||||
"label": "Configurações interativas",
|
||||
"submenu": {
|
||||
"hide-button-text": "Ocultar texto do botão",
|
||||
"refresh-on-play-pause": "Atualizar ao Reproduzir/Pausar",
|
||||
"tray-controls": "Abrir/Fechar ao clicar na área de notificação"
|
||||
}
|
||||
},
|
||||
"priority": "Prioridade da notificação",
|
||||
"toast-style": "Estilo de alerta",
|
||||
"unpause-notification": "Mostrar notificação ao despausar"
|
||||
},
|
||||
"name": "Notificações"
|
||||
},
|
||||
"picture-in-picture": {
|
||||
"description": "Permite alternar o aplicativo para o modo picture-in-picture",
|
||||
"menu": {
|
||||
"always-on-top": "Sempre no topo",
|
||||
"hotkey": {
|
||||
"label": "Tecla de atalho",
|
||||
"prompt": {
|
||||
"keybind-options": {
|
||||
"hotkey": "Tecla de atalho"
|
||||
},
|
||||
"label": "Escolha uma tecla de atalho para alternar entre picture-in-picture",
|
||||
"title": "Atalho do picture-in-picture"
|
||||
}
|
||||
},
|
||||
"save-window-position": "Salvar posição da janela",
|
||||
"save-window-size": "Salvar tamanho da janela",
|
||||
"use-native-pip": "Usar PiP nativo do navegador"
|
||||
},
|
||||
"name": "Picture-in-picture",
|
||||
"templates": {
|
||||
"button": "Picture-in-picture"
|
||||
}
|
||||
},
|
||||
"playback-speed": {
|
||||
"description": "Ouça rápido, ouça devagar! Adiciona um controle deslizante que controla a velocidade da música",
|
||||
"name": "Velocidade de reprodução",
|
||||
"templates": {
|
||||
"button": "Velocidade"
|
||||
}
|
||||
},
|
||||
"precise-volume": {
|
||||
"description": "Controle o volume com precisão usando a roda do mouse/teclas de atalho, com um HUD personalizado e etapas de volume personalizáveis",
|
||||
"menu": {
|
||||
"arrows-shortcuts": "Controles de teclas de seta locais",
|
||||
"custom-volume-steps": "Definir etapas de volume personalizadas",
|
||||
"global-shortcuts": "Teclas de atalho globais"
|
||||
},
|
||||
"name": "Volume preciso",
|
||||
"prompt": {
|
||||
"global-shortcuts": {
|
||||
"keybind-options": {
|
||||
"decrease": "Diminuir volume",
|
||||
"increase": "Aumentar volume"
|
||||
},
|
||||
"label": "Selecione as teclas de atalho global do volume:",
|
||||
"title": "Teclas de atalho global de volume"
|
||||
},
|
||||
"volume-steps": {
|
||||
"label": "Escolha as etapas de aumento/diminuição do volume",
|
||||
"title": "Fases de volume"
|
||||
}
|
||||
}
|
||||
},
|
||||
"quality-changer": {
|
||||
"backend": {
|
||||
"dialog": {
|
||||
"quality-changer": {
|
||||
"detail": "Qualidade atual: {{quality}}",
|
||||
"message": "Escolher qualidade do vídeo:",
|
||||
"title": "Escolher qualidade do vídeo"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": "Permite alterar a qualidade do vídeo com um botão na sobreposição de vídeo",
|
||||
"name": "Alterador de qualidade do vídeo"
|
||||
},
|
||||
"scrobbler": {
|
||||
"description": "Adicionar suporte para scrobbling (last.fm, Listenbrainz, etc.)",
|
||||
"dialog": {
|
||||
"lastfm": {
|
||||
"auth-failed": {
|
||||
"message": "Falha ao autenticar com Last.fm\nOcultar o pop-up até a próxima reinicialização.",
|
||||
"title": "Falha na autenticação"
|
||||
}
|
||||
}
|
||||
},
|
||||
"menu": {
|
||||
"lastfm": {
|
||||
"api-settings": "Configurações da API do Last.fm"
|
||||
},
|
||||
"listenbrainz": {
|
||||
"token": "Insira o token de usuário ListenBrainz"
|
||||
},
|
||||
"scrobble-other-media": "Scrobble outras mídias"
|
||||
},
|
||||
"name": "Scrobbler",
|
||||
"prompt": {
|
||||
"lastfm": {
|
||||
"api-key": "Chave de API do Last.fm",
|
||||
"api-secret": "Chave secreta da API do Last.fm"
|
||||
},
|
||||
"listenbrainz": {
|
||||
"token": {
|
||||
"label": "Insira seu token de usuário do ListenBrainz:",
|
||||
"title": "ListenBrainz token"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"shortcuts": {
|
||||
"description": "Permite definir teclas de atalho globais para reprodução (reproduzir/pausar/próximo/anterior) e desativar o OSD de mídia substituindo as teclas de mídia, ativando Ctrl/CMD + F para pesquisar, ativando o suporte Linux MPRIS para teclas de mídia e teclas de atalho personalizadas para usuários avançados",
|
||||
"menu": {
|
||||
"override-media-keys": "Substituir chaves de multimédia",
|
||||
"set-keybinds": "Definir controles globais de música"
|
||||
},
|
||||
"name": "Atalhos (& MPRIS)",
|
||||
"prompt": {
|
||||
"keybind": {
|
||||
"keybind-options": {
|
||||
"next": "Próximo",
|
||||
"play-pause": "Reproduzir / Pausar",
|
||||
"previous": "Anterior"
|
||||
},
|
||||
"label": "Escolha atalhos de teclado globais para controle de músicas:",
|
||||
"title": "Atalhos de teclado global"
|
||||
}
|
||||
}
|
||||
},
|
||||
"skip-disliked-songs": {
|
||||
"description": "Ignora músicas marcadas com \"não gostei\"",
|
||||
"name": "Pular músicas marcadas com \"não gostei\""
|
||||
},
|
||||
"skip-silences": {
|
||||
"description": "Pular automaticamente seções de silêncio em músicas",
|
||||
"name": "Pular silêncios"
|
||||
},
|
||||
"sponsorblock": {
|
||||
"description": "Pula automaticamente partes não musicais, como introdução/finalização ou partes de videoclipes onde a música não está tocando",
|
||||
"name": "SponsorBlock [Bloquear patrocínios]"
|
||||
},
|
||||
"synced-lyrics": {
|
||||
"description": "Fornece letras sincronizadas para músicas, usando provedores como LRClib.",
|
||||
"errors": {
|
||||
"fetch": "⚠️ - Ocorreu um erro ao buscar a letra. Tente novamente mais tarde.",
|
||||
"not-found": "⚠️ - Nenhuma letra encontrada para esta música."
|
||||
},
|
||||
"menu": {
|
||||
"default-text-string": {
|
||||
"label": "Caractere padrão entre letras",
|
||||
"tooltip": "Escolha o caractere padrão a ser usado para o intervalo entre as letras"
|
||||
},
|
||||
"line-effect": {
|
||||
"label": "Efeito de linha",
|
||||
"submenu": {
|
||||
"focus": {
|
||||
"label": "Foco",
|
||||
"tooltip": "Deixe apenas a linha atual branca"
|
||||
},
|
||||
"offset": {
|
||||
"label": "Deslocar",
|
||||
"tooltip": "Deslocamento à direita da linha atual"
|
||||
},
|
||||
"scale": {
|
||||
"label": "Aumentar",
|
||||
"tooltip": "Aumentar a linha atual"
|
||||
}
|
||||
},
|
||||
"tooltip": "Escolha o efeito a ser aplicado à linha atual"
|
||||
},
|
||||
"precise-timing": {
|
||||
"label": "Deixa as letras perfeitamente sincronizadas",
|
||||
"tooltip": "Calcular até o milissegundo a exibição da próxima linha (pode ter um pequeno impacto no desempenho)"
|
||||
},
|
||||
"show-lyrics-even-if-inexact": {
|
||||
"label": "Mostrar letras mesmo que não sejam exatas",
|
||||
"tooltip": "Se a música não for encontrada, o plugin tenta novamente com uma consulta de pesquisa diferente.\nO resultado da segunda tentativa pode não ser exato."
|
||||
},
|
||||
"show-time-codes": {
|
||||
"label": "Mostrar códigos de tempo",
|
||||
"tooltip": "Mostrar os códigos de tempo ao lado das letras"
|
||||
}
|
||||
},
|
||||
"name": "Letras sincronizadas",
|
||||
"refetch-btn": {
|
||||
"fetching": "Buscando...",
|
||||
"normal": "Buscar letras novamente"
|
||||
},
|
||||
"warnings": {
|
||||
"duration-mismatch": "⚠️ - A letra pode estar dessincronizada devido a uma incompatibilidade de duração.",
|
||||
"inexact": "⚠️ - A letra desta música pode não ser exata",
|
||||
"instrumental": "⚠️ - Esta é uma música instrumental"
|
||||
}
|
||||
},
|
||||
"taskbar-mediacontrol": {
|
||||
"description": "Controle a reprodução na barra de tarefas do Windows",
|
||||
"name": "Controle de mídia da barra de tarefas"
|
||||
},
|
||||
"touchbar": {
|
||||
"description": "Adiciona um widget TouchBar para usuários do macOS",
|
||||
"name": "TouchBar"
|
||||
},
|
||||
"tuna-obs": {
|
||||
"description": "Integração com o plugin Tuna do OBS",
|
||||
"name": "Tuna OBS"
|
||||
},
|
||||
"video-toggle": {
|
||||
"description": "Adiciona um botão para alternar entre o modo Vídeo/Música. Também é possível remover opcionalmente toda a aba de vídeo",
|
||||
"menu": {
|
||||
"align": {
|
||||
"label": "Alinhamento",
|
||||
"submenu": {
|
||||
"left": "Esquerda",
|
||||
"middle": "Meio",
|
||||
"right": "Direita"
|
||||
}
|
||||
},
|
||||
"force-hide": "Forçar remoção da aba de vídeo",
|
||||
"mode": {
|
||||
"label": "Modo",
|
||||
"submenu": {
|
||||
"custom": "Alternância personalizada",
|
||||
"disabled": "Desativado",
|
||||
"native": "Alternância nativa"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "Alternar vídeo",
|
||||
"templates": {
|
||||
"button": "Música"
|
||||
}
|
||||
},
|
||||
"visualizer": {
|
||||
"description": "Adiciona um visualizador ao player",
|
||||
"menu": {
|
||||
"visualizer-type": "Tipo de visualizador"
|
||||
},
|
||||
"name": "Visualizador"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -158,6 +158,14 @@
|
||||
},
|
||||
"remove-upgrade-button": "Remover botão upgrade",
|
||||
"theme": {
|
||||
"dialog": {
|
||||
"button": {
|
||||
"cancel": "Cancelar",
|
||||
"remove": "Remover"
|
||||
},
|
||||
"remove-theme": "Você tem certeza que quer remover o tema customizado?",
|
||||
"remove-theme-message": "Isso removerá o tema customizado"
|
||||
},
|
||||
"label": "Tema",
|
||||
"submenu": {
|
||||
"import-css-file": "Importar arquivo CSS personalizado",
|
||||
@ -199,6 +207,10 @@
|
||||
}
|
||||
},
|
||||
"plugins": {
|
||||
"ad-speedup": {
|
||||
"description": "Se um anúncio for reproduzido, ele será silenciado o áudio e será definido a velocidade de reprodução para 16x",
|
||||
"name": "Acelerar os anúncios"
|
||||
},
|
||||
"adblocker": {
|
||||
"description": "Bloquear todos os anúncios e rastreamento automaticamente",
|
||||
"menu": {
|
||||
@ -214,9 +226,9 @@
|
||||
"description": "Aplica um tema dinâmico e efeitos visuais com base na paleta de cores do álbum",
|
||||
"menu": {
|
||||
"color-mix-ratio": {
|
||||
"label": "Rácio de mistura das cores",
|
||||
"label": "Relação de mistura de cores",
|
||||
"submenu": {
|
||||
"percent": "Proporção"
|
||||
"percent": "{{ratio}}%"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -402,6 +414,21 @@
|
||||
"description": "Baixa MP3 / fonte de áudio diretamente da interface",
|
||||
"menu": {
|
||||
"choose-download-folder": "Escolha a pasta de download",
|
||||
"download-finish-settings": {
|
||||
"label": "Baixar ao terminar",
|
||||
"prompt": {
|
||||
"last-percent": "Depois de x por cento",
|
||||
"last-seconds": "Últimos x segundos",
|
||||
"title": "Configurar quando baixar"
|
||||
},
|
||||
"submenu": {
|
||||
"advanced": "Avançado",
|
||||
"enabled": "Ativado",
|
||||
"mode": "Modo de tempo",
|
||||
"percent": "Porcentagem",
|
||||
"seconds": "Segundos"
|
||||
}
|
||||
},
|
||||
"download-playlist": "Baixar lista de reprodução",
|
||||
"presets": "Predefinições",
|
||||
"skip-existing": "Ignorar arquivos existentes"
|
||||
@ -474,15 +501,15 @@
|
||||
"add-song-failed": "Falha ao adicionar canção",
|
||||
"closed": "Música Juntos encerrado",
|
||||
"disconnected": "Música Juntos foi desconectado",
|
||||
"host-failed": "Falha ao hospedar o Música Juntos",
|
||||
"host-failed": "Falha ao hospedar o Music Together",
|
||||
"id-copied": "ID de anfitrião copiado para a área de transferência",
|
||||
"id-copy-failed": "Falha ao copiar o ID de anfitrião para a área de transferência",
|
||||
"join-failed": "Falha ao entrar em Música Juntos",
|
||||
"joined": "Entrou em Música Juntos",
|
||||
"permission-changed": "A permissão do Música Juntos foi alterada para \"{{permission}}\"",
|
||||
"join-failed": "Falha ao entrar em Music Together",
|
||||
"joined": "Entrou em Music Together",
|
||||
"permission-changed": "A permissão do Music Together foi alterada para \"{{permission}}\"",
|
||||
"remove-song-failed": "Falha ao remover música",
|
||||
"user-connected": "{{name}} entrou em Música Juntos",
|
||||
"user-disconnected": "{{name}} saiu do Música Juntos"
|
||||
"user-connected": "{{name}} entrou em Music Together",
|
||||
"user-disconnected": "{{name}} saiu do Music Together"
|
||||
}
|
||||
},
|
||||
"navigation": {
|
||||
@ -641,6 +668,59 @@
|
||||
"description": "Ignora automaticamente partes não musicais, como introdução/final ou partes de videoclipes onde a música não está tocando",
|
||||
"name": "SponsorBlock (bloqueador de patrocínios)"
|
||||
},
|
||||
"synced-lyrics": {
|
||||
"description": "Fornece letras sincronizadas de músicas, utilizando fornecedores como o LRClib.",
|
||||
"errors": {
|
||||
"fetch": "⚠️ - Ocorreu um erro ao obter as letras da música. Por favor, tenta novamente mais tarde.",
|
||||
"not-found": "⚠️ - Não foram encontradas letras para esta música."
|
||||
},
|
||||
"menu": {
|
||||
"default-text-string": {
|
||||
"label": "Caractere padrão entre as letras",
|
||||
"tooltip": "Escolha o caractere padrão para usar no espaço entre as letras"
|
||||
},
|
||||
"line-effect": {
|
||||
"label": "Efeito de linha",
|
||||
"submenu": {
|
||||
"focus": {
|
||||
"label": "Foco",
|
||||
"tooltip": "Deixe apenas a linha atual branca"
|
||||
},
|
||||
"offset": {
|
||||
"label": "Deslocamento",
|
||||
"tooltip": "Desloque a linha atual para a direita"
|
||||
},
|
||||
"scale": {
|
||||
"label": "Escala",
|
||||
"tooltip": "Escalar a linha atual"
|
||||
}
|
||||
},
|
||||
"tooltip": "Escolha o efeito a ser aplicado à linha atual"
|
||||
},
|
||||
"precise-timing": {
|
||||
"label": "Sincronize perfeitamente as letras",
|
||||
"tooltip": "Calcule até o milissegundo a exibição da próxima linha (pode ter um pequeno impacto no desempenho)"
|
||||
},
|
||||
"show-lyrics-even-if-inexact": {
|
||||
"label": "Mostrar letras mesmo que imprecisas",
|
||||
"tooltip": "Se a música não for encontrada, o plugin tenta novamente com uma consulta de pesquisa diferente.\nO resultado da segunda tentativa pode não ser exato."
|
||||
},
|
||||
"show-time-codes": {
|
||||
"label": "Mostrar códigos de tempo",
|
||||
"tooltip": "Mostrar os códigos de tempo ao lado das letras"
|
||||
}
|
||||
},
|
||||
"name": "Letras Sincronizadas",
|
||||
"refetch-btn": {
|
||||
"fetching": "Buscando...",
|
||||
"normal": "Buscar as letras novamente"
|
||||
},
|
||||
"warnings": {
|
||||
"duration-mismatch": "⚠️ - As letras da música pode estar dessincronizada devido a um erro de duração.",
|
||||
"inexact": "⚠️ - As letras desta música podem não ser exactas.",
|
||||
"instrumental": "⚠️ - Esta é uma música instrumental."
|
||||
}
|
||||
},
|
||||
"taskbar-mediacontrol": {
|
||||
"description": "Controle a reprodução na barra de tarefas do Windows",
|
||||
"name": "Controle de mídia da barra de tarefas"
|
||||
|
||||
@ -128,12 +128,12 @@
|
||||
},
|
||||
"label": "Limba",
|
||||
"submenu": {
|
||||
"to-help-translate": "Vrei sa ajuti la traducere? Apasa aici"
|
||||
"to-help-translate": "Vrei să ajuți la traducere? Apasă aici"
|
||||
}
|
||||
},
|
||||
"resume-on-start": "Continua ultimul cantec ascultat cand porneste aplicatia",
|
||||
"single-instance-lock": "Oprirea deschiderii mai multor instante",
|
||||
"start-at-login": "Incepe la autentificare",
|
||||
"resume-on-start": "Continuă ultimul cântec ascultat când pornește aplicația",
|
||||
"single-instance-lock": "Blocare cu o singură instanță",
|
||||
"start-at-login": "Începe de la autentificare",
|
||||
"starting-page": {
|
||||
"label": "Pagina de pornire",
|
||||
"unset": "Deselectat"
|
||||
@ -142,22 +142,30 @@
|
||||
"label": "Tray",
|
||||
"submenu": {
|
||||
"disabled": "Dezactivat",
|
||||
"enabled-and-hide-app": "Activeaza si ascunde fereastra aplicatiei",
|
||||
"enabled-and-show-app": "Activeaza si arata fereastra aplicatiei",
|
||||
"enabled-and-hide-app": "Activează și ascunde fereastra aplicației",
|
||||
"enabled-and-show-app": "Activează și arata fereastra aplicației",
|
||||
"play-pause-on-click": "Start/Pauza la click"
|
||||
}
|
||||
},
|
||||
"visual-tweaks": {
|
||||
"label": "Optimizari vizuale",
|
||||
"label": "Modificări Vizuale",
|
||||
"submenu": {
|
||||
"like-buttons": {
|
||||
"default": "Default",
|
||||
"force-show": "Forteaza randarea",
|
||||
"force-show": "Forțează randarea",
|
||||
"hide": "Ascunde",
|
||||
"label": "Butoane de like"
|
||||
},
|
||||
"remove-upgrade-button": "Elimina butonul de upgrade",
|
||||
"theme": {
|
||||
"dialog": {
|
||||
"button": {
|
||||
"cancel": "Anulează",
|
||||
"remove": "Elimină"
|
||||
},
|
||||
"remove-theme": "Ești sigur că vrei să elimini tema personalizata?",
|
||||
"remove-theme-message": "Acesta va elimina tema personalizata"
|
||||
},
|
||||
"label": "Tema",
|
||||
"submenu": {
|
||||
"import-css-file": "Importa fisiere CSS proprii",
|
||||
|
||||
@ -158,6 +158,14 @@
|
||||
},
|
||||
"remove-upgrade-button": "Убрать кнопку Youtube Premium",
|
||||
"theme": {
|
||||
"dialog": {
|
||||
"button": {
|
||||
"cancel": "Отмена",
|
||||
"remove": "Убрать"
|
||||
},
|
||||
"remove-theme": "Вы уверены, что хотите убрать пользовательскую тему?",
|
||||
"remove-theme-message": "Это уберёт пользовательскую тему"
|
||||
},
|
||||
"label": "Тема",
|
||||
"submenu": {
|
||||
"import-css-file": "Импортировать кастомный CSS файл",
|
||||
@ -199,6 +207,10 @@
|
||||
}
|
||||
},
|
||||
"plugins": {
|
||||
"ad-speedup": {
|
||||
"description": "Если воспроизводится реклама, аудио заглушается и скорость воспроизведения устанавливается на 16х",
|
||||
"name": "Ускоренная перемотка"
|
||||
},
|
||||
"adblocker": {
|
||||
"description": "Блокируйте всю рекламу и трекинг сразу после установки",
|
||||
"menu": {
|
||||
@ -267,9 +279,52 @@
|
||||
},
|
||||
"name": "Режим Ambient"
|
||||
},
|
||||
"api-server": {
|
||||
"description": "Добавляет API сервер для контроля за плеером",
|
||||
"dialog": {
|
||||
"request": {
|
||||
"buttons": {
|
||||
"allow": "Разрешить",
|
||||
"deny": "Отказать"
|
||||
},
|
||||
"message": "Разрешить {{ID}} ({{origin}}) доступ к API?",
|
||||
"title": "Запрос на авторизацию в API"
|
||||
}
|
||||
},
|
||||
"menu": {
|
||||
"auth-strategy": {
|
||||
"label": "Способ авторизации",
|
||||
"submenu": {
|
||||
"auth-at-first": {
|
||||
"label": "Авторизация при первом запросе"
|
||||
},
|
||||
"none": {
|
||||
"label": "Без авторизации"
|
||||
}
|
||||
}
|
||||
},
|
||||
"hostname": {
|
||||
"label": "Имя хоста"
|
||||
},
|
||||
"port": {
|
||||
"label": "Порт"
|
||||
}
|
||||
},
|
||||
"name": "API Сервер [БЕТА]",
|
||||
"prompt": {
|
||||
"hostname": {
|
||||
"label": "Введите имя хоста (на подобии 0.0.0.0) для API сервера:",
|
||||
"title": "Имя хоста"
|
||||
},
|
||||
"port": {
|
||||
"label": "Введите порт для API сервера:",
|
||||
"title": "Порт"
|
||||
}
|
||||
}
|
||||
},
|
||||
"audio-compressor": {
|
||||
"description": "Применяет компрессию к аудио (уменьшает громкость самых громких частей сигнала и повышает громкость самых тихих частей)",
|
||||
"name": "Аудио компрессор"
|
||||
"name": "Нормализация аудио"
|
||||
},
|
||||
"blur-nav-bar": {
|
||||
"description": "Делает панель навигации прозрачной и размытой",
|
||||
@ -402,6 +457,21 @@
|
||||
"description": "Скачивать MP3 / исходное аудио напрямую из интерфейса",
|
||||
"menu": {
|
||||
"choose-download-folder": "Выберите папку для загрузок",
|
||||
"download-finish-settings": {
|
||||
"label": "Скачать по завершении",
|
||||
"prompt": {
|
||||
"last-percent": "После х процентов",
|
||||
"last-seconds": "Осталось x сек",
|
||||
"title": "Условия скачивания"
|
||||
},
|
||||
"submenu": {
|
||||
"advanced": "Расширенные настройки",
|
||||
"enabled": "Включено",
|
||||
"mode": "Врмеменной режим",
|
||||
"percent": "Проценты",
|
||||
"seconds": "Секунды"
|
||||
}
|
||||
},
|
||||
"download-playlist": "Скачать плейлист",
|
||||
"presets": "Пресеты",
|
||||
"skip-existing": "Пропускать уже существующие файлы"
|
||||
@ -641,6 +711,58 @@
|
||||
"description": "Автоматически пропускает не музыкальные фрагменты, например интро/аутро или фрагменты музыкальных клипов, в которых песня не звучит (тишина)",
|
||||
"name": "SponsorBlock"
|
||||
},
|
||||
"synced-lyrics": {
|
||||
"description": "Предоставляет синхронизированные слова для песен из таких источников, как LRClib.",
|
||||
"errors": {
|
||||
"fetch": "⚠️ - Возникла ошибка во время получения слов. Повторите попытку позже.",
|
||||
"not-found": "⚠️ - Для этой песни не найдено слов."
|
||||
},
|
||||
"menu": {
|
||||
"default-text-string": {
|
||||
"label": "Стандартный символ между словами",
|
||||
"tooltip": "Выберите стандартный символ для заполнения пространства между словами"
|
||||
},
|
||||
"line-effect": {
|
||||
"label": "Эффект строки",
|
||||
"submenu": {
|
||||
"focus": {
|
||||
"label": "Фокусировка",
|
||||
"tooltip": "Делает только текущую строку белой"
|
||||
},
|
||||
"offset": {
|
||||
"label": "Сдвиг",
|
||||
"tooltip": "Сдвигает текущую строку вправо"
|
||||
},
|
||||
"scale": {
|
||||
"label": "Увеличение",
|
||||
"tooltip": "Увеличивает текущую строку"
|
||||
}
|
||||
},
|
||||
"tooltip": "Выберите эффект применяемый к текущей строке"
|
||||
},
|
||||
"precise-timing": {
|
||||
"label": "Идеально синхронизировать слова",
|
||||
"tooltip": "До миллисекунды рассчитывает отображение следующей строки(может оказать небольшое влияние на производительность)"
|
||||
},
|
||||
"show-lyrics-even-if-inexact": {
|
||||
"label": "Показывать слова, даже если неточные",
|
||||
"tooltip": "Если песня не найдена, плагин попытается снова с другим поисковым запросом.\nСо второй попытки результат может быть неточным."
|
||||
},
|
||||
"show-time-codes": {
|
||||
"label": "Показывать временные метки",
|
||||
"tooltip": "Показывает временные метки рядом со словами"
|
||||
}
|
||||
},
|
||||
"refetch-btn": {
|
||||
"fetching": "Сбор данных...",
|
||||
"normal": "Обновить слова"
|
||||
},
|
||||
"warnings": {
|
||||
"duration-mismatch": "⚠️ - Слова могут быть неточно синхронизированы из-за несовпадения длины трека.",
|
||||
"inexact": "⚠️ - Слова для этой песни могут быть неточными",
|
||||
"instrumental": "⚠️ - Это инструментальная музыка"
|
||||
}
|
||||
},
|
||||
"taskbar-mediacontrol": {
|
||||
"description": "Управляйте воспроизведением с панели задач Windows",
|
||||
"name": "Управление мультимедиа на панели задач"
|
||||
@ -684,7 +806,7 @@
|
||||
"menu": {
|
||||
"visualizer-type": "Вид визуализации"
|
||||
},
|
||||
"name": "Визуалайзер"
|
||||
"name": "Визуализатор"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
42
src/i18n/resources/si.json
Normal file
42
src/i18n/resources/si.json
Normal file
@ -0,0 +1,42 @@
|
||||
{
|
||||
"common": {
|
||||
"console": {
|
||||
"plugins": {
|
||||
"execute-failed": "ප්ලගිනය ක්රියාත්මක කිරීමට අසමත් විය {{pluginName}}::{{contextName}}",
|
||||
"executed-at-ms": "ප්ලගිනය {{pluginName}}::{{contextName}} {{ms}}ms හිදී ක්රියාත්මක කරන ලදී",
|
||||
"initialize-failed": "\"{{pluginName}}\" ප්ලගිනය ආරම්භ කිරීමට අසමත් විය",
|
||||
"load-all": "සියලුම ප්ලගින පූරණය කරමින්",
|
||||
"load-failed": "\"{{pluginName}}\" ප්ලගිනය පූරණය කිරීමට අසමත් විය",
|
||||
"loaded": "ප්ලගිනය \"{{pluginName}}\" පූරණය කරන ලදී",
|
||||
"unload-failed": "ප්ලගින් \"{{pluginName}}\" ගලවන්න අසාර්ථක වුන",
|
||||
"unloaded": "ප්ලගින් \"{{pluginName}}\" ගැලෙව්වා"
|
||||
}
|
||||
}
|
||||
},
|
||||
"language": {
|
||||
"code": "si",
|
||||
"local-name": "සිංහල",
|
||||
"name": "Sinhala"
|
||||
},
|
||||
"main": {
|
||||
"console": {
|
||||
"did-finish-load": {
|
||||
"dev-tools": "පූරණය සම්පුර්නි. ඩෙව්ටූල්ස් ඇරිලා"
|
||||
},
|
||||
"i18n": {
|
||||
"loaded": "i18n පූරණය කර ඇත"
|
||||
},
|
||||
"second-instance": {
|
||||
"receive-command": "ප්රෝටෝකාල් හරහා විධානය ලැබුණි: \"{{command}}\""
|
||||
},
|
||||
"theme": {
|
||||
"css-file-not-found": "සීඑස්එස් ගොනුව \"{{cssFile}}\" නොපවතී, නොසලකා හැරීම"
|
||||
}
|
||||
},
|
||||
"dialog": {
|
||||
"need-to-restart": {
|
||||
"title": "නැවත ආරම්භ කිරීම අවශ්යයි"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
334
src/i18n/resources/sl.json
Normal file
334
src/i18n/resources/sl.json
Normal file
@ -0,0 +1,334 @@
|
||||
{
|
||||
"common": {
|
||||
"console": {
|
||||
"plugins": {
|
||||
"execute-failed": "Napaka pri inicilizaciji dodatka {{pluginName}}::{{contextName}}",
|
||||
"executed-at-ms": "Dodatek {{pluginName}}::{{contextName}} izvešen pri {{ms}}ms",
|
||||
"initialize-failed": "Napaka pri inicilizaciji dodatka \"{{pluginName}}\"",
|
||||
"load-all": "Nalaganje dodatkov",
|
||||
"load-failed": "Napaka pri nalaganju dodatka \"{{pluginName}}\"",
|
||||
"loaded": "Dodatek \"{{pluginName}}\" naložen",
|
||||
"unload-failed": "Napaka pri raztvorbi dodatka \"{{pluginName}}\"",
|
||||
"unloaded": "Dodatek \"{{pluginName}}\" raztvorjen"
|
||||
}
|
||||
}
|
||||
},
|
||||
"language": {
|
||||
"code": "sl",
|
||||
"local-name": "Slovenščina",
|
||||
"name": "Slovenian"
|
||||
},
|
||||
"main": {
|
||||
"console": {
|
||||
"did-finish-load": {
|
||||
"dev-tools": "Nalaganje končano. DevTools odprt"
|
||||
},
|
||||
"i18n": {
|
||||
"loaded": "i18n naložen"
|
||||
},
|
||||
"second-instance": {
|
||||
"receive-command": "Prejel ukaz preko protokola: \"{{command}}\""
|
||||
},
|
||||
"theme": {
|
||||
"css-file-not-found": "CSS datoteka \"{{cssFile}}\" ne obstaja, ignoriram"
|
||||
},
|
||||
"unresponsive": {
|
||||
"details": "Neodzivna napaka!\n{{error}}"
|
||||
},
|
||||
"when-ready": {
|
||||
"clearing-cache-after-20s": "Čiščenje predpolnilnika"
|
||||
},
|
||||
"window": {
|
||||
"tried-to-render-offscreen": "Okno se je poskusilo prikazati izven ekrana, windowSize={{windowSize}}, displaySize={{displaySize}}, position={{position}}"
|
||||
}
|
||||
},
|
||||
"dialog": {
|
||||
"hide-menu-enabled": {
|
||||
"detail": "Meni je skrit, pritisni 'Alt' za odpiranje (ali 'Escape' če uporabljaš In-App Meni)",
|
||||
"message": "Skriti meni je prižgan",
|
||||
"title": "Skrij meni uklopljen"
|
||||
},
|
||||
"need-to-restart": {
|
||||
"buttons": {
|
||||
"restart-now": "Ponovno zaženi zdaj"
|
||||
},
|
||||
"detail": "\"{{pluginName}}\" dodatek potrebuje ponovni zagon za začetek",
|
||||
"message": "\"{{pluginName}}\" je potrebno ponovno zagnati",
|
||||
"title": "Potreben je ponovni zagon"
|
||||
},
|
||||
"unresponsive": {
|
||||
"buttons": {
|
||||
"quit": "Zapri",
|
||||
"relaunch": "Ponovno zaženi",
|
||||
"wait": "Počakaj"
|
||||
},
|
||||
"detail": "Opravičujemo se za neprijetnost! Prosim odločite se kaj narediti:",
|
||||
"message": "Aplikacija se ne odziva",
|
||||
"title": "Okno se ne odziva"
|
||||
},
|
||||
"update-available": {
|
||||
"buttons": {
|
||||
"disable": "Izklopi posodobitve",
|
||||
"download": "Prenesi",
|
||||
"ok": "OK"
|
||||
},
|
||||
"detail": "Nova verzija je na voljo, lahko jo naložiš na {{downloadLink}}",
|
||||
"message": "Nova verzija je na voljo",
|
||||
"title": "Posodobitev je na voljo"
|
||||
}
|
||||
},
|
||||
"menu": {
|
||||
"about": "O aplikaciji",
|
||||
"navigation": {
|
||||
"label": "Navigacija",
|
||||
"submenu": {
|
||||
"copy-current-url": "Kopiraj trenuten URL",
|
||||
"go-back": "Nazaj",
|
||||
"go-forward": "Naprej",
|
||||
"quit": "Izhod",
|
||||
"restart": "Ponovni zagon"
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"label": "Nastavitve",
|
||||
"submenu": {
|
||||
"advanced-options": {
|
||||
"label": "Dodatne nastavitve",
|
||||
"submenu": {
|
||||
"auto-reset-app-cache": "Resetiraj predpolnilnik aplikacije ob zagonu",
|
||||
"disable-hardware-acceleration": "Izklopi strojno pospeševanje",
|
||||
"edit-config-json": "Spremeni config.json",
|
||||
"override-user-agent": "Prepiši User-Agent",
|
||||
"restart-on-config-changes": "Ponovni zagon ko se spremeni config",
|
||||
"set-proxy": {
|
||||
"label": "Nastavi proxy",
|
||||
"prompt": {
|
||||
"label": "Napiši naslov Proxy: (pusti prazno, da izklopiš)",
|
||||
"placeholder": "Primer: SOCKS5://127.0.0.1:9999",
|
||||
"title": "Nastavi Proxy"
|
||||
}
|
||||
},
|
||||
"toggle-dev-tools": "Vklopi DevTools"
|
||||
}
|
||||
},
|
||||
"always-on-top": "Vedno na vrhu",
|
||||
"auto-update": "Avtomatsko posodobi",
|
||||
"hide-menu": {
|
||||
"dialog": {
|
||||
"message": "Meni se bo skrit pri naslednjem zagonu, uporabi [Alt] da se prikaže (ali [`] v in-app-menu)",
|
||||
"title": "Skrij meni vklopljen"
|
||||
},
|
||||
"label": "Skrij meni"
|
||||
},
|
||||
"language": {
|
||||
"dialog": {
|
||||
"message": "Jezik bo spremenjen po ponovnem zagonu",
|
||||
"title": "Jezik je bil spremenjen"
|
||||
},
|
||||
"label": "Jezik",
|
||||
"submenu": {
|
||||
"to-help-translate": "Želiš pomagati prevediti? Klikni tukaj"
|
||||
}
|
||||
},
|
||||
"resume-on-start": "Predvajaj zadnjo pesem, ko se aplikacija prižge",
|
||||
"single-instance-lock": "Zaklep ene instance",
|
||||
"start-at-login": "Prižgi pri zagonu",
|
||||
"starting-page": {
|
||||
"label": "Začetna stran",
|
||||
"unset": "Ni nastavljeno"
|
||||
},
|
||||
"tray": {
|
||||
"label": "Pladenj",
|
||||
"submenu": {
|
||||
"disabled": "Izklopljeno",
|
||||
"enabled-and-hide-app": "Vklopljeno in skrij",
|
||||
"enabled-and-show-app": "Vklopljeno in pokaži",
|
||||
"play-pause-on-click": "Predvajaj/Pavza z klikom"
|
||||
}
|
||||
},
|
||||
"visual-tweaks": {
|
||||
"label": "Vizualni popravki",
|
||||
"submenu": {
|
||||
"like-buttons": {
|
||||
"default": "Privzeto",
|
||||
"force-show": "Prisilno pokaži",
|
||||
"hide": "Skrij",
|
||||
"label": "Gumb všeč mi je"
|
||||
},
|
||||
"remove-upgrade-button": "Odstrani gumb za nadgradnjo",
|
||||
"theme": {
|
||||
"dialog": {
|
||||
"button": {
|
||||
"cancel": "Prekliči",
|
||||
"remove": "Odstrani"
|
||||
},
|
||||
"remove-theme": "Ali želite odstraniti poljubno temo?",
|
||||
"remove-theme-message": "Poljubna tema bo odtranjena"
|
||||
},
|
||||
"label": "Tema",
|
||||
"submenu": {
|
||||
"import-css-file": "Vstavi poljubni CSS",
|
||||
"no-theme": "Brez teme"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"plugins": {
|
||||
"enabled": "Vključeno",
|
||||
"label": "Dodatki",
|
||||
"new": "NOVO"
|
||||
},
|
||||
"view": {
|
||||
"label": "Pogled",
|
||||
"submenu": {
|
||||
"force-reload": "Prisilno ponovno naloži",
|
||||
"reload": "Ponovno naloži",
|
||||
"reset-zoom": "Prava velikost",
|
||||
"toggle-fullscreen": "Prikaži cel zaslon",
|
||||
"zoom-in": "Povečaj",
|
||||
"zoom-out": "Pomanjšaj"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tray": {
|
||||
"next": "Naprej",
|
||||
"play-pause": "Predvajaj/Pavza",
|
||||
"previous": "Prejšni",
|
||||
"quit": "Izhod",
|
||||
"restart": "Ponovni zagon",
|
||||
"show": "Pokaži okno",
|
||||
"tooltip": {
|
||||
"default": "YouTube Glasba",
|
||||
"with-song-info": "YouTube Glasba: {{artist}} - {{title}}"
|
||||
}
|
||||
}
|
||||
},
|
||||
"plugins": {
|
||||
"adblocker": {
|
||||
"description": "Izklopi vse oglase od začetka",
|
||||
"menu": {
|
||||
"blocker": "Blocker"
|
||||
},
|
||||
"name": "Ad Blocker"
|
||||
},
|
||||
"album-actions": {
|
||||
"description": "Doda Undislike, Dislike, Like, in Unlike gumbe vsem glasbam v seznamu predvajanja ali albumu",
|
||||
"name": "Nastavitve albuma"
|
||||
},
|
||||
"album-color-theme": {
|
||||
"description": "Doda dinamično temo in vizualne efekte glede na barve albuma",
|
||||
"menu": {
|
||||
"color-mix-ratio": {
|
||||
"label": "Raznerje barv",
|
||||
"submenu": {
|
||||
"percent": "{{ratio}}%"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "Tema Brav Albuma"
|
||||
},
|
||||
"ambient-mode": {
|
||||
"description": "Doda bravn efekt iz video posnetka na ozadje",
|
||||
"menu": {
|
||||
"blur-amount": {
|
||||
"label": "količina zameglitve",
|
||||
"submenu": {
|
||||
"pixels": "{{blurAmount}} pikslov"
|
||||
}
|
||||
},
|
||||
"buffer": {
|
||||
"label": "Medpolnilnik",
|
||||
"submenu": {
|
||||
"buffer": "{{buffer}}"
|
||||
}
|
||||
},
|
||||
"opacity": {
|
||||
"label": "Nepreglednost",
|
||||
"submenu": {
|
||||
"percent": "{{opacity}}%"
|
||||
}
|
||||
},
|
||||
"quality": {
|
||||
"label": "Kvaliteta",
|
||||
"submenu": {
|
||||
"pixels": "{{quality}} pikslov"
|
||||
}
|
||||
},
|
||||
"size": {
|
||||
"label": "Velikost",
|
||||
"submenu": {
|
||||
"percent": "{{size}}%"
|
||||
}
|
||||
},
|
||||
"smoothness-transition": {
|
||||
"label": "Gladkost prehoda",
|
||||
"submenu": {
|
||||
"during": "Med {{interpolationTime}} s"
|
||||
}
|
||||
},
|
||||
"use-fullscreen": {
|
||||
"label": "Uporablja cel zaslon"
|
||||
}
|
||||
},
|
||||
"name": "Ambienten način"
|
||||
},
|
||||
"audio-compressor": {
|
||||
"description": "Doda kompresijo zvoka (izenači ravni zvoka, zniža glasnost najglasnejših delov in zviša najtišje)",
|
||||
"name": "Kompresija zvoka"
|
||||
},
|
||||
"blur-nav-bar": {
|
||||
"description": "Naredi navigacijsko vrstico prozorno in zamegljeno",
|
||||
"name": "Zameglji navigacijsko vrstico"
|
||||
},
|
||||
"bypass-age-restrictions": {
|
||||
"description": "Preskoči YouTubo-vo preverjanje starosti",
|
||||
"name": "Preskoči starostno omejitev"
|
||||
},
|
||||
"captions-selector": {
|
||||
"description": "Izberi podnapise za YouTube Music zvočne posnetke",
|
||||
"menu": {
|
||||
"autoload": "Avtomatsko uporabi zanje izbrane podnapise",
|
||||
"disable-captions": "Avtomatsko brez podnapisov"
|
||||
},
|
||||
"name": "Izberi podnapise",
|
||||
"prompt": {
|
||||
"selector": {
|
||||
"label": "Trenutni jezik podnapisov: {{language}}",
|
||||
"none": "Brez",
|
||||
"title": "Izberi jezik podnapisov"
|
||||
}
|
||||
},
|
||||
"templates": {
|
||||
"title": "Odpri izbir podnapisov"
|
||||
}
|
||||
},
|
||||
"compact-sidebar": {
|
||||
"description": "Vedno izberi kompakten način stranske vrstice",
|
||||
"name": "Kompaktna stranska vrstica"
|
||||
},
|
||||
"crossfade": {
|
||||
"description": "Bledenje med pesmimi",
|
||||
"menu": {
|
||||
"advanced": "Dodatno"
|
||||
},
|
||||
"name": "Bledenje med pesmimi [Beta]",
|
||||
"prompt": {
|
||||
"options": {
|
||||
"multi-input": {
|
||||
"fade-in-duration": "Čas zbledenja (v pesem) (ms)",
|
||||
"fade-out-duration": "Čas zbledenja (izven pesemi) (ms)",
|
||||
"fade-scaling": {
|
||||
"label": "Fade scaling",
|
||||
"linear": "Linearno",
|
||||
"logarithmic": "Logaritmično"
|
||||
},
|
||||
"seconds-before-end": "Crossfade N seconds before end"
|
||||
},
|
||||
"title": "Možnosti zbledenja"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -8,7 +8,7 @@
|
||||
"load-all": "กำลังโหลดปลั๊กอินทั้งหมด",
|
||||
"load-failed": "ไม่สามารถโหลดปลั๊กอิน \"{{pluginName}}\"ได้",
|
||||
"loaded": "โหลดปลั๊กอิน \"{{pluginName}}\" เรียบร้อยแล้ว",
|
||||
"unload-failed": "ไม่่สามรถโหลดปลั๊กอิน \"{{pluginName}}\"ได้",
|
||||
"unload-failed": "ไม่สามารถโหลดปลั๊กอิน \"{{pluginName}}\"ได้",
|
||||
"unloaded": "ยกเลิกโหลดปลั๊กอิน \"{{pluginName}}\" แล้ว"
|
||||
}
|
||||
}
|
||||
@ -158,6 +158,14 @@
|
||||
},
|
||||
"remove-upgrade-button": "ลบปุ่มอัปเกรด",
|
||||
"theme": {
|
||||
"dialog": {
|
||||
"button": {
|
||||
"cancel": "ยกเลิก",
|
||||
"remove": "ลบ"
|
||||
},
|
||||
"remove-theme": "คุณแน่ใจหรือหรือไม่ที่จะลบธีม?",
|
||||
"remove-theme-message": "สิ่งนี้จะลบธีมที่กำหนดเอง"
|
||||
},
|
||||
"label": "ธีม",
|
||||
"submenu": {
|
||||
"import-css-file": "นำเข้าไฟล์ CSS ที่กำหนดเอง",
|
||||
@ -472,7 +480,60 @@
|
||||
"name": "Music Together [เบต้า]",
|
||||
"toast": {
|
||||
"add-song-failed": "เพิ่มเพลงล้มเหลว",
|
||||
"closed": "ปิด Music Together แล้ว"
|
||||
"closed": "ปิด Music Together แล้ว",
|
||||
"disconnected": "การฟังเพลงร่วมกัน ถูกตัดการเชื่อมต่อแล้ว",
|
||||
"host-failed": "มีปัญหาสำหรับโฮสต์ฟังเพลงร่วมกัน",
|
||||
"id-copied": "ID โฮสต์ถูกคัดลอกแล้ว",
|
||||
"id-copy-failed": "ไม่สามรถคัดลอก ID โฮสต์ได้",
|
||||
"join-failed": "ไม่สามรถเข้าร่วมฟังเพลงร่วมกันได้",
|
||||
"joined": "เข้าร่วมฟังเพลงด้วยกันแล้ว",
|
||||
"permission-changed": "สิทธิการฟังเพลงร่วมกันเปลี่ยนเป็น \"{{permission}}\"",
|
||||
"remove-song-failed": "ไม่สารถลบเพลงได้",
|
||||
"user-connected": "{{name}}เข้าร่วมตี้ฟังเพลงด้วยกัน",
|
||||
"user-disconnected": "{{name}}ออกจากตี้ฟังเพลงด้วยกัน"
|
||||
}
|
||||
},
|
||||
"navigation": {
|
||||
"description": "ลูกศรนำทางถัดไป/ย้อนกลับรวมอยู่ในอินเทอร์เฟซโดยตรง เช่นเดียวกับในเบราว์เซอร์ที่คุณชื่นชอบ",
|
||||
"name": "การนำทาง"
|
||||
},
|
||||
"no-google-login": {
|
||||
"description": "ลบปุ่มเข้าสู่ระบบ Google และลิงก์ออกจากอินเทอร์เฟซ",
|
||||
"name": "ไม่ล็อกอิน Google"
|
||||
},
|
||||
"notifications": {
|
||||
"description": "แสดงการแจ้งเตือนเมื่อเพลงเริ่มเล่น (การแจ้งเตือนมีให้ใช้งานบน Windows)",
|
||||
"menu": {
|
||||
"interactive": "การแจ้งเตือนแบบโต้ตอบ",
|
||||
"interactive-settings": {
|
||||
"label": "การตั้งค่าการโต้ตอบ",
|
||||
"submenu": {
|
||||
"hide-button-text": "ซ่อนข้อความปุ่ม",
|
||||
"refresh-on-play-pause": "รีเฟรชเมื่อเล่น/หยุดชั่วคราว",
|
||||
"tray-controls": "เปิด/ปิดเมื่อคลิกถาด"
|
||||
}
|
||||
},
|
||||
"priority": "ลำดับความสำคัญของการแจ้งเตือน",
|
||||
"unpause-notification": "แสดงการแจ้งเตือนเมื่อหยุดพัก"
|
||||
},
|
||||
"name": "การแจ้งเตือน"
|
||||
},
|
||||
"picture-in-picture": {
|
||||
"description": "อนุญาตให้สลับแอปเป็นโหมดภาพในภาพ",
|
||||
"menu": {
|
||||
"always-on-top": "อยู่ด้านบนเสมอ",
|
||||
"hotkey": {
|
||||
"label": "ปุ่มลัด",
|
||||
"prompt": {
|
||||
"keybind-options": {
|
||||
"hotkey": "ปุ่มลัด"
|
||||
},
|
||||
"label": "เลือกปุ่มลัดเพื่อสลับโหมดภาพในภาพ",
|
||||
"title": "ปุ่มลัดสำหรับโหมดภาพในภาพ"
|
||||
}
|
||||
},
|
||||
"save-window-position": "บันทึกตำแหน่งหน้าต่าง",
|
||||
"save-window-size": "บันทึกขนาดหน้าต่าง"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -158,6 +158,14 @@
|
||||
},
|
||||
"remove-upgrade-button": "Yükseltme düğmesini kaldır",
|
||||
"theme": {
|
||||
"dialog": {
|
||||
"button": {
|
||||
"cancel": "İptal",
|
||||
"remove": "Kaldır"
|
||||
},
|
||||
"remove-theme": "Özel temayı kaldırmak istediğinizden emin misiniz?",
|
||||
"remove-theme-message": "Bu işlem özel temayı kaldıracaktır"
|
||||
},
|
||||
"label": "Tema",
|
||||
"submenu": {
|
||||
"import-css-file": "Özel CSS dosyanı içeri aktar",
|
||||
@ -199,6 +207,10 @@
|
||||
}
|
||||
},
|
||||
"plugins": {
|
||||
"ad-speedup": {
|
||||
"description": "Bir reklam oynatılırsa sesi kapatır ve oynatma hızını 16x olarak ayarlar",
|
||||
"name": "Hızlandırma"
|
||||
},
|
||||
"adblocker": {
|
||||
"description": "Tüm reklamları ve izleyicileri engelle",
|
||||
"menu": {
|
||||
@ -402,6 +414,21 @@
|
||||
"description": "MP3 / kaynak sesini doğrudan arayüzden indir",
|
||||
"menu": {
|
||||
"choose-download-folder": "İndirme klasörünü seç",
|
||||
"download-finish-settings": {
|
||||
"label": "Bittiğinde indir",
|
||||
"prompt": {
|
||||
"last-percent": "Yüzde x'ten sonra",
|
||||
"last-seconds": "Son x saniyede",
|
||||
"title": "Ne zaman indirileceğini ayarla"
|
||||
},
|
||||
"submenu": {
|
||||
"advanced": "Gelişmiş",
|
||||
"enabled": "Etkin",
|
||||
"mode": "Zaman türü",
|
||||
"percent": "Yüzde",
|
||||
"seconds": "Saniye"
|
||||
}
|
||||
},
|
||||
"download-playlist": "Oynatma listesini indir",
|
||||
"presets": "Hazır Ayarlar",
|
||||
"skip-existing": "Mevcut dosyaları atla"
|
||||
@ -641,6 +668,59 @@
|
||||
"description": "Giriş/Çıkış gibi müzik olmayan kısımları veya müzik videolarında şarkının çalmadığı kısımları otomatik olarak atlar",
|
||||
"name": "SponsorBlock"
|
||||
},
|
||||
"synced-lyrics": {
|
||||
"description": "LRClib gibi sağlayıcıları kullanarak şarkılara senkronize şarkı sözleri sağlar.",
|
||||
"errors": {
|
||||
"fetch": "⚠️ - Şarkı sözleri getirilirken bir hata oluştu. Lütfen daha sonra tekrar deneyin.",
|
||||
"not-found": "⚠️ - Bu şarkı için şarkı sözü bulunamadı."
|
||||
},
|
||||
"menu": {
|
||||
"default-text-string": {
|
||||
"label": "Şarkı sözleri arasında varsayılan karakter",
|
||||
"tooltip": "Şarkı sözleri arasındaki boşluk için kullanılacak varsayılan karakteri seçin"
|
||||
},
|
||||
"line-effect": {
|
||||
"label": "Çizgi etkisi",
|
||||
"submenu": {
|
||||
"focus": {
|
||||
"label": "odak",
|
||||
"tooltip": "Yalnızca geçerli satırı beyaz yapın"
|
||||
},
|
||||
"offset": {
|
||||
"label": "telafi etmek,ofset",
|
||||
"tooltip": "Geçerli satırın sağındaki ofset"
|
||||
},
|
||||
"scale": {
|
||||
"label": "ölçek",
|
||||
"tooltip": "Geçerli satırı ölçeklendirir"
|
||||
}
|
||||
},
|
||||
"tooltip": "Geçerli satıra uygulanacak efekti seçin"
|
||||
},
|
||||
"precise-timing": {
|
||||
"label": "Şarkı sözlerini mükemmel şekilde senkronize edin",
|
||||
"tooltip": "Bir sonraki satırın görüntülenmesini milisaniyesine kadar hesaplayın (performans üzerinde küçük bir etkisi olabilir)"
|
||||
},
|
||||
"show-lyrics-even-if-inexact": {
|
||||
"label": "Kesin olmasa bile şarkı sözlerini gösterin",
|
||||
"tooltip": "Şarkı bulunamazsa, eklenti farklı bir arama sorgusuyla tekrar dener. \nİkinci denemenin sonucu tam olmayabilir."
|
||||
},
|
||||
"show-time-codes": {
|
||||
"label": "Zaman kodlarını göster",
|
||||
"tooltip": "Şarkı sözlerinin yanında zaman kodlarını gösterin"
|
||||
}
|
||||
},
|
||||
"name": "Senkronize Şarkı Sözleri",
|
||||
"refetch-btn": {
|
||||
"fetching": "Getiriliyor...",
|
||||
"normal": "Refetch şarkı sözleri"
|
||||
},
|
||||
"warnings": {
|
||||
"duration-mismatch": "⚠️ - Süre uyuşmazlığı nedeniyle şarkı sözleri senkronize olmayabilir.",
|
||||
"inexact": "⚠️ - Bu şarkının sözleri tam olmayabilir",
|
||||
"instrumental": "⚠️ - Bu enstrümantal bir şarkıdır"
|
||||
}
|
||||
},
|
||||
"taskbar-mediacontrol": {
|
||||
"description": "Windows görev çubuğu üzerinden oynatmayı kontrol edebilmenize olanak sağlar",
|
||||
"name": "Görev Çubuğu Medya Kontrolü"
|
||||
|
||||
@ -158,6 +158,14 @@
|
||||
},
|
||||
"remove-upgrade-button": "Прибрати кнопку оновлення",
|
||||
"theme": {
|
||||
"dialog": {
|
||||
"button": {
|
||||
"cancel": "Скасувати",
|
||||
"remove": "Видалити"
|
||||
},
|
||||
"remove-theme": "Ви впевнені, що хочете видалити власну тему?",
|
||||
"remove-theme-message": "Це видалить власну тему"
|
||||
},
|
||||
"label": "Тема",
|
||||
"submenu": {
|
||||
"import-css-file": "Імпортувати власний CSS файл",
|
||||
@ -199,6 +207,10 @@
|
||||
}
|
||||
},
|
||||
"plugins": {
|
||||
"ad-speedup": {
|
||||
"description": "При програванні реклами звук вимикається і встановлюється швидкість відтворення 16х",
|
||||
"name": "Прискорення реклами"
|
||||
},
|
||||
"adblocker": {
|
||||
"description": "Блокувати всю рекламу та відстеження з коробки",
|
||||
"menu": {
|
||||
@ -267,6 +279,49 @@
|
||||
},
|
||||
"name": "Режим навколишнього середовища"
|
||||
},
|
||||
"api-server": {
|
||||
"description": "Додає API сервер для контролю плеєра",
|
||||
"dialog": {
|
||||
"request": {
|
||||
"buttons": {
|
||||
"allow": "Дозволити",
|
||||
"deny": "Відмінити"
|
||||
},
|
||||
"message": "Дозволити {{ID}} ({{origin}}) доступ до API?",
|
||||
"title": "Запит авторизації до API"
|
||||
}
|
||||
},
|
||||
"menu": {
|
||||
"auth-strategy": {
|
||||
"label": "Стратегія авторизації",
|
||||
"submenu": {
|
||||
"auth-at-first": {
|
||||
"label": "Авторизувати при першому запиті"
|
||||
},
|
||||
"none": {
|
||||
"label": "Немає авторизації"
|
||||
}
|
||||
}
|
||||
},
|
||||
"hostname": {
|
||||
"label": "Назва серверу"
|
||||
},
|
||||
"port": {
|
||||
"label": "Порт"
|
||||
}
|
||||
},
|
||||
"name": "API сервер [Бета]",
|
||||
"prompt": {
|
||||
"hostname": {
|
||||
"label": "Введіть ім'я хоста (наприклад 0.0.0.0) для API серверу:",
|
||||
"title": "Ім'я хоста"
|
||||
},
|
||||
"port": {
|
||||
"label": "Введіть порт API серверу:",
|
||||
"title": "Порт"
|
||||
}
|
||||
}
|
||||
},
|
||||
"audio-compressor": {
|
||||
"description": "Застосувати стиснення аудіо (зменшити гучність найгучніших фрагментів сигналу та збільшити гучність тихих фрагментів)",
|
||||
"name": "Аудіокомпресор"
|
||||
@ -402,6 +457,21 @@
|
||||
"description": "Завантажує MP3 / джерело аудіо безпосередньо з інтерфейсу",
|
||||
"menu": {
|
||||
"choose-download-folder": "Оберіть папку для завантаження",
|
||||
"download-finish-settings": {
|
||||
"label": "Скачати по завершенню",
|
||||
"prompt": {
|
||||
"last-percent": "Після Х відсотків",
|
||||
"last-seconds": "Останні Х секунд",
|
||||
"title": "Налаштувати коли завантажувати"
|
||||
},
|
||||
"submenu": {
|
||||
"advanced": "Розширені",
|
||||
"enabled": "Увімкнено",
|
||||
"mode": "Режим часу",
|
||||
"percent": "Відсоток",
|
||||
"seconds": "Секунди"
|
||||
}
|
||||
},
|
||||
"download-playlist": "Завантажити плейлист",
|
||||
"presets": "Попередні налаштування",
|
||||
"skip-existing": "Пропустити наявні файли"
|
||||
@ -641,6 +711,59 @@
|
||||
"description": "Автоматично пропускати немузичні частини, такі як вступ/закінчення або частини музичних відеороликів, де не відтворюється музика",
|
||||
"name": "SponsorBlock"
|
||||
},
|
||||
"synced-lyrics": {
|
||||
"description": "Додає синхронізовані тексти до пісень використовуючи провайдери, такі як LRClib.",
|
||||
"errors": {
|
||||
"fetch": "⚠️ - При завантаженні тексту сталась помилка. Спробуйте ще раз пізніше.",
|
||||
"not-found": "⚠️ - До цієї пісні текст не знайдено."
|
||||
},
|
||||
"menu": {
|
||||
"default-text-string": {
|
||||
"label": "Символ за замовчуванням між текстами пісень",
|
||||
"tooltip": "Виберіть символ за замовчуванням, який буде використовуватися для проміжку між текстами пісень"
|
||||
},
|
||||
"line-effect": {
|
||||
"label": "Лінійний ефект",
|
||||
"submenu": {
|
||||
"focus": {
|
||||
"label": "Зосереджитись",
|
||||
"tooltip": "Зробити білим лише поточний рядок"
|
||||
},
|
||||
"offset": {
|
||||
"label": "Офсет",
|
||||
"tooltip": "Офсет з права від нинішньої лінії"
|
||||
},
|
||||
"scale": {
|
||||
"label": "Масштабувати",
|
||||
"tooltip": "Масштабуваты поточну лінію"
|
||||
}
|
||||
},
|
||||
"tooltip": "Виберіть ефект, який потрібно застосувати до поточної лінії"
|
||||
},
|
||||
"precise-timing": {
|
||||
"label": "Зробити текст пісні ідеально синхронізованим",
|
||||
"tooltip": "Обчисли до мілісекунд відображення наступного рядка (може мати невеликий вплив на продуктивність)"
|
||||
},
|
||||
"show-lyrics-even-if-inexact": {
|
||||
"label": "Показувати текст пісні, навіть якщо він неточний",
|
||||
"tooltip": "Якщо пісня не знайдена, плагін повторює спробу з іншим пошуковим запитом.\nРезультат з другої спроби може бути не точним."
|
||||
},
|
||||
"show-time-codes": {
|
||||
"label": "Показувати часові марки",
|
||||
"tooltip": "Показує часові маркы поруч із текстом пісні"
|
||||
}
|
||||
},
|
||||
"name": "Синхронізовані тексти",
|
||||
"refetch-btn": {
|
||||
"fetching": "Завантаження...",
|
||||
"normal": "Перезавантажити текст"
|
||||
},
|
||||
"warnings": {
|
||||
"duration-mismatch": "⚠️ - Тексти цієї пісні можуть бути не синхронізовані через не співпадіння довжини пісні.",
|
||||
"inexact": "⚠️ - Текст цієї пісні може не співпадати",
|
||||
"instrumental": "⚠️ - Це інструментал"
|
||||
}
|
||||
},
|
||||
"taskbar-mediacontrol": {
|
||||
"description": "Керування відтворенням з панелі завдань Windows",
|
||||
"name": "Керування медіа на панелі завдань"
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
"common": {
|
||||
"console": {
|
||||
"plugins": {
|
||||
"execute-failed": "Lỗi khi bắt đầu phần mở rộng {{pluginName}}::{{contextName}}",
|
||||
"execute-failed": "Lỗi thực thi plugin {{pluginName}}::{{contextName}}",
|
||||
"executed-at-ms": "Phần mở rộng {{pluginName}}::{{contextName}} đã bắt đầu trong {{ms}}ms",
|
||||
"initialize-failed": "Lỗi khi khởi động phần mở rộng \"{{pluginName}}\"",
|
||||
"load-all": "Đang tải tất cả phần mở rộng",
|
||||
@ -158,6 +158,14 @@
|
||||
},
|
||||
"remove-upgrade-button": "Xóa nút nâng cấp",
|
||||
"theme": {
|
||||
"dialog": {
|
||||
"button": {
|
||||
"cancel": "Hủy",
|
||||
"remove": "Loại bỏ"
|
||||
},
|
||||
"remove-theme": "Bạn có chắc muốn loại bỏ chủ đề tùy chỉnh không?",
|
||||
"remove-theme-message": "Tùy chọn này sẽ loại bỏ chủ đề tùy chỉnh"
|
||||
},
|
||||
"label": "Chủ đề",
|
||||
"submenu": {
|
||||
"import-css-file": "Nhập tệp CSS tùy chỉnh",
|
||||
@ -199,6 +207,10 @@
|
||||
}
|
||||
},
|
||||
"plugins": {
|
||||
"ad-speedup": {
|
||||
"description": "Nếu một quảng cáo được phát thì sẽ bị tắt tiếng và tăng tốc độ phát lên 16x",
|
||||
"name": "Tăng tốc quảng cáo"
|
||||
},
|
||||
"adblocker": {
|
||||
"description": "Chặn toàn bộ quảng cáo và trình theo dõi",
|
||||
"menu": {
|
||||
@ -402,6 +414,21 @@
|
||||
"description": "Tải xuống MP3 / âm thanh nguồn trực tiếp từ giao diện",
|
||||
"menu": {
|
||||
"choose-download-folder": "Chọn thư mục tải xuống",
|
||||
"download-finish-settings": {
|
||||
"label": "Tải xuống khi hoàn tất",
|
||||
"prompt": {
|
||||
"last-percent": "Sau x phần trăm",
|
||||
"last-seconds": "x giây cuối",
|
||||
"title": "Định cấu hình thời điểm tải xuống"
|
||||
},
|
||||
"submenu": {
|
||||
"advanced": "Nâng cao",
|
||||
"enabled": "Đã kích hoạt",
|
||||
"mode": "Chế độ thời gian",
|
||||
"percent": "Phần trăm",
|
||||
"seconds": "Giây"
|
||||
}
|
||||
},
|
||||
"download-playlist": "Tải danh sách phát",
|
||||
"presets": "Cài đặt sẵn",
|
||||
"skip-existing": "Bỏ qua các tập tin hiện có"
|
||||
@ -641,6 +668,55 @@
|
||||
"description": "Tự động bỏ qua các phần không phải âm nhạc như phần giới thiệu/kết thúc hoặc các phần của video nhạc mà bài hát không được phát",
|
||||
"name": "SponsorBlock"
|
||||
},
|
||||
"synced-lyrics": {
|
||||
"description": "Cung cấp lời bài hát được đồng bộ hoá với các bài hát, sử dụng những nhà cung cấp như LRClib.",
|
||||
"errors": {
|
||||
"fetch": "⚠️ - Đã xảy ra lỗi khi tìm nạp lời bài hát, Vui lòng thử lại sau.",
|
||||
"not-found": "⚠️ - Không tìm thấy lời cho bài hát này."
|
||||
},
|
||||
"menu": {
|
||||
"default-text-string": {
|
||||
"label": "Kí tự mặc định giữa các lời bài hát",
|
||||
"tooltip": "Chọn kí tự mặc định cho khoảng trống giữa các lời bài hát"
|
||||
},
|
||||
"line-effect": {
|
||||
"label": "Kiểu đường thẳng",
|
||||
"submenu": {
|
||||
"focus": {
|
||||
"label": "Tập trung",
|
||||
"tooltip": "Chỉ làm cho dòng hiện tại có màu trắng"
|
||||
},
|
||||
"scale": {
|
||||
"label": "Tỉ lệ",
|
||||
"tooltip": "Áp dụng tỉ lệ cho dòng hiện tại"
|
||||
}
|
||||
},
|
||||
"tooltip": "Chọn kiểu để áp dụng cho dòng hiện tại"
|
||||
},
|
||||
"precise-timing": {
|
||||
"label": "Làm cho lời bài hát được đồng bộ hoàn hảo",
|
||||
"tooltip": "Tính toán chính xác đến mili giây thời gian hiển thị dòng tiếp theo (có thể có tác động nhỏ đến hiệu suất)"
|
||||
},
|
||||
"show-lyrics-even-if-inexact": {
|
||||
"label": "Hiển thị lời bài hát ngay cả khi không chính xác",
|
||||
"tooltip": "Nếu không tìm thấy bài hát, plugin sẽ thử lại bằng truy vấn tìm kiếm khác.\nKết quả từ lần thử thứ hai có thể không chính xác."
|
||||
},
|
||||
"show-time-codes": {
|
||||
"label": "Hiện mốc thời gian",
|
||||
"tooltip": "Hiện mốc thời gian bên cạnh lời bài hát"
|
||||
}
|
||||
},
|
||||
"name": "Lời bài hát được đồng bộ hoá",
|
||||
"refetch-btn": {
|
||||
"fetching": "Đang tìm nạp...",
|
||||
"normal": "Tải lại lời bài hát"
|
||||
},
|
||||
"warnings": {
|
||||
"duration-mismatch": "⚠️ - Lời bài hát có thể không đồng bộ do thời lượng không khớp.",
|
||||
"inexact": "⚠️ - Lời bài hát này có thể không chính xác",
|
||||
"instrumental": "⚠️ - Đây là một bài hát trình diễn bằng nhạc khí"
|
||||
}
|
||||
},
|
||||
"taskbar-mediacontrol": {
|
||||
"description": "Kiểm soát phát lại từ thanh tác vụ Windows của bạn",
|
||||
"name": "Kiểm soát phương tiện trên thanh tác vụ"
|
||||
|
||||
@ -158,6 +158,14 @@
|
||||
},
|
||||
"remove-upgrade-button": "移除升级按钮",
|
||||
"theme": {
|
||||
"dialog": {
|
||||
"button": {
|
||||
"cancel": "取消",
|
||||
"remove": "移除"
|
||||
},
|
||||
"remove-theme": "您确定要移除自定义主题?",
|
||||
"remove-theme-message": "此操作将移除自定义主题"
|
||||
},
|
||||
"label": "主题",
|
||||
"submenu": {
|
||||
"import-css-file": "导入自定义 CSS 文件",
|
||||
@ -199,6 +207,10 @@
|
||||
}
|
||||
},
|
||||
"plugins": {
|
||||
"ad-speedup": {
|
||||
"description": "使用静音以及 16 倍速播放跳过广告片段",
|
||||
"name": "广告加速跳过"
|
||||
},
|
||||
"adblocker": {
|
||||
"description": "屏蔽所有广告与跟踪器",
|
||||
"menu": {
|
||||
@ -402,6 +414,21 @@
|
||||
"description": "在界面内直接下载 MP3 / 源音频",
|
||||
"menu": {
|
||||
"choose-download-folder": "选择下载文件夹",
|
||||
"download-finish-settings": {
|
||||
"label": "边播边下",
|
||||
"prompt": {
|
||||
"last-percent": "播放超过指定百分比时开始下载",
|
||||
"last-seconds": "歌曲剩余指定秒数时开始下载",
|
||||
"title": "配置在何时开始下载"
|
||||
},
|
||||
"submenu": {
|
||||
"advanced": "高级",
|
||||
"enabled": "已启用",
|
||||
"mode": "激活时机",
|
||||
"percent": "按播放百分比",
|
||||
"seconds": "按播放秒数"
|
||||
}
|
||||
},
|
||||
"download-playlist": "下载播放列表",
|
||||
"presets": "预设",
|
||||
"skip-existing": "跳过已存在的文件"
|
||||
@ -641,6 +668,59 @@
|
||||
"description": "自动跳过非音乐部分,如 MV 的介绍/结语以及歌曲未开始的部分",
|
||||
"name": "SponsorBlock"
|
||||
},
|
||||
"synced-lyrics": {
|
||||
"description": "透过 LRClib 等服务提供滚动歌词显示。",
|
||||
"errors": {
|
||||
"fetch": "⚠️ - 获取歌词时发生错误。请稍后再试。",
|
||||
"not-found": "⚠️ - 未找到此歌曲的歌词。"
|
||||
},
|
||||
"menu": {
|
||||
"default-text-string": {
|
||||
"label": "默认的歌词行间字符",
|
||||
"tooltip": "选择在歌词间隙期间默认显示的字符"
|
||||
},
|
||||
"line-effect": {
|
||||
"label": "歌词行特效",
|
||||
"submenu": {
|
||||
"focus": {
|
||||
"label": "高亮",
|
||||
"tooltip": "仅将当前歌词行显示为白色"
|
||||
},
|
||||
"offset": {
|
||||
"label": "偏移",
|
||||
"tooltip": "将当前歌词行向右偏移"
|
||||
},
|
||||
"scale": {
|
||||
"label": "放大",
|
||||
"tooltip": "放大当前歌词行"
|
||||
}
|
||||
},
|
||||
"tooltip": "选择当前歌词行应用的特效"
|
||||
},
|
||||
"precise-timing": {
|
||||
"label": "让滚动歌词完全同步",
|
||||
"tooltip": "以毫秒精度估算下句歌词的显示时间(可能对性能有小幅影响)"
|
||||
},
|
||||
"show-lyrics-even-if-inexact": {
|
||||
"label": "即使时值不精确依然显示歌词",
|
||||
"tooltip": "若首次搜索未找到该歌曲的歌词,插件将尝试用不同的查询方式重新获取。\n重试查询的结果可能不精确。"
|
||||
},
|
||||
"show-time-codes": {
|
||||
"label": "显示时值",
|
||||
"tooltip": "在歌词旁显示时值"
|
||||
}
|
||||
},
|
||||
"name": "滚动歌词",
|
||||
"refetch-btn": {
|
||||
"fetching": "正在获取…",
|
||||
"normal": "重新获取歌词"
|
||||
},
|
||||
"warnings": {
|
||||
"duration-mismatch": "⚠️ - 由于持续时间不对应,滚动歌词可能不同步。",
|
||||
"inexact": "⚠️ - 此曲目的歌词可能不准确",
|
||||
"instrumental": "⚠️ - 此曲目为纯音乐"
|
||||
}
|
||||
},
|
||||
"taskbar-mediacontrol": {
|
||||
"description": "从 Windows 任务栏控制音乐回放",
|
||||
"name": "任务栏媒体控件"
|
||||
|
||||
@ -69,9 +69,9 @@
|
||||
},
|
||||
"update-available": {
|
||||
"buttons": {
|
||||
"disable": "停用更新",
|
||||
"download": "下載",
|
||||
"ok": "確定"
|
||||
"disable": "停用新版本通知",
|
||||
"download": "前往下載",
|
||||
"ok": "略過"
|
||||
},
|
||||
"detail": "新版本已經推出,你可以至 {{downloadLink}} 下載",
|
||||
"message": "有新版本可用",
|
||||
@ -96,11 +96,11 @@
|
||||
"advanced-options": {
|
||||
"label": "進階選項",
|
||||
"submenu": {
|
||||
"auto-reset-app-cache": "當程式啟動時重設應用程式快取",
|
||||
"auto-reset-app-cache": "啟動時重設應用快取",
|
||||
"disable-hardware-acceleration": "關閉硬體加速",
|
||||
"edit-config-json": "編輯 config.json",
|
||||
"override-user-agent": "覆寫使用者代理",
|
||||
"restart-on-config-changes": "在設定檔更動時自動重啟應用程式",
|
||||
"restart-on-config-changes": "設定變更時自動重啟應用",
|
||||
"set-proxy": {
|
||||
"label": "設定代理伺服器",
|
||||
"prompt": {
|
||||
@ -123,7 +123,7 @@
|
||||
},
|
||||
"language": {
|
||||
"dialog": {
|
||||
"message": "語言會在下一次重啟應用程式時變更",
|
||||
"message": "語言會在重啟應用後變更",
|
||||
"title": "語言已變更"
|
||||
},
|
||||
"label": "語言",
|
||||
@ -131,7 +131,7 @@
|
||||
"to-help-translate": "想協助翻譯?按一下這裡"
|
||||
}
|
||||
},
|
||||
"resume-on-start": "應用啟動時繼續上次播放的歌曲",
|
||||
"resume-on-start": "應用開啟時繼續播放上次的歌曲",
|
||||
"single-instance-lock": "單實例模式",
|
||||
"start-at-login": "開機時啟動",
|
||||
"starting-page": {
|
||||
@ -139,11 +139,11 @@
|
||||
"unset": "不指定"
|
||||
},
|
||||
"tray": {
|
||||
"label": "系統閘",
|
||||
"label": "系統匣",
|
||||
"submenu": {
|
||||
"disabled": "已停用",
|
||||
"enabled-and-hide-app": "啟用並最小化應用程式",
|
||||
"enabled-and-show-app": "啟用但持續顯示應用程式",
|
||||
"enabled-and-hide-app": "啟用並最小化應用",
|
||||
"enabled-and-show-app": "啟用並顯示應用",
|
||||
"play-pause-on-click": "點擊時播放/暫停"
|
||||
}
|
||||
},
|
||||
@ -158,6 +158,14 @@
|
||||
},
|
||||
"remove-upgrade-button": "移除升級按鈕",
|
||||
"theme": {
|
||||
"dialog": {
|
||||
"button": {
|
||||
"cancel": "取消",
|
||||
"remove": "確定移除"
|
||||
},
|
||||
"remove-theme": "確定要移除自訂主題嗎?",
|
||||
"remove-theme-message": "這將會移除自訂主題"
|
||||
},
|
||||
"label": "主題",
|
||||
"submenu": {
|
||||
"import-css-file": "匯入自訂 CSS 檔案",
|
||||
@ -199,6 +207,10 @@
|
||||
}
|
||||
},
|
||||
"plugins": {
|
||||
"ad-speedup": {
|
||||
"description": "使用 16 倍速播放及靜音來跳過廣告片段",
|
||||
"name": "加速略過"
|
||||
},
|
||||
"adblocker": {
|
||||
"description": "阻擋所有廣告",
|
||||
"menu": {
|
||||
@ -211,7 +223,7 @@
|
||||
"name": "進階專輯操作"
|
||||
},
|
||||
"album-color-theme": {
|
||||
"description": "依歌曲色調自動更改應用程式主題",
|
||||
"description": "根據專輯封面色調更改應用程式主題顏色",
|
||||
"menu": {
|
||||
"color-mix-ratio": {
|
||||
"label": "顏色混合程度",
|
||||
@ -267,6 +279,49 @@
|
||||
},
|
||||
"name": "微光效果"
|
||||
},
|
||||
"api-server": {
|
||||
"description": "新增伺服器以使用 API 控制播放器",
|
||||
"dialog": {
|
||||
"request": {
|
||||
"buttons": {
|
||||
"allow": "允許",
|
||||
"deny": "拒絕"
|
||||
},
|
||||
"message": "允許 {{ID}} ({{origin}}) 訪問 API 嗎?",
|
||||
"title": "API 驗證請求"
|
||||
}
|
||||
},
|
||||
"menu": {
|
||||
"auth-strategy": {
|
||||
"label": "驗證策略",
|
||||
"submenu": {
|
||||
"auth-at-first": {
|
||||
"label": "首次請求時驗證"
|
||||
},
|
||||
"none": {
|
||||
"label": "不要驗證"
|
||||
}
|
||||
}
|
||||
},
|
||||
"hostname": {
|
||||
"label": "主機名稱"
|
||||
},
|
||||
"port": {
|
||||
"label": "接口"
|
||||
}
|
||||
},
|
||||
"name": "API 伺服器 [Beta]",
|
||||
"prompt": {
|
||||
"hostname": {
|
||||
"label": "輸入 API 伺服器的主機名稱 例 (0.0.0.0):",
|
||||
"title": "主機名稱"
|
||||
},
|
||||
"port": {
|
||||
"label": "輸入 API 伺服器接口:",
|
||||
"title": "接口"
|
||||
}
|
||||
}
|
||||
},
|
||||
"audio-compressor": {
|
||||
"description": "使用音效壓縮 (大聲部份的音量降低, 柔和部份的音量提高)",
|
||||
"name": "音效壓縮器"
|
||||
@ -288,7 +343,7 @@
|
||||
"name": "標題選擇器",
|
||||
"prompt": {
|
||||
"selector": {
|
||||
"label": "目前標題語言: {{language}}",
|
||||
"label": "目前標題語言:{{language}}",
|
||||
"none": "無",
|
||||
"title": "選擇標題語言"
|
||||
}
|
||||
@ -333,10 +388,10 @@
|
||||
"discord": {
|
||||
"backend": {
|
||||
"already-connected": "已嘗試可用連接",
|
||||
"connected": "已連接至Discord",
|
||||
"disconnected": "與Discord斷開連接"
|
||||
"connected": "已連接至 Discord",
|
||||
"disconnected": "與 Discord 斷開連接"
|
||||
},
|
||||
"description": "使用Discord狀態與你的好友分享你正在收聽的音樂",
|
||||
"description": "使用 Discord 狀態與你的好友分享你正在收聽的音樂",
|
||||
"menu": {
|
||||
"auto-reconnect": "自動重新連接",
|
||||
"clear-activity": "清除狀態",
|
||||
@ -344,14 +399,14 @@
|
||||
"connected": "已連接",
|
||||
"disconnected": "已斷開連接",
|
||||
"hide-duration-left": "隱藏音樂剩餘時間狀態",
|
||||
"hide-github-button": "隱藏Github頁面按鈕",
|
||||
"play-on-youtube-music": "顯示Play on YouTube Music按鈕",
|
||||
"hide-github-button": "隱藏 Github 頁面按鈕",
|
||||
"play-on-youtube-music": "顯示 Play on YouTube Music 按鈕",
|
||||
"set-inactivity-timeout": "設定閒置狀態時長"
|
||||
},
|
||||
"name": "Discord狀態",
|
||||
"name": "Discord 狀態",
|
||||
"prompt": {
|
||||
"set-inactivity-timeout": {
|
||||
"label": "設定多少秒後清除狀態:",
|
||||
"label": "設定多少秒後清除狀態:",
|
||||
"title": "設定閒置狀態時長"
|
||||
}
|
||||
}
|
||||
@ -376,11 +431,11 @@
|
||||
}
|
||||
},
|
||||
"feedback": {
|
||||
"conversion-progress": "轉檔進度: {{percent}}%",
|
||||
"conversion-progress": "轉檔進度:{{percent}}%",
|
||||
"converting": "轉檔中…",
|
||||
"done": "完成下載: {{filePath}}",
|
||||
"done": "完成下載:{{filePath}}",
|
||||
"download-info": "正在下載 {{artist}} - {{title}} [{{videoId}}",
|
||||
"download-progress": "下載進度: {{percent}}%",
|
||||
"download-progress": "下載進度:{{percent}}%",
|
||||
"downloading": "下載中…",
|
||||
"downloading-counter": "正在下載第 {{current}}/{{total}}…",
|
||||
"downloading-playlist": "正在下載播放清單 \"{{playlistTitle}}\" - 共 {{playlistSize}} 首歌 ({{playlistId}})",
|
||||
@ -391,17 +446,32 @@
|
||||
"playlist-has-only-one-song": "播放清單內只有一首歌曲, 將直接下載",
|
||||
"playlist-id-not-found": "沒有找到播放清單 ID",
|
||||
"playlist-is-empty": "播放清單是空的",
|
||||
"playlist-is-mix-or-private": "獲取播放清單資訊時發生錯誤: 請確認非私人播放清單或是\"為你推薦的合輯\"\n\n{{error}}",
|
||||
"playlist-is-mix-or-private": "獲取播放清單資訊時發生錯誤:請確認非私人播放清單或是\"為你推薦的合輯\"\n\n{{error}}",
|
||||
"preparing-file": "正在準備檔案…",
|
||||
"saving": "儲存中…",
|
||||
"trying-to-get-playlist-id": "正在嘗試獲取播放清單 ID: {{playlistId}}",
|
||||
"trying-to-get-playlist-id": "正在嘗試獲取播放清單 ID:{{playlistId}}",
|
||||
"video-id-not-found": "未能找到該影片",
|
||||
"writing-id3": "正在寫入 ID3 標籤…"
|
||||
}
|
||||
},
|
||||
"description": "在應用程式內下載 MP3/原始音樂檔",
|
||||
"description": "開啟應用程式內下載 MP3/原始音檔功能",
|
||||
"menu": {
|
||||
"choose-download-folder": "選擇下載位置",
|
||||
"download-finish-settings": {
|
||||
"label": "智慧下載",
|
||||
"prompt": {
|
||||
"last-percent": "歌曲剩餘多少 % 時下載",
|
||||
"last-seconds": "歌曲剩餘多少秒時下載",
|
||||
"title": "智慧下載進階設定"
|
||||
},
|
||||
"submenu": {
|
||||
"advanced": "進階",
|
||||
"enabled": "啟用",
|
||||
"mode": "判斷方式",
|
||||
"percent": "百分比",
|
||||
"seconds": "秒數"
|
||||
}
|
||||
},
|
||||
"download-playlist": "下載播放清單",
|
||||
"presets": "預設格式",
|
||||
"skip-existing": "跳過已存在的檔案"
|
||||
@ -486,12 +556,12 @@
|
||||
}
|
||||
},
|
||||
"navigation": {
|
||||
"description": "將上一頁/下一頁按鈕新增至應用程式上方, 就像你最熟悉的瀏覽器",
|
||||
"description": "允許應用程式上方顯示上一頁/下一頁按鈕",
|
||||
"name": "導覽列"
|
||||
},
|
||||
"no-google-login": {
|
||||
"description": "移除Google登入按鈕及連結",
|
||||
"name": "停用Google登入"
|
||||
"description": "移除 Google 登入按鈕及連結",
|
||||
"name": "停用 Google 登入"
|
||||
},
|
||||
"notifications": {
|
||||
"description": "在歌曲播放時發送一個系統通知 (可互動通知僅限Windows)",
|
||||
@ -555,7 +625,7 @@
|
||||
"decrease": "降低音量",
|
||||
"increase": "增加音量"
|
||||
},
|
||||
"label": "選擇全域音量控制快捷鍵:",
|
||||
"label": "選擇全域音量控制快捷鍵:",
|
||||
"title": "全域音量控制快捷鍵"
|
||||
},
|
||||
"volume-steps": {
|
||||
@ -568,8 +638,8 @@
|
||||
"backend": {
|
||||
"dialog": {
|
||||
"quality-changer": {
|
||||
"detail": "目前畫質: {{quality}}",
|
||||
"message": "選擇影片畫質:",
|
||||
"detail": "目前畫質:{{quality}}",
|
||||
"message": "選擇影片畫質:",
|
||||
"title": "選擇影片畫質"
|
||||
}
|
||||
}
|
||||
@ -624,7 +694,7 @@
|
||||
"play-pause": "播放/暫停",
|
||||
"previous": "上一首"
|
||||
},
|
||||
"label": "選擇全域音樂控制快捷鍵:",
|
||||
"label": "選擇全域音樂控制快捷鍵:",
|
||||
"title": "全域快捷鍵"
|
||||
}
|
||||
}
|
||||
@ -641,8 +711,61 @@
|
||||
"description": "自動跳過贊助片段",
|
||||
"name": "贊助阻擋"
|
||||
},
|
||||
"synced-lyrics": {
|
||||
"description": "使用 LRClib 等管道提供歌詞同步顯示。",
|
||||
"errors": {
|
||||
"fetch": "⚠️擷取歌詞時發生錯誤。請稍後再試。",
|
||||
"not-found": "⚠️未找到該首歌曲的歌詞。"
|
||||
},
|
||||
"menu": {
|
||||
"default-text-string": {
|
||||
"label": "預設歌詞中間隔的符號",
|
||||
"tooltip": "選擇歌詞中間隔要使用的符號"
|
||||
},
|
||||
"line-effect": {
|
||||
"label": "歌詞顯示效果",
|
||||
"submenu": {
|
||||
"focus": {
|
||||
"label": "高亮",
|
||||
"tooltip": "高亮當前的歌詞"
|
||||
},
|
||||
"offset": {
|
||||
"label": "凸行",
|
||||
"tooltip": "凸行當前的歌詞"
|
||||
},
|
||||
"scale": {
|
||||
"label": "放大",
|
||||
"tooltip": "放大當前的歌詞"
|
||||
}
|
||||
},
|
||||
"tooltip": "選擇要使用的歌詞顯示效果"
|
||||
},
|
||||
"precise-timing": {
|
||||
"label": "使歌詞完美同步",
|
||||
"tooltip": "更精確的計算下一行歌詞的顯示(將會降低些許效能)"
|
||||
},
|
||||
"show-lyrics-even-if-inexact": {
|
||||
"label": "即使不精確依然強制顯示歌詞",
|
||||
"tooltip": "當找不到符合該歌曲的歌詞時,該功能會嘗試不同的搜尋方式。\n使用不同的搜尋方式會導致不精確的結果。"
|
||||
},
|
||||
"show-time-codes": {
|
||||
"label": "顯示時間線",
|
||||
"tooltip": "在歌詞旁顯示時間線"
|
||||
}
|
||||
},
|
||||
"name": "歌詞同步",
|
||||
"refetch-btn": {
|
||||
"fetching": "擷取中...",
|
||||
"normal": "重新擷取歌詞"
|
||||
},
|
||||
"warnings": {
|
||||
"duration-mismatch": "⚠️歌詞可能會出現不同步的情況。",
|
||||
"inexact": "⚠️該歌曲的歌詞可能並不精確",
|
||||
"instrumental": "⚠️該首歌曲並無人聲"
|
||||
}
|
||||
},
|
||||
"taskbar-mediacontrol": {
|
||||
"description": "透過工作列應用程式圖式控制媒體播放",
|
||||
"description": "允許工作列應用程式預覽介面顯示媒體控制相關按鈕",
|
||||
"name": "工作列媒體控制"
|
||||
},
|
||||
"touchbar": {
|
||||
|
||||
119
src/index.ts
119
src/index.ts
@ -11,6 +11,8 @@ import {
|
||||
shell,
|
||||
dialog,
|
||||
ipcMain,
|
||||
protocol,
|
||||
type BrowserWindowConstructorOptions,
|
||||
} from 'electron';
|
||||
import enhanceWebRequest, {
|
||||
BetterSession,
|
||||
@ -82,6 +84,34 @@ if (!gotTheLock) {
|
||||
app.exit();
|
||||
}
|
||||
|
||||
protocol.registerSchemesAsPrivileged([
|
||||
{
|
||||
scheme: 'http',
|
||||
privileges: {
|
||||
standard: true,
|
||||
bypassCSP: true,
|
||||
allowServiceWorkers: true,
|
||||
supportFetchAPI: true,
|
||||
corsEnabled: true,
|
||||
stream: true,
|
||||
codeCache: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
scheme: 'https',
|
||||
privileges: {
|
||||
standard: true,
|
||||
bypassCSP: true,
|
||||
allowServiceWorkers: true,
|
||||
supportFetchAPI: true,
|
||||
corsEnabled: true,
|
||||
stream: true,
|
||||
codeCache: true,
|
||||
},
|
||||
},
|
||||
{ scheme: 'mailto', privileges: { standard: true } },
|
||||
]);
|
||||
|
||||
// Ozone platform hint: Required for Wayland support
|
||||
app.commandLine.appendSwitch('ozone-platform-hint', 'auto');
|
||||
// SharedArrayBuffer: Required for downloader (@ffmpeg/core-mt)
|
||||
@ -100,9 +130,18 @@ if (config.get('options.disableHardwareAcceleration')) {
|
||||
app.disableHardwareAcceleration();
|
||||
}
|
||||
|
||||
if (is.linux() && config.plugins.isEnabled('shortcuts')) {
|
||||
if (is.linux()) {
|
||||
const disabledFeatures = [
|
||||
// Workaround for issue #2248
|
||||
'UseMultiPlaneFormatForSoftwareVideo',
|
||||
];
|
||||
|
||||
// Stops chromium from launching its own MPRIS service
|
||||
app.commandLine.appendSwitch('disable-features', 'MediaSessionService');
|
||||
if (config.plugins.isEnabled('shortcuts')) {
|
||||
disabledFeatures.push('MediaSessionService');
|
||||
}
|
||||
|
||||
app.commandLine.appendSwitch('disable-features', disabledFeatures.join());
|
||||
}
|
||||
|
||||
if (config.get('options.proxy')) {
|
||||
@ -277,6 +316,23 @@ async function createMainWindow() {
|
||||
height: 32,
|
||||
};
|
||||
|
||||
const decorations: Partial<BrowserWindowConstructorOptions> = {
|
||||
frame: !is.macOS() && !useInlineMenu,
|
||||
titleBarOverlay: defaultTitleBarOverlayOptions,
|
||||
titleBarStyle: useInlineMenu
|
||||
? 'hidden'
|
||||
: is.macOS()
|
||||
? 'hiddenInset'
|
||||
: 'default',
|
||||
autoHideMenuBar: config.get('options.hideMenu'),
|
||||
};
|
||||
|
||||
// Note: on linux, for some weird reason, having these extra properties with 'frame: false' does not work
|
||||
if (is.linux() && useInlineMenu) {
|
||||
delete decorations.titleBarOverlay;
|
||||
delete decorations.titleBarStyle;
|
||||
}
|
||||
|
||||
const win = new BrowserWindow({
|
||||
icon,
|
||||
width: windowSize.width,
|
||||
@ -294,14 +350,7 @@ async function createMainWindow() {
|
||||
sandbox: false,
|
||||
}),
|
||||
},
|
||||
frame: !is.macOS() && !useInlineMenu,
|
||||
titleBarOverlay: defaultTitleBarOverlayOptions,
|
||||
titleBarStyle: useInlineMenu
|
||||
? 'hidden'
|
||||
: is.macOS()
|
||||
? 'hiddenInset'
|
||||
: 'default',
|
||||
autoHideMenuBar: config.get('options.hideMenu'),
|
||||
...decorations,
|
||||
});
|
||||
initHook(win);
|
||||
initTheme(win);
|
||||
@ -312,28 +361,31 @@ async function createMainWindow() {
|
||||
const { x: windowX, y: windowY } = windowPosition;
|
||||
const winSize = win.getSize();
|
||||
const display = screen.getDisplayNearestPoint(windowPosition);
|
||||
const scaleFactor = is.windows() ? display.scaleFactor: 1;
|
||||
const primaryDisplay = screen.getPrimaryDisplay();
|
||||
|
||||
const scaledWidth = Math.floor(windowSize.width / scaleFactor);
|
||||
const scaledHeight = Math.floor(windowSize.height / scaleFactor);
|
||||
const scaleFactor = is.windows()
|
||||
? primaryDisplay.scaleFactor / display.scaleFactor
|
||||
: 1;
|
||||
const scaledWidth = Math.floor(windowSize.width * scaleFactor);
|
||||
const scaledHeight = Math.floor(windowSize.height * scaleFactor);
|
||||
|
||||
const scaledX = windowX;
|
||||
const scaledY = windowY;
|
||||
|
||||
if (
|
||||
scaledX + scaledWidth < display.bounds.x - 8 ||
|
||||
scaledX - scaledWidth > display.bounds.x + display.bounds.width ||
|
||||
scaledY < display.bounds.y - 8 ||
|
||||
scaledY > display.bounds.y + display.bounds.height
|
||||
scaledX + scaledWidth / 2 < display.bounds.x - 8 || // Left
|
||||
scaledX + scaledWidth / 2 > display.bounds.x + display.bounds.width || // Right
|
||||
scaledY < display.bounds.y - 8 || // Top
|
||||
scaledY + scaledHeight / 2 > display.bounds.y + display.bounds.height // Bottom
|
||||
) {
|
||||
// Window is offscreen
|
||||
if (is.dev()) {
|
||||
console.warn(
|
||||
LoggerPrefix,
|
||||
t('main.console.window.tried-to-render-offscreen', {
|
||||
winSize: String(winSize),
|
||||
displaySize: String(display.bounds),
|
||||
windowPosition: String(windowPosition),
|
||||
windowSize: String(winSize),
|
||||
displaySize: JSON.stringify(display.bounds),
|
||||
position: JSON.stringify(windowPosition),
|
||||
}),
|
||||
);
|
||||
}
|
||||
@ -421,7 +473,7 @@ async function createMainWindow() {
|
||||
...defaultTitleBarOverlayOptions,
|
||||
height: Math.floor(
|
||||
defaultTitleBarOverlayOptions.height! *
|
||||
win.webContents.getZoomFactor(),
|
||||
win.webContents.getZoomFactor(),
|
||||
),
|
||||
});
|
||||
}
|
||||
@ -434,7 +486,7 @@ async function createMainWindow() {
|
||||
event.preventDefault();
|
||||
|
||||
win.webContents.loadURL(
|
||||
'https://accounts.google.com/ServiceLogin?ltmpl=music&service=youtube&continue=https%3A%2F%2Fwww.youtube.com%2Fsignin%3Faction_handle_signin%3Dtrue%26next%3Dhttps%253A%252F%252Fmusic.youtube.com%252F'
|
||||
'https://accounts.google.com/ServiceLogin?ltmpl=music&service=youtube&continue=https%3A%2F%2Fwww.youtube.com%2Fsignin%3Faction_handle_signin%3Dtrue%26next%3Dhttps%253A%252F%252Fmusic.youtube.com%252F',
|
||||
);
|
||||
}
|
||||
});
|
||||
@ -458,8 +510,8 @@ app.once('browser-window-created', (_event, win) => {
|
||||
const updatedUserAgent = is.macOS()
|
||||
? userAgents.mac
|
||||
: is.windows()
|
||||
? userAgents.windows
|
||||
: userAgents.linux;
|
||||
? userAgents.windows
|
||||
: userAgents.linux;
|
||||
|
||||
win.webContents.userAgent = updatedUserAgent;
|
||||
app.userAgentFallback = updatedUserAgent;
|
||||
@ -508,7 +560,11 @@ app.once('browser-window-created', (_event, win) => {
|
||||
console.log(log);
|
||||
}
|
||||
|
||||
if (errorCode !== -3) {
|
||||
if (
|
||||
errorCode !== -3 &&
|
||||
// Workaround for #2435
|
||||
!new URL(validatedURL).hostname.includes('doubleclick.net')
|
||||
) {
|
||||
// -3 is a false positive
|
||||
win.webContents.send('log', log);
|
||||
win.webContents.loadFile(ErrorHtmlAsset);
|
||||
@ -597,6 +653,7 @@ app.whenReady().then(async () => {
|
||||
shortcutDetails.target !== appLocation ||
|
||||
shortcutDetails.appUserModelId !== appID
|
||||
) {
|
||||
// eslint-disable-next-line @typescript-eslint/only-throw-error
|
||||
throw 'needUpdate';
|
||||
}
|
||||
} catch (error) {
|
||||
@ -620,7 +677,9 @@ app.whenReady().then(async () => {
|
||||
// In dev mode, get string from process.env.VITE_DEV_SERVER_URL, else use fs.readFileSync
|
||||
if (is.dev() && process.env.ELECTRON_RENDERER_URL) {
|
||||
// HACK: to make vite work with electron renderer (supports hot reload)
|
||||
event.returnValue = [null, `
|
||||
event.returnValue = [
|
||||
null,
|
||||
`
|
||||
console.log('${LoggerPrefix}', 'Loading vite from dev server');
|
||||
(async () => {
|
||||
await new Promise((resolve) => {
|
||||
@ -641,7 +700,8 @@ app.whenReady().then(async () => {
|
||||
document.body.appendChild(rendererScript);
|
||||
})();
|
||||
0
|
||||
`];
|
||||
`,
|
||||
];
|
||||
} else {
|
||||
const rendererPath = path.join(__dirname, '..', 'renderer');
|
||||
const indexHTML = parse(
|
||||
@ -653,7 +713,10 @@ app.whenReady().then(async () => {
|
||||
scriptSrc.getAttribute('src')!,
|
||||
);
|
||||
const scriptString = fs.readFileSync(scriptPath, 'utf-8');
|
||||
event.returnValue = [url.pathToFileURL(scriptPath).toString(), scriptString + ';0'];
|
||||
event.returnValue = [
|
||||
url.pathToFileURL(scriptPath).toString(),
|
||||
scriptString + ';0',
|
||||
];
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@ -34,11 +34,12 @@ const createContext = (
|
||||
win.webContents.send(event, ...args);
|
||||
},
|
||||
handle: (event: string, listener: CallableFunction) => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-return,@typescript-eslint/no-unsafe-call
|
||||
ipcMain.handle(event, (_, ...args: unknown[]) => listener(...args));
|
||||
},
|
||||
on: (event: string, listener: CallableFunction) => {
|
||||
ipcMain.on(event, (_, ...args: unknown[]) => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
||||
listener(...args);
|
||||
});
|
||||
},
|
||||
@ -75,11 +76,11 @@ export const forceUnloadMainPlugin = async (
|
||||
);
|
||||
return;
|
||||
} else {
|
||||
console.log(
|
||||
LoggerPrefix,
|
||||
t('common.console.plugins.unload-failed', { pluginName: id }),
|
||||
);
|
||||
return Promise.reject();
|
||||
const message = t('common.console.plugins.unload-failed', {
|
||||
pluginName: id,
|
||||
});
|
||||
console.log(LoggerPrefix, message);
|
||||
return Promise.reject(new Error(message));
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(
|
||||
@ -87,7 +88,7 @@ export const forceUnloadMainPlugin = async (
|
||||
t('common.console.plugins.unload-failed', { pluginName: id }),
|
||||
);
|
||||
console.trace(err);
|
||||
return Promise.reject(err);
|
||||
return Promise.reject(err as Error);
|
||||
}
|
||||
};
|
||||
|
||||
@ -111,11 +112,11 @@ export const forceLoadMainPlugin = async (
|
||||
) {
|
||||
loadedPluginMap[id] = plugin;
|
||||
} else {
|
||||
console.log(
|
||||
LoggerPrefix,
|
||||
t('common.console.plugins.load-failed', { pluginName: id }),
|
||||
);
|
||||
return Promise.reject();
|
||||
const message = t('common.console.plugins.load-failed', {
|
||||
pluginName: id,
|
||||
});
|
||||
console.log(LoggerPrefix, message);
|
||||
return Promise.reject(new Error(message));
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(
|
||||
@ -123,7 +124,7 @@ export const forceLoadMainPlugin = async (
|
||||
t('common.console.plugins.initialize-failed', { pluginName: id }),
|
||||
);
|
||||
console.trace(err);
|
||||
return Promise.reject(err);
|
||||
return Promise.reject(err as Error);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -18,7 +18,8 @@ const loadedPluginMap: Record<
|
||||
export const createContext = <Config extends PluginConfig>(
|
||||
id: string,
|
||||
): RendererContext<Config> => ({
|
||||
getConfig: async () => window.ipcRenderer.invoke('ytmd:get-config', id),
|
||||
getConfig: async () =>
|
||||
window.ipcRenderer.invoke('ytmd:get-config', id) as Promise<Config>,
|
||||
setConfig: async (newConfig) => {
|
||||
await window.ipcRenderer.invoke('ytmd:set-config', id, newConfig);
|
||||
},
|
||||
@ -30,6 +31,7 @@ export const createContext = <Config extends PluginConfig>(
|
||||
window.ipcRenderer.invoke(event, ...args),
|
||||
on: (event: string, listener: CallableFunction) => {
|
||||
window.ipcRenderer.on(event, (_, ...args: unknown[]) => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
||||
listener(...args);
|
||||
});
|
||||
},
|
||||
|
||||
79
src/menu.ts
79
src/menu.ts
@ -76,12 +76,21 @@ export const mainMenuTemplate = async (
|
||||
const plugin = allPlugins[id];
|
||||
const pluginLabel = plugin?.name?.() ?? id;
|
||||
const pluginDescription = plugin?.description?.() ?? undefined;
|
||||
const isNew = plugin?.addedVersion ? satisfies(packageJson.version, plugin.addedVersion) : false;
|
||||
const isNew = plugin?.addedVersion
|
||||
? satisfies(packageJson.version, plugin.addedVersion)
|
||||
: false;
|
||||
|
||||
if (!config.plugins.isEnabled(id)) {
|
||||
return [
|
||||
id,
|
||||
pluginEnabledMenu(id, pluginLabel, pluginDescription, isNew, true, innerRefreshMenu),
|
||||
pluginEnabledMenu(
|
||||
id,
|
||||
pluginLabel,
|
||||
pluginDescription,
|
||||
isNew,
|
||||
true,
|
||||
innerRefreshMenu,
|
||||
),
|
||||
] as const;
|
||||
}
|
||||
|
||||
@ -123,9 +132,18 @@ export const mainMenuTemplate = async (
|
||||
const plugin = allPlugins[id];
|
||||
const pluginLabel = plugin?.name?.() ?? id;
|
||||
const pluginDescription = plugin?.description?.() ?? undefined;
|
||||
const isNew = plugin?.addedVersion ? satisfies(packageJson.version, plugin.addedVersion) : false;
|
||||
const isNew = plugin?.addedVersion
|
||||
? satisfies(packageJson.version, plugin.addedVersion)
|
||||
: false;
|
||||
|
||||
return pluginEnabledMenu(id, pluginLabel, pluginDescription, isNew, true, innerRefreshMenu);
|
||||
return pluginEnabledMenu(
|
||||
id,
|
||||
pluginLabel,
|
||||
pluginDescription,
|
||||
isNew,
|
||||
true,
|
||||
innerRefreshMenu,
|
||||
);
|
||||
});
|
||||
|
||||
const availableLanguages = Object.keys(languageResources);
|
||||
@ -235,16 +253,50 @@ export const mainMenuTemplate = async (
|
||||
'main.menu.options.submenu.visual-tweaks.submenu.theme.label',
|
||||
),
|
||||
submenu: [
|
||||
{
|
||||
label: t(
|
||||
'main.menu.options.submenu.visual-tweaks.submenu.theme.submenu.no-theme',
|
||||
),
|
||||
type: 'radio',
|
||||
checked: config.get('options.themes')?.length === 0, // Todo rename "themes"
|
||||
click() {
|
||||
config.set('options.themes', []);
|
||||
...((config.get('options.themes')?.length ?? 0) === 0
|
||||
? [
|
||||
{
|
||||
label: t(
|
||||
'main.menu.options.submenu.visual-tweaks.submenu.theme.submenu.no-theme',
|
||||
),
|
||||
},
|
||||
]
|
||||
: []),
|
||||
...(config.get('options.themes')?.map((theme: string) => ({
|
||||
type: 'normal' as const,
|
||||
label: theme,
|
||||
async click() {
|
||||
const { response } = await dialog.showMessageBox(win, {
|
||||
type: 'question',
|
||||
defaultId: 1,
|
||||
title: t(
|
||||
'main.menu.options.submenu.visual-tweaks.submenu.theme.dialog.remove-theme',
|
||||
),
|
||||
message: t(
|
||||
'main.menu.options.submenu.visual-tweaks.submenu.theme.dialog.remove-theme-message',
|
||||
{ theme },
|
||||
),
|
||||
buttons: [
|
||||
t(
|
||||
'main.menu.options.submenu.visual-tweaks.submenu.theme.dialog.button.cancel',
|
||||
),
|
||||
t(
|
||||
'main.menu.options.submenu.visual-tweaks.submenu.theme.dialog.button.remove',
|
||||
),
|
||||
],
|
||||
});
|
||||
|
||||
if (response === 1) {
|
||||
config.set(
|
||||
'options.themes',
|
||||
config
|
||||
.get('options.themes')
|
||||
?.filter((t) => t !== theme) ?? [],
|
||||
);
|
||||
innerRefreshMenu();
|
||||
}
|
||||
},
|
||||
},
|
||||
})) ?? []),
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: t(
|
||||
@ -258,6 +310,7 @@ export const mainMenuTemplate = async (
|
||||
});
|
||||
if (filePaths) {
|
||||
config.set('options.themes', filePaths);
|
||||
innerRefreshMenu();
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
58
src/plugins/adblocker/adSpeedup.ts
Normal file
58
src/plugins/adblocker/adSpeedup.ts
Normal file
@ -0,0 +1,58 @@
|
||||
function skipAd(target: Element) {
|
||||
const skipButton = target.querySelector<HTMLButtonElement>(
|
||||
'button.ytp-ad-skip-button-modern',
|
||||
);
|
||||
if (skipButton) {
|
||||
skipButton.click();
|
||||
}
|
||||
}
|
||||
|
||||
function speedUpAndMute(player: Element, isAdShowing: boolean) {
|
||||
const video = player.querySelector<HTMLVideoElement>('video');
|
||||
if (!video) return;
|
||||
if (isAdShowing) {
|
||||
video.playbackRate = 16;
|
||||
video.muted = true;
|
||||
} else if (!isAdShowing) {
|
||||
video.playbackRate = 1;
|
||||
video.muted = false;
|
||||
}
|
||||
}
|
||||
|
||||
export const loadAdSpeedup = () => {
|
||||
const player = document.querySelector<HTMLVideoElement>('#movie_player');
|
||||
if (!player) return;
|
||||
|
||||
new MutationObserver((mutations) => {
|
||||
for (const mutation of mutations) {
|
||||
if (
|
||||
mutation.type === 'attributes' &&
|
||||
mutation.attributeName === 'class'
|
||||
) {
|
||||
const target = mutation.target as HTMLElement;
|
||||
|
||||
const isAdShowing =
|
||||
target.classList.contains('ad-showing') ||
|
||||
target.classList.contains('ad-interrupting');
|
||||
speedUpAndMute(target, isAdShowing);
|
||||
}
|
||||
if (
|
||||
mutation.type === 'childList' &&
|
||||
mutation.addedNodes.length &&
|
||||
mutation.target instanceof HTMLElement
|
||||
) {
|
||||
skipAd(mutation.target);
|
||||
}
|
||||
}
|
||||
}).observe(player, {
|
||||
attributes: true,
|
||||
childList: true,
|
||||
subtree: true,
|
||||
});
|
||||
|
||||
const isAdShowing =
|
||||
player.classList.contains('ad-showing') ||
|
||||
player.classList.contains('ad-interrupting');
|
||||
speedUpAndMute(player, isAdShowing);
|
||||
skipAd(player);
|
||||
};
|
||||
@ -8,13 +8,17 @@ import { app, net } from 'electron';
|
||||
const SOURCES = [
|
||||
'https://raw.githubusercontent.com/kbinani/adblock-youtube-ads/master/signed.txt',
|
||||
// UBlock Origin
|
||||
'https://raw.githubusercontent.com/uBlockOrigin/uAssets/master/filters/filters.txt',
|
||||
'https://raw.githubusercontent.com/uBlockOrigin/uAssets/master/filters/filters-2020.txt',
|
||||
'https://raw.githubusercontent.com/uBlockOrigin/uAssets/master/filters/filters-2021.txt',
|
||||
'https://raw.githubusercontent.com/uBlockOrigin/uAssets/master/filters/filters-2022.txt',
|
||||
'https://raw.githubusercontent.com/uBlockOrigin/uAssets/master/filters/filters-2023.txt',
|
||||
'https://raw.githubusercontent.com/ghostery/adblocker/master/packages/adblocker/assets/ublock-origin/filters.txt',
|
||||
'https://raw.githubusercontent.com/ghostery/adblocker/master/packages/adblocker/assets/ublock-origin/quick-fixes.txt',
|
||||
'https://raw.githubusercontent.com/ghostery/adblocker/master/packages/adblocker/assets/ublock-origin/unbreak.txt',
|
||||
'https://raw.githubusercontent.com/ghostery/adblocker/master/packages/adblocker/assets/ublock-origin/filters-2020.txt',
|
||||
'https://raw.githubusercontent.com/ghostery/adblocker/master/packages/adblocker/assets/ublock-origin/filters-2021.txt',
|
||||
'https://raw.githubusercontent.com/ghostery/adblocker/master/packages/adblocker/assets/ublock-origin/filters-2022.txt',
|
||||
'https://raw.githubusercontent.com/ghostery/adblocker/master/packages/adblocker/assets/ublock-origin/filters-2023.txt',
|
||||
// Fanboy Annoyances
|
||||
'https://secure.fanboy.co.nz/fanboy-annoyance_ubo.txt',
|
||||
// AdGuard
|
||||
'https://filters.adtidy.org/extension/ublock/filters/122_optimized.txt',
|
||||
];
|
||||
|
||||
let blocker: ElectronBlocker | undefined;
|
||||
|
||||
@ -10,6 +10,7 @@ import {
|
||||
|
||||
import injectCliqzPreload from './injectors/inject-cliqz-preload';
|
||||
import { inject, isInjected } from './injectors/inject';
|
||||
import { loadAdSpeedup } from './adSpeedup';
|
||||
|
||||
import { t } from '@/i18n';
|
||||
|
||||
@ -72,6 +73,14 @@ export default createPlugin({
|
||||
},
|
||||
];
|
||||
},
|
||||
renderer: {
|
||||
async onPlayerApiReady(_, { getConfig }) {
|
||||
const config = await getConfig();
|
||||
if (config.blocker === blockers.AdSpeedup) {
|
||||
await loadAdSpeedup();
|
||||
}
|
||||
},
|
||||
},
|
||||
backend: {
|
||||
mainWindow: null as BrowserWindow | null,
|
||||
async start({ getConfig, window }) {
|
||||
@ -109,7 +118,19 @@ export default createPlugin({
|
||||
},
|
||||
},
|
||||
preload: {
|
||||
script: 'window.JSON.parse = window._proxyJsonParse; window._proxyJsonParse = undefined; window.Response.prototype.json = window._proxyResponseJson; window._proxyResponseJson = undefined; 0',
|
||||
// see #1478
|
||||
script: `const _prunerFn = window._pruner;
|
||||
window._pruner = undefined;
|
||||
JSON.parse = new Proxy(JSON.parse, {
|
||||
apply() {
|
||||
return _prunerFn(Reflect.apply(...arguments));
|
||||
},
|
||||
});
|
||||
Response.prototype.json = new Proxy(Response.prototype.json, {
|
||||
apply() {
|
||||
return Reflect.apply(...arguments).then((o) => _prunerFn(o));
|
||||
},
|
||||
}); 0`,
|
||||
async start({ getConfig }) {
|
||||
const config = await getConfig();
|
||||
|
||||
|
||||
@ -22,32 +22,46 @@ export const inject = (contextBridge) => {
|
||||
const pruner = function (o) {
|
||||
delete o.playerAds;
|
||||
delete o.adPlacements;
|
||||
delete o.adSlots;
|
||||
//
|
||||
if (o.playerResponse) {
|
||||
delete o.playerResponse.playerAds;
|
||||
delete o.playerResponse.adPlacements;
|
||||
delete o.playerResponse.adSlots;
|
||||
}
|
||||
if (o.ytInitialPlayerResponse) {
|
||||
delete o.ytInitialPlayerResponse.playerAds;
|
||||
delete o.ytInitialPlayerResponse.adPlacements;
|
||||
delete o.ytInitialPlayerResponse.adSlots;
|
||||
}
|
||||
|
||||
//
|
||||
return o;
|
||||
};
|
||||
}
|
||||
|
||||
contextBridge.exposeInMainWorld('_proxyJsonParse', new Proxy(JSON.parse, {
|
||||
apply() {
|
||||
return pruner(Reflect.apply(...arguments));
|
||||
},
|
||||
}));
|
||||
|
||||
contextBridge.exposeInMainWorld('_proxyResponseJson', new Proxy(Response.prototype.json, {
|
||||
apply() {
|
||||
return Reflect.apply(...arguments).then((o) => pruner(o));
|
||||
},
|
||||
}));
|
||||
contextBridge.exposeInMainWorld('_pruner', pruner);
|
||||
}
|
||||
|
||||
(function () {
|
||||
let cValue = 'undefined';
|
||||
const chain = 'playerResponse.adPlacements';
|
||||
const chains = [
|
||||
{
|
||||
chain: 'playerResponse.adPlacements',
|
||||
cValue: 'undefined',
|
||||
},
|
||||
{
|
||||
chain: 'ytInitialPlayerResponse.playerAds',
|
||||
cValue: 'undefined',
|
||||
},
|
||||
{
|
||||
chain: 'ytInitialPlayerResponse.adPlacements',
|
||||
cValue: 'undefined',
|
||||
},
|
||||
{
|
||||
chain: 'ytInitialPlayerResponse.adSlots',
|
||||
cValue: 'undefined',
|
||||
}
|
||||
];
|
||||
|
||||
chains.forEach(function ({ chain, cValue }) {
|
||||
const thisScript = document.currentScript;
|
||||
//
|
||||
switch (cValue) {
|
||||
@ -241,203 +255,5 @@ export const inject = (contextBridge) => {
|
||||
|
||||
//
|
||||
trapChain(window, chain);
|
||||
})();
|
||||
|
||||
(function () {
|
||||
let cValue = 'undefined';
|
||||
const thisScript = document.currentScript;
|
||||
const chain = 'ytInitialPlayerResponse.adPlacements';
|
||||
//
|
||||
switch (cValue) {
|
||||
case 'null': {
|
||||
cValue = null;
|
||||
break;
|
||||
}
|
||||
|
||||
case "''": {
|
||||
cValue = '';
|
||||
break;
|
||||
}
|
||||
|
||||
case 'true': {
|
||||
cValue = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case 'false': {
|
||||
cValue = false;
|
||||
break;
|
||||
}
|
||||
|
||||
case 'undefined': {
|
||||
cValue = undefined;
|
||||
break;
|
||||
}
|
||||
|
||||
case 'noopFunc': {
|
||||
cValue = function () {};
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'trueFunc': {
|
||||
cValue = function () {
|
||||
return true;
|
||||
};
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'falseFunc': {
|
||||
cValue = function () {
|
||||
return false;
|
||||
};
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
if (/^\d+$/.test(cValue)) {
|
||||
cValue = Number.parseFloat(cValue);
|
||||
//
|
||||
if (isNaN(cValue)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (Math.abs(cValue) > 0x7f_ff) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
let aborted = false;
|
||||
const mustAbort = function (v) {
|
||||
if (aborted) {
|
||||
return true;
|
||||
}
|
||||
|
||||
aborted =
|
||||
v !== undefined &&
|
||||
v !== null &&
|
||||
cValue !== undefined &&
|
||||
cValue !== null &&
|
||||
typeof v !== typeof cValue;
|
||||
return aborted;
|
||||
};
|
||||
|
||||
/*
|
||||
Support multiple trappers for the same property:
|
||||
https://github.com/uBlockOrigin/uBlock-issues/issues/156
|
||||
*/
|
||||
|
||||
const trapProp = function (owner, prop, configurable, handler) {
|
||||
if (handler.init(owner[prop]) === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
const odesc = Object.getOwnPropertyDescriptor(owner, prop);
|
||||
let previousGetter;
|
||||
let previousSetter;
|
||||
if (odesc instanceof Object) {
|
||||
if (odesc.configurable === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (odesc.get instanceof Function) {
|
||||
previousGetter = odesc.get;
|
||||
}
|
||||
|
||||
if (odesc.set instanceof Function) {
|
||||
previousSetter = odesc.set;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
Object.defineProperty(owner, prop, {
|
||||
configurable,
|
||||
get() {
|
||||
if (previousGetter !== undefined) {
|
||||
previousGetter();
|
||||
}
|
||||
|
||||
//
|
||||
return handler.getter();
|
||||
},
|
||||
set(a) {
|
||||
if (previousSetter !== undefined) {
|
||||
previousSetter(a);
|
||||
}
|
||||
|
||||
//
|
||||
handler.setter(a);
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const trapChain = function (owner, chain) {
|
||||
const pos = chain.indexOf('.');
|
||||
if (pos === -1) {
|
||||
trapProp(owner, chain, false, {
|
||||
v: undefined,
|
||||
getter() {
|
||||
return document.currentScript === thisScript ? this.v : cValue;
|
||||
},
|
||||
setter(a) {
|
||||
if (mustAbort(a) === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
cValue = a;
|
||||
},
|
||||
init(v) {
|
||||
if (mustAbort(v)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
this.v = v;
|
||||
return true;
|
||||
},
|
||||
});
|
||||
//
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
const prop = chain.slice(0, pos);
|
||||
const v = owner[prop];
|
||||
//
|
||||
chain = chain.slice(pos + 1);
|
||||
if (v instanceof Object || (typeof v === 'object' && v !== null)) {
|
||||
trapChain(v, chain);
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
trapProp(owner, prop, true, {
|
||||
v: undefined,
|
||||
getter() {
|
||||
return this.v;
|
||||
},
|
||||
setter(a) {
|
||||
this.v = a;
|
||||
if (a instanceof Object) {
|
||||
trapChain(a, chain);
|
||||
}
|
||||
},
|
||||
init(v) {
|
||||
this.v = v;
|
||||
return true;
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
//
|
||||
trapChain(window, chain);
|
||||
})();
|
||||
});
|
||||
};
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
export const blockers = {
|
||||
WithBlocklists: 'With blocklists',
|
||||
InPlayer: 'In player',
|
||||
AdSpeedup: 'Ad speedup',
|
||||
} as const;
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import { t } from '@/i18n';
|
||||
import { createPlugin } from '@/utils';
|
||||
import { ElementFromHtml } from '@/plugins/utils/renderer';
|
||||
import { waitForElement } from '@/utils/wait-for-element';
|
||||
|
||||
import undislikeHTML from './templates/undislike.html?raw';
|
||||
import dislikeHTML from './templates/dislike.html?raw';
|
||||
@ -16,7 +17,6 @@ export default createPlugin<
|
||||
changeObserver?: MutationObserver;
|
||||
waiting: boolean;
|
||||
onPageChange(): void;
|
||||
waitForElem(selector: string): Promise<HTMLElement>;
|
||||
loadFullList: (event: MouseEvent) => void;
|
||||
applyToList(id: string, loader: HTMLElement): void;
|
||||
start(): void;
|
||||
@ -50,7 +50,7 @@ export default createPlugin<
|
||||
} else {
|
||||
this.waiting = true;
|
||||
}
|
||||
const continuations = await this.waitForElem('#continuations');
|
||||
const continuations = await waitForElement<HTMLElement>('#continuations');
|
||||
this.waiting = false;
|
||||
//Gets the for buttons
|
||||
const buttons: Array<HTMLElement> = [
|
||||
@ -104,16 +104,28 @@ export default createPlugin<
|
||||
buttons.splice(i, 1);
|
||||
i--;
|
||||
} else {
|
||||
(buttons[i].children[0].children[0] as HTMLElement).style.setProperty(
|
||||
(
|
||||
buttons[i].children[0].children[0] as HTMLElement
|
||||
).style.setProperty(
|
||||
'-webkit-mask-size',
|
||||
`100% ${100 - ((count / listsLength) * 100)}%`,
|
||||
`100% ${100 - (count / listsLength) * 100}%`,
|
||||
);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
const menu = document.querySelector('.detail-page-menu');
|
||||
if (menu && !document.querySelector('.like-menu')) {
|
||||
const menuParent =
|
||||
document.querySelector('#action-buttons')?.parentElement;
|
||||
if (menuParent && !document.querySelector('.like-menu')) {
|
||||
const menu = document.createElement('div');
|
||||
menu.id = 'ytmd-album-action-buttons';
|
||||
menu.className =
|
||||
'action-buttons style-scope ytmusic-responsive-header-renderer';
|
||||
|
||||
menuParent.insertBefore(
|
||||
menu,
|
||||
menuParent.children[menuParent.children.length - 1],
|
||||
);
|
||||
for (const button of buttons) {
|
||||
menu.appendChild(button);
|
||||
button.addEventListener('click', this.loadFullList);
|
||||
@ -178,16 +190,5 @@ export default createPlugin<
|
||||
button.remove();
|
||||
}
|
||||
},
|
||||
waitForElem(selector: string) {
|
||||
return new Promise((resolve) => {
|
||||
const interval = setInterval(() => {
|
||||
const elem = document.querySelector<HTMLElement>(selector);
|
||||
if (!elem) return;
|
||||
|
||||
clearInterval(interval);
|
||||
resolve(elem);
|
||||
});
|
||||
});
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@ -1,40 +1,58 @@
|
||||
<button
|
||||
id="alldislike"
|
||||
data-type="dislike"
|
||||
data-filled="false"
|
||||
class="like-menu yt-spec-button-shape-next yt-spec-button-shape-next--text yt-spec-button-shape-next--mono yt-spec-button-shape-next--size-m yt-spec-button-shape-next--icon-button"
|
||||
aria-pressed="false"
|
||||
aria-label="Dislike all"
|
||||
>
|
||||
<div
|
||||
class="yt-spec-button-shape-next__icon"
|
||||
style="color: var(--ytmusic-setting-item-toggle-active)"
|
||||
aria-hidden="true"
|
||||
<div class="style-scope">
|
||||
<button
|
||||
id="alldislike"
|
||||
data-type="dislike"
|
||||
data-filled="false"
|
||||
class="like-menu yt-spec-button-shape-next yt-spec-button-shape-next--text yt-spec-button-shape-next--mono yt-spec-button-shape-next--size-m yt-spec-button-shape-next--icon-button"
|
||||
aria-pressed="false"
|
||||
aria-label="Dislike all"
|
||||
>
|
||||
<div
|
||||
class="yt-spec-button-shape-next__icon"
|
||||
style="
|
||||
color: white;
|
||||
-webkit-mask: linear-gradient(grey, grey);
|
||||
-webkit-mask-size: 100% 50%;
|
||||
-webkit-mask-repeat: no-repeat;
|
||||
z-index: 1;
|
||||
position: absolute;
|
||||
"
|
||||
style="color: var(--ytmusic-setting-item-toggle-active)"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<div
|
||||
class="yt-spec-button-shape-next__icon"
|
||||
style="
|
||||
color: white;
|
||||
-webkit-mask: linear-gradient(grey, grey);
|
||||
-webkit-mask-size: 100% 50%;
|
||||
-webkit-mask-repeat: no-repeat;
|
||||
z-index: 1;
|
||||
position: absolute;
|
||||
"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<div style="width: 24px; height: 24px">
|
||||
<svg
|
||||
viewBox="0 0 24 24"
|
||||
preserveAspectRatio="xMidYMid meet"
|
||||
focusable="false"
|
||||
class="style-scope yt-icon"
|
||||
style="
|
||||
pointer-events: none;
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
"
|
||||
>
|
||||
<g class="style-scope yt-icon">
|
||||
<path
|
||||
d="M18,4h3v10h-3V4z M5.23,14h4.23l-1.52,4.94C7.62,19.97,8.46,21,9.62,21c0.58,0,1.14-0.24,1.52-0.65L17,14V4H6.57 C5.5,4,4.59,4.67,4.38,5.61l-1.34,6C2.77,12.85,3.82,14,5.23,14z"
|
||||
class="style-scope yt-icon"
|
||||
></path>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<div style="width: 24px; height: 24px">
|
||||
<svg
|
||||
viewBox="0 0 24 24"
|
||||
preserveAspectRatio="xMidYMid meet"
|
||||
focusable="false"
|
||||
class="style-scope yt-icon"
|
||||
style="
|
||||
pointer-events: none;
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
"
|
||||
style="pointer-events: none; display: block; width: 100%; height: 100%"
|
||||
>
|
||||
<g class="style-scope yt-icon">
|
||||
<path
|
||||
@ -45,30 +63,14 @@
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<div style="width: 24px; height: 24px">
|
||||
<svg
|
||||
viewBox="0 0 24 24"
|
||||
preserveAspectRatio="xMidYMid meet"
|
||||
focusable="false"
|
||||
class="style-scope yt-icon"
|
||||
style="pointer-events: none; display: block; width: 100%; height: 100%"
|
||||
<yt-touch-feedback-shape style="border-radius: inherit">
|
||||
<div
|
||||
class="yt-spec-touch-feedback-shape yt-spec-touch-feedback-shape--touch-response"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<g class="style-scope yt-icon">
|
||||
<path
|
||||
d="M18,4h3v10h-3V4z M5.23,14h4.23l-1.52,4.94C7.62,19.97,8.46,21,9.62,21c0.58,0,1.14-0.24,1.52-0.65L17,14V4H6.57 C5.5,4,4.59,4.67,4.38,5.61l-1.34,6C2.77,12.85,3.82,14,5.23,14z"
|
||||
class="style-scope yt-icon"
|
||||
></path>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<yt-touch-feedback-shape style="border-radius: inherit">
|
||||
<div
|
||||
class="yt-spec-touch-feedback-shape yt-spec-touch-feedback-shape--touch-response"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<div class="yt-spec-touch-feedback-shape__stroke"></div>
|
||||
<div class="yt-spec-touch-feedback-shape__fill"></div>
|
||||
</div>
|
||||
</yt-touch-feedback-shape>
|
||||
</button>
|
||||
<div class="yt-spec-touch-feedback-shape__stroke"></div>
|
||||
<div class="yt-spec-touch-feedback-shape__fill"></div>
|
||||
</div>
|
||||
</yt-touch-feedback-shape>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@ -1,40 +1,58 @@
|
||||
<button
|
||||
id="alllike"
|
||||
data-type="like"
|
||||
data-filled="false"
|
||||
class="like-menu yt-spec-button-shape-next yt-spec-button-shape-next--text yt-spec-button-shape-next--mono yt-spec-button-shape-next--size-m yt-spec-button-shape-next--icon-button"
|
||||
aria-pressed="false"
|
||||
aria-label="Like all"
|
||||
>
|
||||
<div
|
||||
class="yt-spec-button-shape-next__icon"
|
||||
style="color: var(--ytmusic-setting-item-toggle-active)"
|
||||
aria-hidden="true"
|
||||
<div class="style-scope">
|
||||
<button
|
||||
id="alllike"
|
||||
data-type="like"
|
||||
data-filled="false"
|
||||
class="like-menu yt-spec-button-shape-next yt-spec-button-shape-next--text yt-spec-button-shape-next--mono yt-spec-button-shape-next--size-m yt-spec-button-shape-next--icon-button"
|
||||
aria-pressed="false"
|
||||
aria-label="Like all"
|
||||
>
|
||||
<div
|
||||
class="yt-spec-button-shape-next__icon"
|
||||
style="
|
||||
color: white;
|
||||
-webkit-mask: linear-gradient(grey, grey);
|
||||
-webkit-mask-size: 100% 50%;
|
||||
-webkit-mask-repeat: no-repeat;
|
||||
z-index: 1;
|
||||
position: absolute;
|
||||
"
|
||||
style="color: var(--ytmusic-setting-item-toggle-active)"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<div
|
||||
class="yt-spec-button-shape-next__icon"
|
||||
style="
|
||||
color: white;
|
||||
-webkit-mask: linear-gradient(grey, grey);
|
||||
-webkit-mask-size: 100% 50%;
|
||||
-webkit-mask-repeat: no-repeat;
|
||||
z-index: 1;
|
||||
position: absolute;
|
||||
"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<div style="width: 24px; height: 24px">
|
||||
<svg
|
||||
viewBox="0 0 24 24"
|
||||
preserveAspectRatio="xMidYMid meet"
|
||||
focusable="false"
|
||||
class="style-scope yt-icon"
|
||||
style="
|
||||
pointer-events: none;
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
"
|
||||
>
|
||||
<g class="style-scope yt-icon">
|
||||
<path
|
||||
d="M3,11h3v10H3V11z M18.77,11h-4.23l1.52-4.94C16.38,5.03,15.54,4,14.38,4c-0.58,0-1.14,0.24-1.52,0.65L7,11v10h10.43 c1.06,0,1.98-0.67,2.19-1.61l1.34-6C21.23,12.15,20.18,11,18.77,11z"
|
||||
class="style-scope yt-icon"
|
||||
></path>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<div style="width: 24px; height: 24px">
|
||||
<svg
|
||||
viewBox="0 0 24 24"
|
||||
preserveAspectRatio="xMidYMid meet"
|
||||
focusable="false"
|
||||
class="style-scope yt-icon"
|
||||
style="
|
||||
pointer-events: none;
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
"
|
||||
style="pointer-events: none; display: block; width: 100%; height: 100%"
|
||||
>
|
||||
<g class="style-scope yt-icon">
|
||||
<path
|
||||
@ -45,30 +63,14 @@
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<div style="width: 24px; height: 24px">
|
||||
<svg
|
||||
viewBox="0 0 24 24"
|
||||
preserveAspectRatio="xMidYMid meet"
|
||||
focusable="false"
|
||||
class="style-scope yt-icon"
|
||||
style="pointer-events: none; display: block; width: 100%; height: 100%"
|
||||
<yt-touch-feedback-shape style="border-radius: inherit">
|
||||
<div
|
||||
class="yt-spec-touch-feedback-shape yt-spec-touch-feedback-shape--touch-response"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<g class="style-scope yt-icon">
|
||||
<path
|
||||
d="M3,11h3v10H3V11z M18.77,11h-4.23l1.52-4.94C16.38,5.03,15.54,4,14.38,4c-0.58,0-1.14,0.24-1.52,0.65L7,11v10h10.43 c1.06,0,1.98-0.67,2.19-1.61l1.34-6C21.23,12.15,20.18,11,18.77,11z"
|
||||
class="style-scope yt-icon"
|
||||
></path>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<yt-touch-feedback-shape style="border-radius: inherit">
|
||||
<div
|
||||
class="yt-spec-touch-feedback-shape yt-spec-touch-feedback-shape--touch-response"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<div class="yt-spec-touch-feedback-shape__stroke"></div>
|
||||
<div class="yt-spec-touch-feedback-shape__fill"></div>
|
||||
</div>
|
||||
</yt-touch-feedback-shape>
|
||||
</button>
|
||||
<div class="yt-spec-touch-feedback-shape__stroke"></div>
|
||||
<div class="yt-spec-touch-feedback-shape__fill"></div>
|
||||
</div>
|
||||
</yt-touch-feedback-shape>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@ -1,40 +1,58 @@
|
||||
<button
|
||||
id="allundislike"
|
||||
data-type="dislike"
|
||||
data-filled="true"
|
||||
class="like-menu yt-spec-button-shape-next yt-spec-button-shape-next--text yt-spec-button-shape-next--mono yt-spec-button-shape-next--size-m yt-spec-button-shape-next--icon-button"
|
||||
aria-pressed="false"
|
||||
aria-label="Undislike all"
|
||||
>
|
||||
<div
|
||||
class="yt-spec-button-shape-next__icon"
|
||||
style="color: var(--ytmusic-setting-item-toggle-active)"
|
||||
aria-hidden="true"
|
||||
<div class="style-scope">
|
||||
<button
|
||||
id="allundislike"
|
||||
data-type="dislike"
|
||||
data-filled="true"
|
||||
class="like-menu yt-spec-button-shape-next yt-spec-button-shape-next--text yt-spec-button-shape-next--mono yt-spec-button-shape-next--size-m yt-spec-button-shape-next--icon-button"
|
||||
aria-pressed="false"
|
||||
aria-label="Undislike all"
|
||||
>
|
||||
<div
|
||||
class="yt-spec-button-shape-next__icon"
|
||||
style="
|
||||
color: white;
|
||||
-webkit-mask: linear-gradient(grey, grey);
|
||||
-webkit-mask-size: 100% 50%;
|
||||
-webkit-mask-repeat: no-repeat;
|
||||
z-index: 1;
|
||||
position: absolute;
|
||||
"
|
||||
style="color: var(--ytmusic-setting-item-toggle-active)"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<div
|
||||
class="yt-spec-button-shape-next__icon"
|
||||
style="
|
||||
color: white;
|
||||
-webkit-mask: linear-gradient(grey, grey);
|
||||
-webkit-mask-size: 100% 50%;
|
||||
-webkit-mask-repeat: no-repeat;
|
||||
z-index: 1;
|
||||
position: absolute;
|
||||
"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<div style="width: 24px; height: 24px">
|
||||
<svg
|
||||
viewBox="0 0 24 24"
|
||||
preserveAspectRatio="xMidYMid meet"
|
||||
focusable="false"
|
||||
class="style-scope yt-icon"
|
||||
style="
|
||||
pointer-events: none;
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
"
|
||||
>
|
||||
<g class="style-scope yt-icon">
|
||||
<path
|
||||
d="M17,4h-1H6.57C5.5,4,4.59,4.67,4.38,5.61l-1.34,6C2.77,12.85,3.82,14,5.23,14h4.23l-1.52,4.94C7.62,19.97,8.46,21,9.62,21 c0.58,0,1.14-0.24,1.52-0.65L17,14h4V4H17z M10.4,19.67C10.21,19.88,9.92,20,9.62,20c-0.26,0-0.5-0.11-0.63-0.3 c-0.07-0.1-0.15-0.26-0.09-0.47l1.52-4.94l0.4-1.29H9.46H5.23c-0.41,0-0.8-0.17-1.03-0.46c-0.12-0.15-0.25-0.4-0.18-0.72l1.34-6 C5.46,5.35,5.97,5,6.57,5H16v8.61L10.4,19.67z M20,13h-3V5h3V13z"
|
||||
class="style-scope yt-icon"
|
||||
></path>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<div style="width: 24px; height: 24px">
|
||||
<svg
|
||||
viewBox="0 0 24 24"
|
||||
preserveAspectRatio="xMidYMid meet"
|
||||
focusable="false"
|
||||
class="style-scope yt-icon"
|
||||
style="
|
||||
pointer-events: none;
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
"
|
||||
style="pointer-events: none; display: block; width: 100%; height: 100%"
|
||||
>
|
||||
<g class="style-scope yt-icon">
|
||||
<path
|
||||
@ -45,30 +63,14 @@
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<div style="width: 24px; height: 24px">
|
||||
<svg
|
||||
viewBox="0 0 24 24"
|
||||
preserveAspectRatio="xMidYMid meet"
|
||||
focusable="false"
|
||||
class="style-scope yt-icon"
|
||||
style="pointer-events: none; display: block; width: 100%; height: 100%"
|
||||
<yt-touch-feedback-shape style="border-radius: inherit">
|
||||
<div
|
||||
class="yt-spec-touch-feedback-shape yt-spec-touch-feedback-shape--touch-response"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<g class="style-scope yt-icon">
|
||||
<path
|
||||
d="M17,4h-1H6.57C5.5,4,4.59,4.67,4.38,5.61l-1.34,6C2.77,12.85,3.82,14,5.23,14h4.23l-1.52,4.94C7.62,19.97,8.46,21,9.62,21 c0.58,0,1.14-0.24,1.52-0.65L17,14h4V4H17z M10.4,19.67C10.21,19.88,9.92,20,9.62,20c-0.26,0-0.5-0.11-0.63-0.3 c-0.07-0.1-0.15-0.26-0.09-0.47l1.52-4.94l0.4-1.29H9.46H5.23c-0.41,0-0.8-0.17-1.03-0.46c-0.12-0.15-0.25-0.4-0.18-0.72l1.34-6 C5.46,5.35,5.97,5,6.57,5H16v8.61L10.4,19.67z M20,13h-3V5h3V13z"
|
||||
class="style-scope yt-icon"
|
||||
></path>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<yt-touch-feedback-shape style="border-radius: inherit">
|
||||
<div
|
||||
class="yt-spec-touch-feedback-shape yt-spec-touch-feedback-shape--touch-response"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<div class="yt-spec-touch-feedback-shape__stroke"></div>
|
||||
<div class="yt-spec-touch-feedback-shape__fill"></div>
|
||||
</div>
|
||||
</yt-touch-feedback-shape>
|
||||
</button>
|
||||
<div class="yt-spec-touch-feedback-shape__stroke"></div>
|
||||
<div class="yt-spec-touch-feedback-shape__fill"></div>
|
||||
</div>
|
||||
</yt-touch-feedback-shape>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@ -1,40 +1,58 @@
|
||||
<button
|
||||
id="allunlike"
|
||||
data-type="like"
|
||||
data-filled="true"
|
||||
class="like-menu yt-spec-button-shape-next yt-spec-button-shape-next--text yt-spec-button-shape-next--mono yt-spec-button-shape-next--size-m yt-spec-button-shape-next--icon-button"
|
||||
aria-pressed="false"
|
||||
aria-label="Unlike all"
|
||||
>
|
||||
<div
|
||||
class="yt-spec-button-shape-next__icon"
|
||||
style="color: var(--ytmusic-setting-item-toggle-active)"
|
||||
aria-hidden="true"
|
||||
<div class="style-scope">
|
||||
<button
|
||||
id="allunlike"
|
||||
data-type="like"
|
||||
data-filled="true"
|
||||
class="like-menu yt-spec-button-shape-next yt-spec-button-shape-next--text yt-spec-button-shape-next--mono yt-spec-button-shape-next--size-m yt-spec-button-shape-next--icon-button"
|
||||
aria-pressed="false"
|
||||
aria-label="Unlike all"
|
||||
>
|
||||
<div
|
||||
class="yt-spec-button-shape-next__icon"
|
||||
style="
|
||||
color: white;
|
||||
-webkit-mask: linear-gradient(grey, grey);
|
||||
-webkit-mask-size: 100% 50%;
|
||||
-webkit-mask-repeat: no-repeat;
|
||||
z-index: 1;
|
||||
position: absolute;
|
||||
"
|
||||
style="color: var(--ytmusic-setting-item-toggle-active)"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<div
|
||||
class="yt-spec-button-shape-next__icon"
|
||||
style="
|
||||
color: white;
|
||||
-webkit-mask: linear-gradient(grey, grey);
|
||||
-webkit-mask-size: 100% 50%;
|
||||
-webkit-mask-repeat: no-repeat;
|
||||
z-index: 1;
|
||||
position: absolute;
|
||||
"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<div style="width: 24px; height: 24px">
|
||||
<svg
|
||||
viewBox="0 0 24 24"
|
||||
preserveAspectRatio="xMidYMid meet"
|
||||
focusable="false"
|
||||
class="style-scope yt-icon"
|
||||
style="
|
||||
pointer-events: none;
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
"
|
||||
>
|
||||
<g class="style-scope yt-icon">
|
||||
<path
|
||||
d="M18.77,11h-4.23l1.52-4.94C16.38,5.03,15.54,4,14.38,4c-0.58,0-1.14,0.24-1.52,0.65L7,11H3v10h4h1h9.43 c1.06,0,1.98-0.67,2.19-1.61l1.34-6C21.23,12.15,20.18,11,18.77,11z M7,20H4v-8h3V20z M19.98,13.17l-1.34,6 C18.54,19.65,18.03,20,17.43,20H8v-8.61l5.6-6.06C13.79,5.12,14.08,5,14.38,5c0.26,0,0.5,0.11,0.63,0.3 c0.07,0.1,0.15,0.26,0.09,0.47l-1.52,4.94L13.18,12h1.35h4.23c0.41,0,0.8,0.17,1.03,0.46C19.92,12.61,20.05,12.86,19.98,13.17z"
|
||||
class="style-scope yt-icon"
|
||||
></path>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<div style="width: 24px; height: 24px">
|
||||
<svg
|
||||
viewBox="0 0 24 24"
|
||||
preserveAspectRatio="xMidYMid meet"
|
||||
focusable="false"
|
||||
class="style-scope yt-icon"
|
||||
style="
|
||||
pointer-events: none;
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
"
|
||||
style="pointer-events: none; display: block; width: 100%; height: 100%"
|
||||
>
|
||||
<g class="style-scope yt-icon">
|
||||
<path
|
||||
@ -45,30 +63,14 @@
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<div style="width: 24px; height: 24px">
|
||||
<svg
|
||||
viewBox="0 0 24 24"
|
||||
preserveAspectRatio="xMidYMid meet"
|
||||
focusable="false"
|
||||
class="style-scope yt-icon"
|
||||
style="pointer-events: none; display: block; width: 100%; height: 100%"
|
||||
<yt-touch-feedback-shape style="border-radius: inherit">
|
||||
<div
|
||||
class="yt-spec-touch-feedback-shape yt-spec-touch-feedback-shape--touch-response"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<g class="style-scope yt-icon">
|
||||
<path
|
||||
d="M18.77,11h-4.23l1.52-4.94C16.38,5.03,15.54,4,14.38,4c-0.58,0-1.14,0.24-1.52,0.65L7,11H3v10h4h1h9.43 c1.06,0,1.98-0.67,2.19-1.61l1.34-6C21.23,12.15,20.18,11,18.77,11z M7,20H4v-8h3V20z M19.98,13.17l-1.34,6 C18.54,19.65,18.03,20,17.43,20H8v-8.61l5.6-6.06C13.79,5.12,14.08,5,14.38,5c0.26,0,0.5,0.11,0.63,0.3 c0.07,0.1,0.15,0.26,0.09,0.47l-1.52,4.94L13.18,12h1.35h4.23c0.41,0,0.8,0.17,1.03,0.46C19.92,12.61,20.05,12.86,19.98,13.17z"
|
||||
class="style-scope yt-icon"
|
||||
></path>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<yt-touch-feedback-shape style="border-radius: inherit">
|
||||
<div
|
||||
class="yt-spec-touch-feedback-shape yt-spec-touch-feedback-shape--touch-response"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<div class="yt-spec-touch-feedback-shape__stroke"></div>
|
||||
<div class="yt-spec-touch-feedback-shape__fill"></div>
|
||||
</div>
|
||||
</yt-touch-feedback-shape>
|
||||
</button>
|
||||
<div class="yt-spec-touch-feedback-shape__stroke"></div>
|
||||
<div class="yt-spec-touch-feedback-shape__fill"></div>
|
||||
</div>
|
||||
</yt-touch-feedback-shape>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@ -25,7 +25,12 @@ export default createPlugin<
|
||||
sidebarSmall: HTMLElement | null;
|
||||
ytmusicAppLayout: HTMLElement | null;
|
||||
|
||||
getMixedColor(color: string, key: string, alpha?: number, ratioMultiply?: number): string;
|
||||
getMixedColor(
|
||||
color: string,
|
||||
key: string,
|
||||
alpha?: number,
|
||||
ratioMultiply?: number,
|
||||
): string;
|
||||
updateColor(): void;
|
||||
},
|
||||
{
|
||||
@ -91,7 +96,10 @@ export default createPlugin<
|
||||
this.ytmusicAppLayout = document.querySelector<HTMLElement>('#layout');
|
||||
|
||||
const config = await getConfig();
|
||||
document.documentElement.style.setProperty(RATIO_KEY, `${~~(config.ratio * 100)}%`);
|
||||
document.documentElement.style.setProperty(
|
||||
RATIO_KEY,
|
||||
`${~~(config.ratio * 100)}%`,
|
||||
);
|
||||
},
|
||||
onPlayerApiReady(playerApi) {
|
||||
const fastAverageColor = new FastAverageColor();
|
||||
@ -100,10 +108,12 @@ export default createPlugin<
|
||||
if (event.detail.name !== 'dataloaded') return;
|
||||
|
||||
const playerResponse = playerApi.getPlayerResponse();
|
||||
const thumbnail = playerResponse?.videoDetails?.thumbnail?.thumbnails?.at(0);
|
||||
const thumbnail =
|
||||
playerResponse?.videoDetails?.thumbnail?.thumbnails?.at(0);
|
||||
if (!thumbnail) return;
|
||||
|
||||
const albumColor = await fastAverageColor.getColorAsync(thumbnail.url)
|
||||
const albumColor = await fastAverageColor
|
||||
.getColorAsync(thumbnail.url)
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
return null;
|
||||
@ -120,8 +130,14 @@ export default createPlugin<
|
||||
this.darkColor = this.darkColor?.darken(0.05);
|
||||
}
|
||||
|
||||
document.documentElement.style.setProperty(COLOR_KEY, `${~~this.color.red()}, ${~~this.color.green()}, ${~~this.color.blue()}`);
|
||||
document.documentElement.style.setProperty(DARK_COLOR_KEY, `${~~this.darkColor.red()}, ${~~this.darkColor.green()}, ${~~this.darkColor.blue()}`);
|
||||
document.documentElement.style.setProperty(
|
||||
COLOR_KEY,
|
||||
`${~~this.color.red()}, ${~~this.color.green()}, ${~~this.color.blue()}`,
|
||||
);
|
||||
document.documentElement.style.setProperty(
|
||||
DARK_COLOR_KEY,
|
||||
`${~~this.darkColor.red()}, ${~~this.darkColor.green()}, ${~~this.darkColor.blue()}`,
|
||||
);
|
||||
} else {
|
||||
document.documentElement.style.setProperty(COLOR_KEY, '0, 0, 0');
|
||||
document.documentElement.style.setProperty(DARK_COLOR_KEY, '0, 0, 0');
|
||||
@ -131,7 +147,10 @@ export default createPlugin<
|
||||
});
|
||||
},
|
||||
onConfigChange(config) {
|
||||
document.documentElement.style.setProperty(RATIO_KEY, `${~~(config.ratio * 100)}%`);
|
||||
document.documentElement.style.setProperty(
|
||||
RATIO_KEY,
|
||||
`${~~(config.ratio * 100)}%`,
|
||||
);
|
||||
},
|
||||
getMixedColor(color: string, key: string, alpha = 1, ratioMultiply) {
|
||||
const keyColor = `rgba(var(${key}), ${alpha})`;
|
||||
@ -181,11 +200,23 @@ export default createPlugin<
|
||||
'--yt-spec-black-1-alpha-95': 'rgba(40,40,40,0.95)',
|
||||
};
|
||||
Object.entries(variableMap).map(([variable, color]) => {
|
||||
document.documentElement.style.setProperty(variable, this.getMixedColor(color, COLOR_KEY), 'important');
|
||||
document.documentElement.style.setProperty(
|
||||
variable,
|
||||
this.getMixedColor(color, COLOR_KEY),
|
||||
'important',
|
||||
);
|
||||
});
|
||||
|
||||
document.body.style.setProperty('background', this.getMixedColor('#030303', COLOR_KEY), 'important');
|
||||
document.documentElement.style.setProperty('--ytmusic-background', this.getMixedColor('#030303', DARK_COLOR_KEY), 'important');
|
||||
document.body.style.setProperty(
|
||||
'background',
|
||||
this.getMixedColor('#030303', COLOR_KEY),
|
||||
'important',
|
||||
);
|
||||
document.documentElement.style.setProperty(
|
||||
'--ytmusic-background',
|
||||
this.getMixedColor('#030303', DARK_COLOR_KEY),
|
||||
'important',
|
||||
);
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@ -30,7 +30,7 @@ yt-page-navigation-progress {
|
||||
|
||||
/* fix blur navigation bar */
|
||||
|
||||
ytmusic-app-layout > [slot="player-page"]:not([is-mweb-modernization-enabled]) {
|
||||
ytmusic-app-layout > [slot="player-page"]:not([is-mweb-modernization-enabled]):not(:has(ytmusic-player[player-ui-state=FULLSCREEN])) {
|
||||
padding-top: 90px;
|
||||
margin-top: calc(-90px + var(--menu-bar-height, 0px)) !important;
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@ import { t } from '@/i18n';
|
||||
import { createPlugin } from '@/utils';
|
||||
import { menu } from './menu';
|
||||
import { AmbientModePluginConfig } from './types';
|
||||
import { waitForElement } from '@/utils/wait-for-element';
|
||||
|
||||
const defaultConfig: AmbientModePluginConfig = {
|
||||
enabled: false,
|
||||
@ -36,7 +37,7 @@ export default createPlugin({
|
||||
unregister: null as (() => void) | null,
|
||||
update: null as (() => void) | null,
|
||||
interval: null as NodeJS.Timeout | null,
|
||||
lastMediaType: null as "video" | "image" | null,
|
||||
lastMediaType: null as 'video' | 'image' | null,
|
||||
lastVideoSource: null as string | null,
|
||||
lastImageSource: null as string | null,
|
||||
|
||||
@ -52,9 +53,16 @@ export default createPlugin({
|
||||
|
||||
const songImage = document.querySelector<HTMLImageElement>('#song-image');
|
||||
const songVideo = document.querySelector<HTMLDivElement>('#song-video');
|
||||
const image = songImage?.querySelector<HTMLImageElement>('yt-img-shadow > img');
|
||||
const video = songVideo?.querySelector<HTMLVideoElement>('.html5-video-container > video');
|
||||
const videoWrapper = document.querySelector('#song-video > .player-wrapper');
|
||||
const image = songImage?.querySelector<HTMLImageElement>(
|
||||
'yt-img-shadow > img',
|
||||
);
|
||||
const video = await waitForElement<HTMLVideoElement>(
|
||||
'.html5-video-container > video',
|
||||
);
|
||||
|
||||
const videoWrapper = document.querySelector(
|
||||
'#song-video > .player-wrapper',
|
||||
);
|
||||
|
||||
const injectBlurImage = () => {
|
||||
if (!songImage || !image) return null;
|
||||
@ -93,7 +101,9 @@ export default createPlugin({
|
||||
const blurCanvas = document.createElement('canvas');
|
||||
blurCanvas.classList.add('html5-blur-canvas');
|
||||
|
||||
const context = blurCanvas.getContext('2d', { willReadFrequently: true });
|
||||
const context = blurCanvas.getContext('2d', {
|
||||
willReadFrequently: true,
|
||||
});
|
||||
|
||||
/* effect */
|
||||
let lastEffectWorkId: number | null = null;
|
||||
@ -107,14 +117,18 @@ export default createPlugin({
|
||||
if (!context) return;
|
||||
|
||||
const width = this.qualityRatio;
|
||||
let height = Math.max(Math.floor((blurCanvas.height / blurCanvas.width) * width), 1,);
|
||||
let height = Math.max(
|
||||
Math.floor((blurCanvas.height / blurCanvas.width) * width),
|
||||
1,
|
||||
);
|
||||
if (!Number.isFinite(height)) height = width;
|
||||
if (!height) return;
|
||||
|
||||
context.globalAlpha = 1;
|
||||
if (lastImageData) {
|
||||
const frameOffset = (1 / this.buffer) * (1000 / this.interpolationTime);
|
||||
context.globalAlpha = 1 - (frameOffset * 2); // because of alpha value must be < 1
|
||||
const frameOffset =
|
||||
(1 / this.buffer) * (1000 / this.interpolationTime);
|
||||
context.globalAlpha = 1 - frameOffset * 2; // because of alpha value must be < 1
|
||||
context.putImageData(lastImageData, 0, 0);
|
||||
context.globalAlpha = frameOffset;
|
||||
}
|
||||
@ -135,7 +149,9 @@ export default createPlugin({
|
||||
if (newWidth === 0 || newHeight === 0) return;
|
||||
|
||||
blurCanvas.width = this.qualityRatio;
|
||||
blurCanvas.height = Math.floor((newHeight / newWidth) * this.qualityRatio);
|
||||
blurCanvas.height = Math.floor(
|
||||
(newHeight / newWidth) * this.qualityRatio,
|
||||
);
|
||||
|
||||
if (this.isFullscreen) blurCanvas.classList.add('fullscreen');
|
||||
else blurCanvas.classList.remove('fullscreen');
|
||||
@ -149,7 +165,10 @@ export default createPlugin({
|
||||
|
||||
/* hooking */
|
||||
let canvasInterval: NodeJS.Timeout | null = null;
|
||||
canvasInterval = setInterval(onSync, Math.max(1, Math.ceil(1000 / this.buffer)));
|
||||
canvasInterval = setInterval(
|
||||
onSync,
|
||||
Math.max(1, Math.ceil(1000 / this.buffer)),
|
||||
);
|
||||
|
||||
const onPause = () => {
|
||||
if (canvasInterval) clearInterval(canvasInterval);
|
||||
@ -157,7 +176,10 @@ export default createPlugin({
|
||||
};
|
||||
const onPlay = () => {
|
||||
if (canvasInterval) clearInterval(canvasInterval);
|
||||
canvasInterval = setInterval(onSync, Math.max(1, Math.ceil(1000 / this.buffer)));
|
||||
canvasInterval = setInterval(
|
||||
onSync,
|
||||
Math.max(1, Math.ceil(1000 / this.buffer)),
|
||||
);
|
||||
};
|
||||
songVideo.addEventListener('pause', onPause);
|
||||
songVideo.addEventListener('play', onPlay);
|
||||
@ -179,12 +201,12 @@ export default createPlugin({
|
||||
const isVideoMode = () => {
|
||||
const songVideo = document.querySelector<HTMLDivElement>('#song-video');
|
||||
if (!songVideo) {
|
||||
this.lastMediaType = "image";
|
||||
this.lastMediaType = 'image';
|
||||
return false;
|
||||
}
|
||||
|
||||
const isVideo = getComputedStyle(songVideo).display !== 'none';
|
||||
this.lastMediaType = isVideo ? "video" : "image";
|
||||
this.lastMediaType = isVideo ? 'video' : 'image';
|
||||
return isVideo;
|
||||
};
|
||||
|
||||
@ -196,16 +218,25 @@ export default createPlugin({
|
||||
if (isPageOpen) {
|
||||
const isVideo = isVideoMode();
|
||||
if (!force) {
|
||||
if (this.lastMediaType === "video" && this.lastVideoSource === video?.src) return false;
|
||||
if (this.lastMediaType === "image" && this.lastImageSource === image?.src) return false;
|
||||
if (
|
||||
this.lastMediaType === 'video' &&
|
||||
this.lastVideoSource === video?.src
|
||||
)
|
||||
return false;
|
||||
if (
|
||||
this.lastMediaType === 'image' &&
|
||||
this.lastImageSource === image?.src
|
||||
)
|
||||
return false;
|
||||
}
|
||||
this.unregister?.();
|
||||
this.unregister = (isVideo ? injectBlurVideo() : injectBlurImage()) ?? null;
|
||||
this.unregister =
|
||||
(isVideo ? injectBlurVideo() : injectBlurImage()) ?? null;
|
||||
} else {
|
||||
this.unregister?.();
|
||||
this.unregister = null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/* needed for switching between different views (e.g. miniplayer) */
|
||||
const observer = new MutationObserver((mutationsList) => {
|
||||
|
||||
@ -1,14 +1,24 @@
|
||||
import { t } from "@/i18n";
|
||||
import { MenuContext } from "@/types/contexts";
|
||||
import { MenuItemConstructorOptions } from "electron";
|
||||
import { AmbientModePluginConfig } from "./types";
|
||||
import { MenuItemConstructorOptions } from 'electron';
|
||||
|
||||
import { t } from '@/i18n';
|
||||
import { MenuContext } from '@/types/contexts';
|
||||
import { AmbientModePluginConfig } from './types';
|
||||
|
||||
export interface menuParameters {
|
||||
getConfig: () => AmbientModePluginConfig | Promise<AmbientModePluginConfig>;
|
||||
setConfig: (conf: Partial<Omit<AmbientModePluginConfig, "enabled">>) => void | Promise<void>;
|
||||
setConfig: (
|
||||
conf: Partial<Omit<AmbientModePluginConfig, 'enabled'>>,
|
||||
) => void | Promise<void>;
|
||||
}
|
||||
|
||||
export const menu: (ctx: MenuContext<AmbientModePluginConfig>) => MenuItemConstructorOptions[] | Promise<MenuItemConstructorOptions[]> = async ({ getConfig, setConfig }: menuParameters) => {
|
||||
export const menu: (
|
||||
ctx: MenuContext<AmbientModePluginConfig>,
|
||||
) =>
|
||||
| MenuItemConstructorOptions[]
|
||||
| Promise<MenuItemConstructorOptions[]> = async ({
|
||||
getConfig,
|
||||
setConfig,
|
||||
}: menuParameters) => {
|
||||
const interpolationTimeList = [0, 500, 1000, 1500, 2000, 3000, 4000, 5000];
|
||||
const qualityList = [10, 25, 50, 100, 200, 500, 1000];
|
||||
const sizeList = [100, 110, 125, 150, 175, 200, 300];
|
||||
@ -107,4 +117,4 @@ export const menu: (ctx: MenuContext<AmbientModePluginConfig>) => MenuItemConstr
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
};
|
||||
|
||||
@ -7,4 +7,4 @@ export type AmbientModePluginConfig = {
|
||||
size: number;
|
||||
opacity: number;
|
||||
fullscreen: boolean;
|
||||
};
|
||||
};
|
||||
|
||||
1
src/plugins/api-server/backend/index.ts
Normal file
1
src/plugins/api-server/backend/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from './main';
|
||||
121
src/plugins/api-server/backend/main.ts
Normal file
121
src/plugins/api-server/backend/main.ts
Normal file
@ -0,0 +1,121 @@
|
||||
import { jwt } from 'hono/jwt';
|
||||
import { OpenAPIHono as Hono } from '@hono/zod-openapi';
|
||||
import { cors } from 'hono/cors';
|
||||
import { swaggerUI } from '@hono/swagger-ui';
|
||||
import { serve } from '@hono/node-server';
|
||||
|
||||
import registerCallback from '@/providers/song-info';
|
||||
import { createBackend } from '@/utils';
|
||||
|
||||
import { JWTPayloadSchema } from './scheme';
|
||||
import { registerAuth, registerControl } from './routes';
|
||||
|
||||
import { type APIServerConfig, AuthStrategy } from '../config';
|
||||
|
||||
import type { BackendType } from './types';
|
||||
|
||||
export const backend = createBackend<BackendType, APIServerConfig>({
|
||||
async start(ctx) {
|
||||
const config = await ctx.getConfig();
|
||||
|
||||
await this.init(ctx);
|
||||
registerCallback((songInfo) => {
|
||||
this.songInfo = songInfo;
|
||||
});
|
||||
|
||||
this.run(config.hostname, config.port);
|
||||
},
|
||||
stop() {
|
||||
this.end();
|
||||
},
|
||||
onConfigChange(config) {
|
||||
if (
|
||||
this.oldConfig?.hostname === config.hostname &&
|
||||
this.oldConfig?.port === config.port
|
||||
) {
|
||||
this.oldConfig = config;
|
||||
return;
|
||||
}
|
||||
|
||||
this.end();
|
||||
this.run(config.hostname, config.port);
|
||||
this.oldConfig = config;
|
||||
},
|
||||
|
||||
// Custom
|
||||
async init(ctx) {
|
||||
const config = await ctx.getConfig();
|
||||
this.app = new Hono();
|
||||
|
||||
this.app.use('*', cors());
|
||||
|
||||
// middlewares
|
||||
this.app.use('/api/*', async (ctx, next) => {
|
||||
if (config.authStrategy !== AuthStrategy.NONE) {
|
||||
return await jwt({
|
||||
secret: config.secret,
|
||||
})(ctx, next);
|
||||
}
|
||||
await next();
|
||||
});
|
||||
this.app.use('/api/*', async (ctx, next) => {
|
||||
const result = await JWTPayloadSchema.spa(await ctx.get('jwtPayload'));
|
||||
|
||||
const isAuthorized =
|
||||
config.authStrategy === AuthStrategy.NONE ||
|
||||
(result.success && config.authorizedClients.includes(result.data.id));
|
||||
if (!isAuthorized) {
|
||||
ctx.status(401);
|
||||
return ctx.body('Unauthorized');
|
||||
}
|
||||
|
||||
return await next();
|
||||
});
|
||||
|
||||
// routes
|
||||
registerControl(this.app, ctx, () => this.songInfo);
|
||||
registerAuth(this.app, ctx);
|
||||
|
||||
// swagger
|
||||
this.app.openAPIRegistry.registerComponent(
|
||||
'securitySchemes',
|
||||
'bearerAuth',
|
||||
{
|
||||
type: 'http',
|
||||
scheme: 'bearer',
|
||||
bearerFormat: 'JWT',
|
||||
},
|
||||
);
|
||||
this.app.doc('/doc', {
|
||||
openapi: '3.1.0',
|
||||
info: {
|
||||
version: '1.0.0',
|
||||
title: 'Youtube Music API Server',
|
||||
},
|
||||
security: [
|
||||
{
|
||||
bearerAuth: [],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
this.app.get('/swagger', swaggerUI({ url: '/doc' }));
|
||||
},
|
||||
run(hostname, port) {
|
||||
if (!this.app) return;
|
||||
|
||||
try {
|
||||
this.server = serve({
|
||||
fetch: this.app.fetch.bind(this.app),
|
||||
port,
|
||||
hostname,
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
},
|
||||
end() {
|
||||
this.server?.close();
|
||||
this.server = undefined;
|
||||
},
|
||||
});
|
||||
95
src/plugins/api-server/backend/routes/auth.ts
Normal file
95
src/plugins/api-server/backend/routes/auth.ts
Normal file
@ -0,0 +1,95 @@
|
||||
import { createRoute, z } from '@hono/zod-openapi';
|
||||
import { dialog } from 'electron';
|
||||
import { sign } from 'hono/jwt';
|
||||
|
||||
import { getConnInfo } from '@hono/node-server/conninfo';
|
||||
|
||||
import { t } from '@/i18n';
|
||||
|
||||
import { type APIServerConfig, AuthStrategy } from '../../config';
|
||||
|
||||
import type { JWTPayload } from '../scheme';
|
||||
import type { HonoApp } from '../types';
|
||||
import type { BackendContext } from '@/types/contexts';
|
||||
|
||||
const routes = {
|
||||
request: createRoute({
|
||||
method: 'post',
|
||||
path: '/auth/{id}',
|
||||
summary: '',
|
||||
description: '',
|
||||
security: [],
|
||||
request: {
|
||||
params: z.object({
|
||||
id: z.string(),
|
||||
}),
|
||||
},
|
||||
responses: {
|
||||
200: {
|
||||
description: 'Success',
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: z.object({
|
||||
accessToken: z.string(),
|
||||
}),
|
||||
},
|
||||
},
|
||||
},
|
||||
403: {
|
||||
description: 'Forbidden',
|
||||
},
|
||||
},
|
||||
}),
|
||||
};
|
||||
|
||||
export const register = (
|
||||
app: HonoApp,
|
||||
{ getConfig, setConfig }: BackendContext<APIServerConfig>,
|
||||
) => {
|
||||
app.openapi(routes.request, async (ctx) => {
|
||||
const config = await getConfig();
|
||||
const { id } = ctx.req.param();
|
||||
|
||||
if (config.authorizedClients.includes(id)) {
|
||||
// SKIP CHECK
|
||||
} else if (config.authStrategy === AuthStrategy.AUTH_AT_FIRST) {
|
||||
const result = await dialog.showMessageBox({
|
||||
title: t('plugins.api-server.dialog.request.title'),
|
||||
message: t('plugins.api-server.dialog.request.message', {
|
||||
origin: getConnInfo(ctx).remote.address,
|
||||
ID: id,
|
||||
}),
|
||||
buttons: [
|
||||
t('plugins.api-server.dialog.request.buttons.allow'),
|
||||
t('plugins.api-server.dialog.request.buttons.deny'),
|
||||
],
|
||||
defaultId: 1,
|
||||
cancelId: 1,
|
||||
});
|
||||
|
||||
if (result.response === 1) {
|
||||
ctx.status(403);
|
||||
return ctx.body(null);
|
||||
}
|
||||
} else if (config.authStrategy === AuthStrategy.NONE) {
|
||||
// SKIP CHECK
|
||||
}
|
||||
|
||||
setConfig({
|
||||
authorizedClients: [...config.authorizedClients, id],
|
||||
});
|
||||
|
||||
const token = await sign(
|
||||
{
|
||||
id,
|
||||
iat: ~~(Date.now() / 1000),
|
||||
} satisfies JWTPayload,
|
||||
config.secret,
|
||||
);
|
||||
|
||||
ctx.status(200);
|
||||
return ctx.json({
|
||||
accessToken: token,
|
||||
});
|
||||
});
|
||||
};
|
||||
446
src/plugins/api-server/backend/routes/control.ts
Normal file
446
src/plugins/api-server/backend/routes/control.ts
Normal file
@ -0,0 +1,446 @@
|
||||
import { createRoute, z } from '@hono/zod-openapi';
|
||||
|
||||
import { ipcMain } from 'electron';
|
||||
|
||||
import getSongControls from '@/providers/song-controls';
|
||||
|
||||
import {
|
||||
AuthHeadersSchema,
|
||||
type ResponseSongInfo,
|
||||
SongInfoSchema,
|
||||
GoForwardScheme,
|
||||
GoBackSchema,
|
||||
SwitchRepeatSchema,
|
||||
SetVolumeSchema,
|
||||
SetFullscreenSchema,
|
||||
} from '../scheme';
|
||||
|
||||
import type { SongInfo } from '@/providers/song-info';
|
||||
import type { BackendContext } from '@/types/contexts';
|
||||
import type { APIServerConfig } from '../../config';
|
||||
import type { HonoApp } from '../types';
|
||||
import type { QueueResponse } from '@/types/youtube-music-desktop-internal';
|
||||
|
||||
const API_VERSION = 'v1';
|
||||
|
||||
const routes = {
|
||||
previous: createRoute({
|
||||
method: 'post',
|
||||
path: `/api/${API_VERSION}/previous`,
|
||||
summary: 'play previous song',
|
||||
description: 'Plays the previous song in the queue',
|
||||
responses: {
|
||||
204: {
|
||||
description: 'Success',
|
||||
},
|
||||
},
|
||||
}),
|
||||
next: createRoute({
|
||||
method: 'post',
|
||||
path: `/api/${API_VERSION}/next`,
|
||||
summary: 'play next song',
|
||||
description: 'Plays the next song in the queue',
|
||||
responses: {
|
||||
204: {
|
||||
description: 'Success',
|
||||
},
|
||||
},
|
||||
}),
|
||||
play: createRoute({
|
||||
method: 'post',
|
||||
path: `/api/${API_VERSION}/play`,
|
||||
summary: 'Play',
|
||||
description: 'Change the state of the player to play',
|
||||
responses: {
|
||||
204: {
|
||||
description: 'Success',
|
||||
},
|
||||
},
|
||||
}),
|
||||
pause: createRoute({
|
||||
method: 'post',
|
||||
path: `/api/${API_VERSION}/pause`,
|
||||
summary: 'Pause',
|
||||
description: 'Change the state of the player to pause',
|
||||
responses: {
|
||||
204: {
|
||||
description: 'Success',
|
||||
},
|
||||
},
|
||||
}),
|
||||
togglePlay: createRoute({
|
||||
method: 'post',
|
||||
path: `/api/${API_VERSION}/toggle-play`,
|
||||
summary: 'Toggle play/pause',
|
||||
description:
|
||||
'Change the state of the player to play if paused, or pause if playing',
|
||||
responses: {
|
||||
204: {
|
||||
description: 'Success',
|
||||
},
|
||||
},
|
||||
}),
|
||||
like: createRoute({
|
||||
method: 'post',
|
||||
path: `/api/${API_VERSION}/like`,
|
||||
summary: 'like song',
|
||||
description: 'Set the current song as liked',
|
||||
responses: {
|
||||
204: {
|
||||
description: 'Success',
|
||||
},
|
||||
},
|
||||
}),
|
||||
dislike: createRoute({
|
||||
method: 'post',
|
||||
path: `/api/${API_VERSION}/dislike`,
|
||||
summary: 'dislike song',
|
||||
description: 'Set the current song as disliked',
|
||||
responses: {
|
||||
204: {
|
||||
description: 'Success',
|
||||
},
|
||||
},
|
||||
}),
|
||||
|
||||
goBack: createRoute({
|
||||
method: 'post',
|
||||
path: `/api/${API_VERSION}/go-back`,
|
||||
summary: 'go back',
|
||||
description: 'Move the current song back by a number of seconds',
|
||||
request: {
|
||||
headers: AuthHeadersSchema,
|
||||
body: {
|
||||
description: 'seconds to go back',
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: GoBackSchema,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
responses: {
|
||||
204: {
|
||||
description: 'Success',
|
||||
},
|
||||
},
|
||||
}),
|
||||
|
||||
goForward: createRoute({
|
||||
method: 'post',
|
||||
path: `/api/${API_VERSION}/go-forward`,
|
||||
summary: 'go forward',
|
||||
description: 'Move the current song forward by a number of seconds',
|
||||
request: {
|
||||
headers: AuthHeadersSchema,
|
||||
body: {
|
||||
description: 'seconds to go forward',
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: GoForwardScheme,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
responses: {
|
||||
204: {
|
||||
description: 'Success',
|
||||
},
|
||||
},
|
||||
}),
|
||||
|
||||
shuffle: createRoute({
|
||||
method: 'post',
|
||||
path: `/api/${API_VERSION}/shuffle`,
|
||||
summary: 'shuffle',
|
||||
description: 'Shuffle the queue',
|
||||
responses: {
|
||||
204: {
|
||||
description: 'Success',
|
||||
},
|
||||
},
|
||||
}),
|
||||
switchRepeat: createRoute({
|
||||
method: 'post',
|
||||
path: `/api/${API_VERSION}/switch-repeat`,
|
||||
summary: 'switch repeat',
|
||||
description: 'Switch the repeat mode',
|
||||
request: {
|
||||
headers: AuthHeadersSchema,
|
||||
body: {
|
||||
description: 'number of times to click the repeat button',
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: SwitchRepeatSchema,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
responses: {
|
||||
204: {
|
||||
description: 'Success',
|
||||
},
|
||||
},
|
||||
}),
|
||||
setVolume: createRoute({
|
||||
method: 'post',
|
||||
path: `/api/${API_VERSION}/volume`,
|
||||
summary: 'set volume',
|
||||
description: 'Set the volume of the player',
|
||||
request: {
|
||||
headers: AuthHeadersSchema,
|
||||
body: {
|
||||
description: 'volume to set',
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: SetVolumeSchema,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
responses: {
|
||||
204: {
|
||||
description: 'Success',
|
||||
},
|
||||
},
|
||||
}),
|
||||
setFullscreen: createRoute({
|
||||
method: 'post',
|
||||
path: `/api/${API_VERSION}/fullscreen`,
|
||||
summary: 'set fullscreen',
|
||||
description: 'Set the fullscreen state of the player',
|
||||
request: {
|
||||
headers: AuthHeadersSchema,
|
||||
body: {
|
||||
description: 'fullscreen state',
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: SetFullscreenSchema,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
responses: {
|
||||
204: {
|
||||
description: 'Success',
|
||||
},
|
||||
},
|
||||
}),
|
||||
toggleMute: createRoute({
|
||||
method: 'post',
|
||||
path: `/api/${API_VERSION}/toggle-mute`,
|
||||
summary: 'toggle mute',
|
||||
description: 'Toggle the mute state of the player',
|
||||
responses: {
|
||||
204: {
|
||||
description: 'Success',
|
||||
},
|
||||
},
|
||||
}),
|
||||
|
||||
getFullscreenState: createRoute({
|
||||
method: 'get',
|
||||
path: `/api/${API_VERSION}/fullscreen`,
|
||||
summary: 'get fullscreen state',
|
||||
description: 'Get the current fullscreen state',
|
||||
responses: {
|
||||
200: {
|
||||
description: 'Success',
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: z.object({
|
||||
state: z.boolean(),
|
||||
}),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
queueInfo: createRoute({
|
||||
method: 'get',
|
||||
path: `/api/${API_VERSION}/queue-info`,
|
||||
summary: 'get current queue info',
|
||||
description: 'Get the current queue info',
|
||||
responses: {
|
||||
200: {
|
||||
description: 'Success',
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: z.object({}),
|
||||
},
|
||||
},
|
||||
},
|
||||
204: {
|
||||
description: 'No queue info',
|
||||
},
|
||||
},
|
||||
}),
|
||||
songInfo: createRoute({
|
||||
method: 'get',
|
||||
path: `/api/${API_VERSION}/song-info`,
|
||||
summary: 'get current song info',
|
||||
description: 'Get the current song info',
|
||||
responses: {
|
||||
200: {
|
||||
description: 'Success',
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: SongInfoSchema,
|
||||
},
|
||||
},
|
||||
},
|
||||
204: {
|
||||
description: 'No song info',
|
||||
},
|
||||
},
|
||||
}),
|
||||
};
|
||||
|
||||
export const register = (
|
||||
app: HonoApp,
|
||||
{ window }: BackendContext<APIServerConfig>,
|
||||
songInfoGetter: () => SongInfo | undefined,
|
||||
) => {
|
||||
const controller = getSongControls(window);
|
||||
|
||||
app.openapi(routes.previous, (ctx) => {
|
||||
controller.previous();
|
||||
|
||||
ctx.status(204);
|
||||
return ctx.body(null);
|
||||
});
|
||||
app.openapi(routes.next, (ctx) => {
|
||||
controller.next();
|
||||
|
||||
ctx.status(204);
|
||||
return ctx.body(null);
|
||||
});
|
||||
app.openapi(routes.play, (ctx) => {
|
||||
controller.play();
|
||||
|
||||
ctx.status(204);
|
||||
return ctx.body(null);
|
||||
});
|
||||
app.openapi(routes.pause, (ctx) => {
|
||||
controller.pause();
|
||||
|
||||
ctx.status(204);
|
||||
return ctx.body(null);
|
||||
});
|
||||
app.openapi(routes.togglePlay, (ctx) => {
|
||||
controller.playPause();
|
||||
|
||||
ctx.status(204);
|
||||
return ctx.body(null);
|
||||
});
|
||||
app.openapi(routes.like, (ctx) => {
|
||||
controller.like();
|
||||
|
||||
ctx.status(204);
|
||||
return ctx.body(null);
|
||||
});
|
||||
app.openapi(routes.dislike, (ctx) => {
|
||||
controller.dislike();
|
||||
|
||||
ctx.status(204);
|
||||
return ctx.body(null);
|
||||
});
|
||||
app.openapi(routes.goBack, (ctx) => {
|
||||
const { seconds } = ctx.req.valid('json');
|
||||
controller.goBack(seconds);
|
||||
|
||||
ctx.status(204);
|
||||
return ctx.body(null);
|
||||
});
|
||||
app.openapi(routes.goForward, (ctx) => {
|
||||
const { seconds } = ctx.req.valid('json');
|
||||
controller.goForward(seconds);
|
||||
|
||||
ctx.status(204);
|
||||
return ctx.body(null);
|
||||
});
|
||||
app.openapi(routes.shuffle, (ctx) => {
|
||||
controller.shuffle();
|
||||
|
||||
ctx.status(204);
|
||||
return ctx.body(null);
|
||||
});
|
||||
app.openapi(routes.switchRepeat, (ctx) => {
|
||||
const { iteration } = ctx.req.valid('json');
|
||||
controller.switchRepeat(iteration);
|
||||
|
||||
ctx.status(204);
|
||||
return ctx.body(null);
|
||||
});
|
||||
app.openapi(routes.setVolume, (ctx) => {
|
||||
const { volume } = ctx.req.valid('json');
|
||||
controller.setVolume(volume);
|
||||
|
||||
ctx.status(204);
|
||||
return ctx.body(null);
|
||||
});
|
||||
app.openapi(routes.setFullscreen, (ctx) => {
|
||||
const { state } = ctx.req.valid('json');
|
||||
controller.setFullscreen(state);
|
||||
|
||||
ctx.status(204);
|
||||
return ctx.body(null);
|
||||
});
|
||||
app.openapi(routes.toggleMute, (ctx) => {
|
||||
controller.muteUnmute();
|
||||
|
||||
ctx.status(204);
|
||||
return ctx.body(null);
|
||||
});
|
||||
|
||||
app.openapi(routes.getFullscreenState, async (ctx) => {
|
||||
const stateResponsePromise = new Promise<boolean>((resolve) => {
|
||||
ipcMain.once(
|
||||
'ytmd:set-fullscreen',
|
||||
(_, isFullscreen: boolean | undefined) => {
|
||||
return resolve(!!isFullscreen);
|
||||
},
|
||||
);
|
||||
|
||||
controller.requestFullscreenInformation();
|
||||
});
|
||||
|
||||
const fullscreen = await stateResponsePromise;
|
||||
|
||||
ctx.status(200);
|
||||
return ctx.json({ state: fullscreen });
|
||||
});
|
||||
app.openapi(routes.queueInfo, async (ctx) => {
|
||||
const queueResponsePromise = new Promise<QueueResponse>((resolve) => {
|
||||
ipcMain.once('ytmd:get-queue-response', (_, queue: QueueResponse) => {
|
||||
return resolve(queue);
|
||||
});
|
||||
|
||||
controller.requestQueueInformation();
|
||||
});
|
||||
|
||||
const info = await queueResponsePromise;
|
||||
|
||||
if (!info) {
|
||||
ctx.status(204);
|
||||
return ctx.body(null);
|
||||
}
|
||||
|
||||
ctx.status(200);
|
||||
return ctx.json(info);
|
||||
});
|
||||
app.openapi(routes.songInfo, (ctx) => {
|
||||
const info = songInfoGetter();
|
||||
|
||||
if (!info) {
|
||||
ctx.status(204);
|
||||
return ctx.body(null);
|
||||
}
|
||||
|
||||
const body = { ...info };
|
||||
delete body.image;
|
||||
|
||||
ctx.status(200);
|
||||
return ctx.json(body satisfies ResponseSongInfo);
|
||||
});
|
||||
};
|
||||
2
src/plugins/api-server/backend/routes/index.ts
Normal file
2
src/plugins/api-server/backend/routes/index.ts
Normal file
@ -0,0 +1,2 @@
|
||||
export { register as registerControl } from './control';
|
||||
export { register as registerAuth } from './auth';
|
||||
13
src/plugins/api-server/backend/scheme/auth.ts
Normal file
13
src/plugins/api-server/backend/scheme/auth.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import { z } from '@hono/zod-openapi';
|
||||
|
||||
export const AuthHeadersSchema = z.object({
|
||||
authorization: z.string().openapi({
|
||||
example: 'Bearer token',
|
||||
}),
|
||||
});
|
||||
|
||||
export type JWTPayload = z.infer<typeof JWTPayloadSchema>;
|
||||
export const JWTPayloadSchema = z.object({
|
||||
id: z.string(),
|
||||
iat: z.number(),
|
||||
});
|
||||
5
src/plugins/api-server/backend/scheme/go-back.ts
Normal file
5
src/plugins/api-server/backend/scheme/go-back.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import { z } from '@hono/zod-openapi';
|
||||
|
||||
export const GoBackSchema = z.object({
|
||||
seconds: z.number(),
|
||||
});
|
||||
5
src/plugins/api-server/backend/scheme/go-forward.ts
Normal file
5
src/plugins/api-server/backend/scheme/go-forward.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import { z } from '@hono/zod-openapi';
|
||||
|
||||
export const GoForwardScheme = z.object({
|
||||
seconds: z.number(),
|
||||
});
|
||||
7
src/plugins/api-server/backend/scheme/index.ts
Normal file
7
src/plugins/api-server/backend/scheme/index.ts
Normal file
@ -0,0 +1,7 @@
|
||||
export * from './auth';
|
||||
export * from './song-info';
|
||||
export * from './go-back';
|
||||
export * from './go-forward';
|
||||
export * from './switch-repeat';
|
||||
export * from './set-volume';
|
||||
export * from './set-fullscreen';
|
||||
5
src/plugins/api-server/backend/scheme/set-fullscreen.ts
Normal file
5
src/plugins/api-server/backend/scheme/set-fullscreen.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import { z } from '@hono/zod-openapi';
|
||||
|
||||
export const SetFullscreenSchema = z.object({
|
||||
state: z.boolean(),
|
||||
});
|
||||
5
src/plugins/api-server/backend/scheme/set-volume.ts
Normal file
5
src/plugins/api-server/backend/scheme/set-volume.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import { z } from '@hono/zod-openapi';
|
||||
|
||||
export const SetVolumeSchema = z.object({
|
||||
volume: z.number(),
|
||||
});
|
||||
26
src/plugins/api-server/backend/scheme/song-info.ts
Normal file
26
src/plugins/api-server/backend/scheme/song-info.ts
Normal file
@ -0,0 +1,26 @@
|
||||
import { z } from '@hono/zod-openapi';
|
||||
|
||||
import { MediaType } from '@/providers/song-info';
|
||||
|
||||
export type ResponseSongInfo = z.infer<typeof SongInfoSchema>;
|
||||
export const SongInfoSchema = z.object({
|
||||
title: z.string(),
|
||||
artist: z.string(),
|
||||
views: z.number(),
|
||||
uploadDate: z.string().optional(),
|
||||
imageSrc: z.string().nullable().optional(),
|
||||
isPaused: z.boolean().optional(),
|
||||
songDuration: z.number(),
|
||||
elapsedSeconds: z.number().optional(),
|
||||
url: z.string().optional(),
|
||||
album: z.string().nullable().optional(),
|
||||
videoId: z.string(),
|
||||
playlistId: z.string().optional(),
|
||||
mediaType: z.enum([
|
||||
MediaType.Audio,
|
||||
MediaType.OriginalMusicVideo,
|
||||
MediaType.UserGeneratedContent,
|
||||
MediaType.PodcastEpisode,
|
||||
MediaType.OtherVideo,
|
||||
]),
|
||||
});
|
||||
5
src/plugins/api-server/backend/scheme/switch-repeat.ts
Normal file
5
src/plugins/api-server/backend/scheme/switch-repeat.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import { z } from '@hono/zod-openapi';
|
||||
|
||||
export const SwitchRepeatSchema = z.object({
|
||||
iteration: z.number(),
|
||||
});
|
||||
18
src/plugins/api-server/backend/types.ts
Normal file
18
src/plugins/api-server/backend/types.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import { OpenAPIHono as Hono } from '@hono/zod-openapi';
|
||||
import { serve } from '@hono/node-server';
|
||||
|
||||
import type { BackendContext } from '@/types/contexts';
|
||||
import type { SongInfo } from '@/providers/song-info';
|
||||
import type { APIServerConfig } from '../config';
|
||||
|
||||
export type HonoApp = Hono;
|
||||
export type BackendType = {
|
||||
app?: HonoApp;
|
||||
server?: ReturnType<typeof serve>;
|
||||
oldConfig?: APIServerConfig;
|
||||
songInfo?: SongInfo;
|
||||
|
||||
init: (ctx: BackendContext<APIServerConfig>) => Promise<void>;
|
||||
run: (hostname: string, port: number) => void;
|
||||
end: () => void;
|
||||
};
|
||||
24
src/plugins/api-server/config.ts
Normal file
24
src/plugins/api-server/config.ts
Normal file
@ -0,0 +1,24 @@
|
||||
export enum AuthStrategy {
|
||||
AUTH_AT_FIRST = 'AUTH_AT_FIRST',
|
||||
NONE = 'NONE',
|
||||
}
|
||||
|
||||
export interface APIServerConfig {
|
||||
enabled: boolean;
|
||||
hostname: string;
|
||||
port: number;
|
||||
authStrategy: AuthStrategy;
|
||||
secret: string;
|
||||
|
||||
authorizedClients: string[];
|
||||
}
|
||||
|
||||
export const defaultAPIServerConfig: APIServerConfig = {
|
||||
enabled: true,
|
||||
hostname: '0.0.0.0',
|
||||
port: 26538,
|
||||
authStrategy: AuthStrategy.AUTH_AT_FIRST,
|
||||
secret: Date.now().toString(36),
|
||||
|
||||
authorizedClients: [],
|
||||
};
|
||||
17
src/plugins/api-server/index.ts
Normal file
17
src/plugins/api-server/index.ts
Normal file
@ -0,0 +1,17 @@
|
||||
import { createPlugin } from '@/utils';
|
||||
import { t } from '@/i18n';
|
||||
|
||||
import { defaultAPIServerConfig } from './config';
|
||||
import { onMenu } from './menu';
|
||||
import { backend } from './backend';
|
||||
|
||||
export default createPlugin({
|
||||
name: () => t('plugins.api-server.name'),
|
||||
description: () => t('plugins.api-server.description'),
|
||||
restartNeeded: false,
|
||||
config: defaultAPIServerConfig,
|
||||
addedVersion: '3.6.X',
|
||||
menu: onMenu,
|
||||
|
||||
backend,
|
||||
});
|
||||
97
src/plugins/api-server/menu.ts
Normal file
97
src/plugins/api-server/menu.ts
Normal file
@ -0,0 +1,97 @@
|
||||
import prompt from 'custom-electron-prompt';
|
||||
|
||||
import { t } from '@/i18n';
|
||||
import promptOptions from '@/providers/prompt-options';
|
||||
|
||||
import {
|
||||
type APIServerConfig,
|
||||
AuthStrategy,
|
||||
defaultAPIServerConfig,
|
||||
} from './config';
|
||||
|
||||
import type { MenuContext } from '@/types/contexts';
|
||||
import type { MenuTemplate } from '@/menu';
|
||||
|
||||
export const onMenu = async ({
|
||||
getConfig,
|
||||
setConfig,
|
||||
window,
|
||||
}: MenuContext<APIServerConfig>): Promise<MenuTemplate> => {
|
||||
const config = await getConfig();
|
||||
|
||||
return [
|
||||
{
|
||||
label: t('plugins.api-server.menu.hostname.label'),
|
||||
type: 'normal',
|
||||
async click() {
|
||||
const config = await getConfig();
|
||||
|
||||
const newHostname =
|
||||
(await prompt(
|
||||
{
|
||||
title: t('plugins.api-server.prompt.hostname.title'),
|
||||
label: t('plugins.api-server.prompt.hostname.label'),
|
||||
value: config.hostname,
|
||||
type: 'input',
|
||||
width: 380,
|
||||
...promptOptions(),
|
||||
},
|
||||
window,
|
||||
)) ??
|
||||
config.hostname ??
|
||||
defaultAPIServerConfig.hostname;
|
||||
|
||||
setConfig({ ...config, hostname: newHostname });
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('plugins.api-server.menu.port.label'),
|
||||
type: 'normal',
|
||||
async click() {
|
||||
const config = await getConfig();
|
||||
|
||||
const newPort =
|
||||
(await prompt(
|
||||
{
|
||||
title: t('plugins.api-server.prompt.port.title'),
|
||||
label: t('plugins.api-server.prompt.port.label'),
|
||||
value: config.port,
|
||||
type: 'counter',
|
||||
counterOptions: { minimum: 0, maximum: 65565 },
|
||||
width: 380,
|
||||
...promptOptions(),
|
||||
},
|
||||
window,
|
||||
)) ??
|
||||
config.port ??
|
||||
defaultAPIServerConfig.port;
|
||||
|
||||
setConfig({ ...config, port: newPort });
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('plugins.api-server.menu.auth-strategy.label'),
|
||||
type: 'submenu',
|
||||
submenu: [
|
||||
{
|
||||
label: t(
|
||||
'plugins.api-server.menu.auth-strategy.submenu.auth-at-first.label',
|
||||
),
|
||||
type: 'radio',
|
||||
checked: config.authStrategy === AuthStrategy.AUTH_AT_FIRST,
|
||||
click() {
|
||||
setConfig({ ...config, authStrategy: AuthStrategy.AUTH_AT_FIRST });
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('plugins.api-server.menu.auth-strategy.submenu.none.label'),
|
||||
type: 'radio',
|
||||
checked: config.authStrategy === AuthStrategy.NONE,
|
||||
click() {
|
||||
setConfig({ ...config, authStrategy: AuthStrategy.NONE });
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
};
|
||||
@ -15,7 +15,10 @@ export default createPlugin({
|
||||
this.styleSheet = new CSSStyleSheet();
|
||||
await this.styleSheet.replace(style);
|
||||
|
||||
document.adoptedStyleSheets = [...document.adoptedStyleSheets, this.styleSheet];
|
||||
document.adoptedStyleSheets = [
|
||||
...document.adoptedStyleSheets,
|
||||
this.styleSheet,
|
||||
];
|
||||
},
|
||||
async stop() {
|
||||
await this.styleSheet?.replace('');
|
||||
|
||||
@ -34,7 +34,7 @@ export default createPlugin<
|
||||
{
|
||||
label: t('plugins.captions-selector.menu.autoload'),
|
||||
type: 'checkbox',
|
||||
checked: config.autoload as boolean,
|
||||
checked: config.autoload,
|
||||
click(item) {
|
||||
setConfig({ autoload: item.checked });
|
||||
},
|
||||
@ -42,7 +42,7 @@ export default createPlugin<
|
||||
{
|
||||
label: t('plugins.captions-selector.menu.disable-captions'),
|
||||
type: 'checkbox',
|
||||
checked: config.disableCaptions as boolean,
|
||||
checked: config.disableCaptions,
|
||||
click(item) {
|
||||
setConfig({ disableCaptions: item.checked });
|
||||
},
|
||||
|
||||
@ -64,7 +64,7 @@ interface VolumeFade {
|
||||
// Main class
|
||||
export class VolumeFader {
|
||||
private readonly media: HTMLMediaElement;
|
||||
private readonly logger: VolumeLogger | false;
|
||||
private readonly logger: VolumeLogger | null;
|
||||
private scale: {
|
||||
internalToVolume: (level: number) => number;
|
||||
volumeToInternal: (level: number) => number;
|
||||
@ -100,7 +100,7 @@ export class VolumeFader {
|
||||
this.logger = options.logger;
|
||||
} else {
|
||||
// Set log function explicitly to false
|
||||
this.logger = false;
|
||||
this.logger = null;
|
||||
}
|
||||
|
||||
// Linear volume fading?
|
||||
@ -112,7 +112,7 @@ export class VolumeFader {
|
||||
};
|
||||
|
||||
// Log setting
|
||||
this.logger && this.logger('Using linear fading.');
|
||||
this.logger?.('Using linear fading.');
|
||||
}
|
||||
// No linear, but logarithmic fading…
|
||||
else {
|
||||
@ -152,9 +152,8 @@ export class VolumeFader {
|
||||
};
|
||||
|
||||
// Log setting if not default
|
||||
options.fadeScaling &&
|
||||
this.logger &&
|
||||
this.logger(
|
||||
if (options.fadeScaling)
|
||||
this.logger?.(
|
||||
'Using logarithmic fading with ' +
|
||||
String(10 * dynamicRange) +
|
||||
' dB dynamic range.',
|
||||
@ -170,8 +169,7 @@ export class VolumeFader {
|
||||
this.media.volume = options.initialVolume;
|
||||
|
||||
// Log setting
|
||||
this.logger &&
|
||||
this.logger('Set initial volume to ' + String(this.media.volume) + '.');
|
||||
this.logger?.('Set initial volume to ' + String(this.media.volume) + '.');
|
||||
}
|
||||
|
||||
// Fade duration given?
|
||||
@ -187,7 +185,7 @@ export class VolumeFader {
|
||||
this.active = false;
|
||||
|
||||
// Initialization done
|
||||
this.logger && this.logger('Initialized for', this.media);
|
||||
this.logger?.('Initialized for', this.media);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -236,8 +234,7 @@ export class VolumeFader {
|
||||
this.fadeDuration = fadeDuration;
|
||||
|
||||
// Log setting
|
||||
this.logger &&
|
||||
this.logger('Set fade duration to ' + String(fadeDuration) + ' ms.');
|
||||
this.logger?.('Set fade duration to ' + String(fadeDuration) + ' ms.');
|
||||
} else {
|
||||
// Abort and throw an exception
|
||||
throw new TypeError('Positive number expected as fade duration!');
|
||||
@ -279,7 +276,7 @@ export class VolumeFader {
|
||||
this.start();
|
||||
|
||||
// Log new fade
|
||||
this.logger && this.logger('New fade started:', this.fade);
|
||||
this.logger?.('New fade started:', this.fade);
|
||||
|
||||
// Return instance for chaining
|
||||
return this;
|
||||
@ -313,7 +310,7 @@ export class VolumeFader {
|
||||
|
||||
// Compute current level on internal scale
|
||||
const level =
|
||||
(progress * (this.fade.volume.end - this.fade.volume.start)) +
|
||||
progress * (this.fade.volume.end - this.fade.volume.start) +
|
||||
this.fade.volume.start;
|
||||
|
||||
// Map fade level to volume level and apply it to media element
|
||||
@ -323,8 +320,7 @@ export class VolumeFader {
|
||||
window.requestAnimationFrame(this.updateVolume.bind(this));
|
||||
} else {
|
||||
// Log end of fade
|
||||
this.logger &&
|
||||
this.logger('Fade to ' + String(this.fade.volume.end) + ' complete.');
|
||||
this.logger?.('Fade to ' + String(this.fade.volume.end) + ' complete.');
|
||||
|
||||
// Time is up, jump to target volume
|
||||
this.media.volume = this.scale.internalToVolume(this.fade.volume.end);
|
||||
@ -333,7 +329,7 @@ export class VolumeFader {
|
||||
this.active = false;
|
||||
|
||||
// Done, call back (if callable)
|
||||
typeof this.fade.callback === 'function' && this.fade.callback();
|
||||
if (typeof this.fade.callback === 'function') this.fade.callback();
|
||||
|
||||
// Clear fade
|
||||
this.fade = undefined;
|
||||
@ -382,7 +378,7 @@ export class VolumeFader {
|
||||
input = Math.log10(input);
|
||||
|
||||
// Scale minus something × 10 dB to 0…1 (clipping at 0)
|
||||
return Math.max(1 + (input / dynamicRange), 0);
|
||||
return Math.max(1 + input / dynamicRange, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -191,7 +191,7 @@ export default createPlugin<
|
||||
let waitForTransition: Promise<unknown>;
|
||||
|
||||
const getStreamURL = async (videoID: string): Promise<string> =>
|
||||
this.ipc?.invoke('audio-url', videoID);
|
||||
this.ipc?.invoke('audio-url', videoID) as Promise<string>;
|
||||
|
||||
const getVideoIDFromURL = (url: string) =>
|
||||
new URLSearchParams(url.split('?')?.at(-1)).get('v');
|
||||
|
||||
@ -2,11 +2,12 @@ import { app, dialog, ipcMain } from 'electron';
|
||||
import { Client as DiscordClient } from '@xhayper/discord-rpc';
|
||||
import { dev } from 'electron-is';
|
||||
|
||||
import { ActivityType, GatewayActivityButton } from 'discord-api-types/v10';
|
||||
|
||||
import registerCallback, { type SongInfo } from '@/providers/song-info';
|
||||
import { createBackend, LoggerPrefix } from '@/utils';
|
||||
import { t } from '@/i18n';
|
||||
|
||||
import type { GatewayActivityButton } from 'discord-api-types/v10';
|
||||
import type { SetActivity } from '@xhayper/discord-rpc/dist/structures/ClientUser';
|
||||
import type { DiscordPluginConfig } from './index';
|
||||
|
||||
@ -180,6 +181,7 @@ export const backend = createBackend<
|
||||
}
|
||||
|
||||
const activityInfo: SetActivity = {
|
||||
type: ActivityType.Listening,
|
||||
details: songInfo.title,
|
||||
state: songInfo.artist,
|
||||
largeImageKey: songInfo.imageSrc ?? '',
|
||||
@ -200,15 +202,15 @@ export const backend = createBackend<
|
||||
}
|
||||
} else if (!config.hideDurationLeft) {
|
||||
// Add the start and end time of the song
|
||||
const songStartTime = Date.now() - ((songInfo.elapsedSeconds ?? 0) * 1000);
|
||||
const songStartTime = Date.now() - (songInfo.elapsedSeconds ?? 0) * 1000;
|
||||
activityInfo.startTimestamp = songStartTime;
|
||||
activityInfo.endTimestamp = songStartTime + (songInfo.songDuration * 1000);
|
||||
activityInfo.endTimestamp = songStartTime + songInfo.songDuration * 1000;
|
||||
}
|
||||
|
||||
info.rpc.user?.setActivity(activityInfo).catch(console.error);
|
||||
},
|
||||
async start({ window: win, getConfig }) {
|
||||
this.config = await getConfig();
|
||||
async start(ctx) {
|
||||
this.config = await ctx.getConfig();
|
||||
|
||||
info.rpc.on('connected', () => {
|
||||
if (dev()) {
|
||||
@ -237,10 +239,10 @@ export const backend = createBackend<
|
||||
|
||||
info.autoReconnect = this.config.autoReconnect;
|
||||
|
||||
window = win;
|
||||
window = ctx.window;
|
||||
|
||||
// If the page is ready, register the callback
|
||||
win.once('ready-to-show', () => {
|
||||
ctx.window.once('ready-to-show', () => {
|
||||
let lastSongInfo: SongInfo;
|
||||
registerCallback((songInfo) => {
|
||||
lastSongInfo = songInfo;
|
||||
|
||||
@ -11,6 +11,13 @@ import { t } from '@/i18n';
|
||||
export type DownloaderPluginConfig = {
|
||||
enabled: boolean;
|
||||
downloadFolder?: string;
|
||||
downloadOnFinish?: {
|
||||
enabled: boolean;
|
||||
seconds: number;
|
||||
percent: number;
|
||||
mode: 'percent' | 'seconds';
|
||||
folder?: string;
|
||||
};
|
||||
selectedPreset: string;
|
||||
customPresetSetting: Preset;
|
||||
skipExisting: boolean;
|
||||
@ -20,6 +27,13 @@ export type DownloaderPluginConfig = {
|
||||
export const defaultConfig: DownloaderPluginConfig = {
|
||||
enabled: false,
|
||||
downloadFolder: undefined,
|
||||
downloadOnFinish: {
|
||||
enabled: false,
|
||||
seconds: 20,
|
||||
percent: 10,
|
||||
mode: 'seconds',
|
||||
folder: undefined,
|
||||
},
|
||||
selectedPreset: 'mp3 (256kbps)', // Selected preset
|
||||
customPresetSetting: DefaultPresetList['mp3 (256kbps)'], // Presets
|
||||
skipExisting: false,
|
||||
|
||||
@ -1,12 +1,8 @@
|
||||
import {
|
||||
existsSync,
|
||||
mkdirSync,
|
||||
writeFileSync,
|
||||
} from 'node:fs';
|
||||
import { existsSync, mkdirSync, writeFileSync } from 'node:fs';
|
||||
import { join } from 'node:path';
|
||||
import { randomBytes } from 'node:crypto';
|
||||
|
||||
import { app, BrowserWindow, dialog } from 'electron';
|
||||
import { app, BrowserWindow, dialog, ipcMain } from 'electron';
|
||||
import {
|
||||
ClientType,
|
||||
Innertube,
|
||||
@ -29,7 +25,12 @@ import {
|
||||
|
||||
import { fetchFromGenius } from '@/plugins/lyrics-genius/main';
|
||||
import { isEnabled } from '@/config/plugins';
|
||||
import { cleanupName, getImage, MediaType, type SongInfo } from '@/providers/song-info';
|
||||
import registerCallback, {
|
||||
cleanupName,
|
||||
getImage,
|
||||
MediaType,
|
||||
type SongInfo,
|
||||
} from '@/providers/song-info';
|
||||
import { getNetFetchAsFetch } from '@/plugins/utils/main';
|
||||
|
||||
import { t } from '@/i18n';
|
||||
@ -114,6 +115,8 @@ export const onMainLoad = async ({
|
||||
ipc.handle('download-playlist-request', async (url: string) =>
|
||||
downloadPlaylist(url),
|
||||
);
|
||||
|
||||
downloadSongOnFinishSetup({ ipc, getConfig });
|
||||
};
|
||||
|
||||
export const onConfigChange = (newConfig: DownloaderPluginConfig) => {
|
||||
@ -162,6 +165,60 @@ export async function downloadSongFromId(
|
||||
}
|
||||
}
|
||||
|
||||
function downloadSongOnFinishSetup({
|
||||
ipc,
|
||||
}: Pick<BackendContext<DownloaderPluginConfig>, 'ipc' | 'getConfig'>) {
|
||||
let currentUrl: string | undefined;
|
||||
let duration: number | undefined;
|
||||
let time = 0;
|
||||
|
||||
const defaultDownloadFolder = app.getPath('downloads');
|
||||
|
||||
registerCallback((songInfo: SongInfo) => {
|
||||
if (
|
||||
!songInfo.isPaused &&
|
||||
songInfo.url !== currentUrl &&
|
||||
config.downloadOnFinish?.enabled
|
||||
) {
|
||||
if (typeof currentUrl === 'string' && duration && duration > 0) {
|
||||
if (
|
||||
config.downloadOnFinish.mode === 'seconds' &&
|
||||
duration - time <= config.downloadOnFinish.seconds
|
||||
) {
|
||||
downloadSong(
|
||||
currentUrl,
|
||||
config.downloadOnFinish.folder ??
|
||||
config.downloadFolder ??
|
||||
defaultDownloadFolder,
|
||||
);
|
||||
} else if (
|
||||
config.downloadOnFinish.mode === 'percent' &&
|
||||
time >= duration * (config.downloadOnFinish.percent / 100)
|
||||
) {
|
||||
downloadSong(
|
||||
currentUrl,
|
||||
config.downloadOnFinish.folder ??
|
||||
config.downloadFolder ??
|
||||
defaultDownloadFolder,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
currentUrl = songInfo.url;
|
||||
duration = songInfo.songDuration;
|
||||
time = 0;
|
||||
}
|
||||
});
|
||||
|
||||
ipcMain.on('ytmd:player-api-loaded', () => {
|
||||
ipc.send('ytmd:setup-time-changed-listener');
|
||||
});
|
||||
|
||||
ipcMain.on('ytmd:time-changed', (_, t: number) => {
|
||||
if (t > time) time = t;
|
||||
});
|
||||
}
|
||||
|
||||
async function downloadSongUnsafe(
|
||||
isId: boolean,
|
||||
idOrUrl: string,
|
||||
@ -216,12 +273,12 @@ async function downloadSongUnsafe(
|
||||
|
||||
let playabilityStatus = info.playability_status;
|
||||
let bypassedResult = null;
|
||||
if (playabilityStatus.status === 'LOGIN_REQUIRED') {
|
||||
if (playabilityStatus?.status === 'LOGIN_REQUIRED') {
|
||||
// Try to bypass the age restriction
|
||||
bypassedResult = await getAndroidTvInfo(id);
|
||||
playabilityStatus = bypassedResult.playability_status;
|
||||
|
||||
if (playabilityStatus.status === 'LOGIN_REQUIRED') {
|
||||
if (playabilityStatus?.status === 'LOGIN_REQUIRED') {
|
||||
throw new Error(
|
||||
`[${playabilityStatus.status}] ${playabilityStatus.reason}`,
|
||||
);
|
||||
@ -230,7 +287,7 @@ async function downloadSongUnsafe(
|
||||
info = bypassedResult;
|
||||
}
|
||||
|
||||
if (playabilityStatus.status === 'UNPLAYABLE') {
|
||||
if (playabilityStatus?.status === 'UNPLAYABLE') {
|
||||
const errorScreen =
|
||||
playabilityStatus.error_screen as PlayerErrorMessage | null;
|
||||
throw new Error(
|
||||
@ -375,7 +432,12 @@ async function iterableStreamToProcessedUint8Array(
|
||||
'writeFile',
|
||||
safeVideoName,
|
||||
Buffer.concat(
|
||||
await downloadChunks(stream, contentLength, sendFeedback, increasePlaylistProgress),
|
||||
await downloadChunks(
|
||||
stream,
|
||||
contentLength,
|
||||
sendFeedback,
|
||||
increasePlaylistProgress,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
@ -388,7 +450,7 @@ async function iterableStreamToProcessedUint8Array(
|
||||
}),
|
||||
ratio,
|
||||
);
|
||||
increasePlaylistProgress(0.15 + (ratio * 0.85));
|
||||
increasePlaylistProgress(0.15 + ratio * 0.85);
|
||||
});
|
||||
|
||||
const safeVideoNameWithExtension = `${safeVideoName}.${extension}`;
|
||||
@ -516,10 +578,17 @@ export async function downloadPlaylist(givenUrl?: string | URL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!playlist || !playlist.items || playlist.items.length === 0) {
|
||||
if (
|
||||
!playlist ||
|
||||
!playlist.items ||
|
||||
playlist.items.length === 0 ||
|
||||
!playlist.header ||
|
||||
!('title' in playlist.header)
|
||||
) {
|
||||
sendError(
|
||||
new Error(t('plugins.downloader.backend.feedback.playlist-is-empty')),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const normalPlaylistTitle = playlist.header?.title?.text;
|
||||
@ -609,7 +678,7 @@ export async function downloadPlaylist(givenUrl?: string | URL) {
|
||||
|
||||
const increaseProgress = (itemPercentage: number) => {
|
||||
const currentProgress = (counter - 1) / (items.length ?? 1);
|
||||
const newProgress = currentProgress + (progressStep * itemPercentage);
|
||||
const newProgress = currentProgress + progressStep * itemPercentage;
|
||||
win.setProgressBar(newProgress);
|
||||
};
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user