mirror of
https://github.com/janishutz/MusicPlayerV2.git
synced 2025-11-25 04:54:23 +00:00
animation of remote display
This commit is contained in:
175
frontend/package-lock.json
generated
175
frontend/package-lock.json
generated
@@ -15,7 +15,8 @@
|
|||||||
"music-metadata": "^7.13.0",
|
"music-metadata": "^7.13.0",
|
||||||
"realtime-bpm-analyzer": "^3.2.1",
|
"realtime-bpm-analyzer": "^3.2.1",
|
||||||
"vue": "^3.2.13",
|
"vue": "^3.2.13",
|
||||||
"vue-router": "^4.0.3"
|
"vue-router": "^4.0.3",
|
||||||
|
"web-audio-beat-detector": "^8.1.55"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@vue/cli-plugin-babel": "~5.0.0",
|
"@vue/cli-plugin-babel": "~5.0.0",
|
||||||
@@ -1640,12 +1641,11 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/@babel/runtime": {
|
"node_modules/@babel/runtime": {
|
||||||
"version": "7.21.5",
|
"version": "7.23.2",
|
||||||
"resolved": "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.21.5.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.2.tgz",
|
||||||
"integrity": "sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q==",
|
"integrity": "sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"regenerator-runtime": "^0.13.11"
|
"regenerator-runtime": "^0.14.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.9.0"
|
"node": ">=6.9.0"
|
||||||
@@ -3877,6 +3877,18 @@
|
|||||||
"node": ">= 4.0.0"
|
"node": ">= 4.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/automation-events": {
|
||||||
|
"version": "6.0.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/automation-events/-/automation-events-6.0.11.tgz",
|
||||||
|
"integrity": "sha512-tUqFMJalQ3OAcbQOXzzNDpxzkuygMQ3eM92lJWJRn6YWJnH4oYIU3pzKipANOul/6L2vDFrOzgXVE21Dv4z/zw==",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": "^7.23.2",
|
||||||
|
"tslib": "^2.6.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/autoprefixer": {
|
"node_modules/autoprefixer": {
|
||||||
"version": "10.4.14",
|
"version": "10.4.14",
|
||||||
"resolved": "https://registry.npmmirror.com/autoprefixer/-/autoprefixer-10.4.14.tgz",
|
"resolved": "https://registry.npmmirror.com/autoprefixer/-/autoprefixer-10.4.14.tgz",
|
||||||
@@ -6998,6 +7010,18 @@
|
|||||||
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
|
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/fast-unique-numbers": {
|
||||||
|
"version": "8.0.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/fast-unique-numbers/-/fast-unique-numbers-8.0.10.tgz",
|
||||||
|
"integrity": "sha512-NUIqIhFYSwexP73lH76CLFkqNk9wHP00mUuqo4CMdhW+ETEGaIb6meriqdXRClwOQcTx2Qj4Ctw9Axo8cSwSqw==",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": "^7.23.2",
|
||||||
|
"tslib": "^2.6.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/fastq": {
|
"node_modules/fastq": {
|
||||||
"version": "1.15.0",
|
"version": "1.15.0",
|
||||||
"resolved": "https://registry.npmmirror.com/fastq/-/fastq-1.15.0.tgz",
|
"resolved": "https://registry.npmmirror.com/fastq/-/fastq-1.15.0.tgz",
|
||||||
@@ -11171,10 +11195,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/regenerator-runtime": {
|
"node_modules/regenerator-runtime": {
|
||||||
"version": "0.13.11",
|
"version": "0.14.0",
|
||||||
"resolved": "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
|
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz",
|
||||||
"integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==",
|
"integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"node_modules/regenerator-transform": {
|
"node_modules/regenerator-transform": {
|
||||||
"version": "0.15.1",
|
"version": "0.15.1",
|
||||||
@@ -12057,6 +12080,16 @@
|
|||||||
"integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==",
|
"integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/standardized-audio-context": {
|
||||||
|
"version": "25.3.58",
|
||||||
|
"resolved": "https://registry.npmjs.org/standardized-audio-context/-/standardized-audio-context-25.3.58.tgz",
|
||||||
|
"integrity": "sha512-1p5wVGiy4MfmhEt9MRY8yjZdkX+fi5jMxG1lqnAS1YmLUpE9VrOowxSINQ9Gjs89dFZMaENVwcMSPeQCjlz90Q==",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": "^7.23.2",
|
||||||
|
"automation-events": "^6.0.11",
|
||||||
|
"tslib": "^2.6.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/stat-mode": {
|
"node_modules/stat-mode": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmmirror.com/stat-mode/-/stat-mode-1.0.0.tgz",
|
"resolved": "https://registry.npmmirror.com/stat-mode/-/stat-mode-1.0.0.tgz",
|
||||||
@@ -12636,10 +12669,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/tslib": {
|
"node_modules/tslib": {
|
||||||
"version": "2.5.2",
|
"version": "2.6.2",
|
||||||
"resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
|
||||||
"integrity": "sha512-5svOrSA2w3iGFDs1HibEVBGbDrAY82bFQ3HZ3ixB+88nsbsWQoKqDRb5UBYAUPEzbBn6dAp5gRNXglySbx1MlA==",
|
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"node_modules/tunnel": {
|
"node_modules/tunnel": {
|
||||||
"version": "0.0.6",
|
"version": "0.0.6",
|
||||||
@@ -13821,6 +13853,38 @@
|
|||||||
"defaults": "^1.0.3"
|
"defaults": "^1.0.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/web-audio-beat-detector": {
|
||||||
|
"version": "8.1.55",
|
||||||
|
"resolved": "https://registry.npmjs.org/web-audio-beat-detector/-/web-audio-beat-detector-8.1.55.tgz",
|
||||||
|
"integrity": "sha512-K/RdkLNl+oBSM9lXb7t2scdqXhk4nkG8+6abknRD3YM+VP4nSYIugN7p8Bm/4EYZua1GWx7JeJXDDdrfFhabYg==",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": "^7.23.2",
|
||||||
|
"tslib": "^2.6.2",
|
||||||
|
"web-audio-beat-detector-broker": "^4.0.92",
|
||||||
|
"web-audio-beat-detector-worker": "^5.2.43"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/web-audio-beat-detector-broker": {
|
||||||
|
"version": "4.0.92",
|
||||||
|
"resolved": "https://registry.npmjs.org/web-audio-beat-detector-broker/-/web-audio-beat-detector-broker-4.0.92.tgz",
|
||||||
|
"integrity": "sha512-uxCHh9iVlS4fqc1Tn2A3jIybeoyvmtm1pqvC0/k2IjmcW44pIvaZMMkHCLf7SPJmPZMlbotBR4LDatnRacE5zA==",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": "^7.23.2",
|
||||||
|
"fast-unique-numbers": "^8.0.10",
|
||||||
|
"standardized-audio-context": "^25.3.58",
|
||||||
|
"tslib": "^2.6.2",
|
||||||
|
"web-audio-beat-detector-worker": "^5.2.43"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/web-audio-beat-detector-worker": {
|
||||||
|
"version": "5.2.43",
|
||||||
|
"resolved": "https://registry.npmjs.org/web-audio-beat-detector-worker/-/web-audio-beat-detector-worker-5.2.43.tgz",
|
||||||
|
"integrity": "sha512-/7U/eHDixwM5NBGZ6CEF9K5D5XrhJbRawY+52vrpIkhHpoyaM0EF02LDwW8WZ7lLjTDo0ab/WzjUIO+oeUpEDg==",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": "^7.23.2",
|
||||||
|
"tslib": "^2.6.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/webidl-conversions": {
|
"node_modules/webidl-conversions": {
|
||||||
"version": "3.0.1",
|
"version": "3.0.1",
|
||||||
"resolved": "https://registry.npmmirror.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
"resolved": "https://registry.npmmirror.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
||||||
@@ -15586,12 +15650,11 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"@babel/runtime": {
|
"@babel/runtime": {
|
||||||
"version": "7.21.5",
|
"version": "7.23.2",
|
||||||
"resolved": "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.21.5.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.2.tgz",
|
||||||
"integrity": "sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q==",
|
"integrity": "sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"regenerator-runtime": "^0.13.11"
|
"regenerator-runtime": "^0.14.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@babel/template": {
|
"@babel/template": {
|
||||||
@@ -17471,6 +17534,15 @@
|
|||||||
"integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==",
|
"integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"automation-events": {
|
||||||
|
"version": "6.0.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/automation-events/-/automation-events-6.0.11.tgz",
|
||||||
|
"integrity": "sha512-tUqFMJalQ3OAcbQOXzzNDpxzkuygMQ3eM92lJWJRn6YWJnH4oYIU3pzKipANOul/6L2vDFrOzgXVE21Dv4z/zw==",
|
||||||
|
"requires": {
|
||||||
|
"@babel/runtime": "^7.23.2",
|
||||||
|
"tslib": "^2.6.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"autoprefixer": {
|
"autoprefixer": {
|
||||||
"version": "10.4.14",
|
"version": "10.4.14",
|
||||||
"resolved": "https://registry.npmmirror.com/autoprefixer/-/autoprefixer-10.4.14.tgz",
|
"resolved": "https://registry.npmmirror.com/autoprefixer/-/autoprefixer-10.4.14.tgz",
|
||||||
@@ -20006,6 +20078,15 @@
|
|||||||
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
|
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"fast-unique-numbers": {
|
||||||
|
"version": "8.0.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/fast-unique-numbers/-/fast-unique-numbers-8.0.10.tgz",
|
||||||
|
"integrity": "sha512-NUIqIhFYSwexP73lH76CLFkqNk9wHP00mUuqo4CMdhW+ETEGaIb6meriqdXRClwOQcTx2Qj4Ctw9Axo8cSwSqw==",
|
||||||
|
"requires": {
|
||||||
|
"@babel/runtime": "^7.23.2",
|
||||||
|
"tslib": "^2.6.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"fastq": {
|
"fastq": {
|
||||||
"version": "1.15.0",
|
"version": "1.15.0",
|
||||||
"resolved": "https://registry.npmmirror.com/fastq/-/fastq-1.15.0.tgz",
|
"resolved": "https://registry.npmmirror.com/fastq/-/fastq-1.15.0.tgz",
|
||||||
@@ -23251,10 +23332,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"regenerator-runtime": {
|
"regenerator-runtime": {
|
||||||
"version": "0.13.11",
|
"version": "0.14.0",
|
||||||
"resolved": "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
|
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz",
|
||||||
"integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==",
|
"integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"regenerator-transform": {
|
"regenerator-transform": {
|
||||||
"version": "0.15.1",
|
"version": "0.15.1",
|
||||||
@@ -24006,6 +24086,16 @@
|
|||||||
"integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==",
|
"integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"standardized-audio-context": {
|
||||||
|
"version": "25.3.58",
|
||||||
|
"resolved": "https://registry.npmjs.org/standardized-audio-context/-/standardized-audio-context-25.3.58.tgz",
|
||||||
|
"integrity": "sha512-1p5wVGiy4MfmhEt9MRY8yjZdkX+fi5jMxG1lqnAS1YmLUpE9VrOowxSINQ9Gjs89dFZMaENVwcMSPeQCjlz90Q==",
|
||||||
|
"requires": {
|
||||||
|
"@babel/runtime": "^7.23.2",
|
||||||
|
"automation-events": "^6.0.11",
|
||||||
|
"tslib": "^2.6.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"stat-mode": {
|
"stat-mode": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmmirror.com/stat-mode/-/stat-mode-1.0.0.tgz",
|
"resolved": "https://registry.npmmirror.com/stat-mode/-/stat-mode-1.0.0.tgz",
|
||||||
@@ -24460,10 +24550,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tslib": {
|
"tslib": {
|
||||||
"version": "2.5.2",
|
"version": "2.6.2",
|
||||||
"resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
|
||||||
"integrity": "sha512-5svOrSA2w3iGFDs1HibEVBGbDrAY82bFQ3HZ3ixB+88nsbsWQoKqDRb5UBYAUPEzbBn6dAp5gRNXglySbx1MlA==",
|
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"tunnel": {
|
"tunnel": {
|
||||||
"version": "0.0.6",
|
"version": "0.0.6",
|
||||||
@@ -25426,6 +25515,38 @@
|
|||||||
"defaults": "^1.0.3"
|
"defaults": "^1.0.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"web-audio-beat-detector": {
|
||||||
|
"version": "8.1.55",
|
||||||
|
"resolved": "https://registry.npmjs.org/web-audio-beat-detector/-/web-audio-beat-detector-8.1.55.tgz",
|
||||||
|
"integrity": "sha512-K/RdkLNl+oBSM9lXb7t2scdqXhk4nkG8+6abknRD3YM+VP4nSYIugN7p8Bm/4EYZua1GWx7JeJXDDdrfFhabYg==",
|
||||||
|
"requires": {
|
||||||
|
"@babel/runtime": "^7.23.2",
|
||||||
|
"tslib": "^2.6.2",
|
||||||
|
"web-audio-beat-detector-broker": "^4.0.92",
|
||||||
|
"web-audio-beat-detector-worker": "^5.2.43"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"web-audio-beat-detector-broker": {
|
||||||
|
"version": "4.0.92",
|
||||||
|
"resolved": "https://registry.npmjs.org/web-audio-beat-detector-broker/-/web-audio-beat-detector-broker-4.0.92.tgz",
|
||||||
|
"integrity": "sha512-uxCHh9iVlS4fqc1Tn2A3jIybeoyvmtm1pqvC0/k2IjmcW44pIvaZMMkHCLf7SPJmPZMlbotBR4LDatnRacE5zA==",
|
||||||
|
"requires": {
|
||||||
|
"@babel/runtime": "^7.23.2",
|
||||||
|
"fast-unique-numbers": "^8.0.10",
|
||||||
|
"standardized-audio-context": "^25.3.58",
|
||||||
|
"tslib": "^2.6.2",
|
||||||
|
"web-audio-beat-detector-worker": "^5.2.43"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"web-audio-beat-detector-worker": {
|
||||||
|
"version": "5.2.43",
|
||||||
|
"resolved": "https://registry.npmjs.org/web-audio-beat-detector-worker/-/web-audio-beat-detector-worker-5.2.43.tgz",
|
||||||
|
"integrity": "sha512-/7U/eHDixwM5NBGZ6CEF9K5D5XrhJbRawY+52vrpIkhHpoyaM0EF02LDwW8WZ7lLjTDo0ab/WzjUIO+oeUpEDg==",
|
||||||
|
"requires": {
|
||||||
|
"@babel/runtime": "^7.23.2",
|
||||||
|
"tslib": "^2.6.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"webidl-conversions": {
|
"webidl-conversions": {
|
||||||
"version": "3.0.1",
|
"version": "3.0.1",
|
||||||
"resolved": "https://registry.npmmirror.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
"resolved": "https://registry.npmmirror.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
||||||
|
|||||||
@@ -18,7 +18,8 @@
|
|||||||
"music-metadata": "^7.13.0",
|
"music-metadata": "^7.13.0",
|
||||||
"realtime-bpm-analyzer": "^3.2.1",
|
"realtime-bpm-analyzer": "^3.2.1",
|
||||||
"vue": "^3.2.13",
|
"vue": "^3.2.13",
|
||||||
"vue-router": "^4.0.3"
|
"vue-router": "^4.0.3",
|
||||||
|
"web-audio-beat-detector": "^8.1.55"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@vue/cli-plugin-babel": "~5.0.0",
|
"@vue/cli-plugin-babel": "~5.0.0",
|
||||||
|
|||||||
@@ -9,16 +9,25 @@
|
|||||||
background: conic-gradient( blue, green, red, blue );
|
background: conic-gradient( blue, green, red, blue );
|
||||||
animation: gradientAnim 10s infinite linear;
|
animation: gradientAnim 10s infinite linear;
|
||||||
background-position: center;
|
background-position: center;
|
||||||
transition: all 0.1s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.beat {
|
.beat {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
background-color: rgba( 0, 0, 0, 0.2 );
|
background-color: rgba( 0, 0, 0, 0.2 );
|
||||||
|
animation: beatAnim 0.6s infinite linear;
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@keyframes beatAnim {
|
||||||
|
0% {
|
||||||
|
background-color: rgba( 0, 0, 0, 0.2 );
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
background-color: rgba( 0, 0, 0, 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@keyframes gradientAnim {
|
@keyframes gradientAnim {
|
||||||
from {
|
from {
|
||||||
transform: rotate( 0deg );
|
transform: rotate( 0deg );
|
||||||
|
|||||||
@@ -1,52 +1,3 @@
|
|||||||
:root, :root.light {
|
|
||||||
--primary-color: #2c3e50;
|
|
||||||
--accent-background: rgb(30, 30, 82);
|
|
||||||
--secondary-color: white;
|
|
||||||
--background-color: white;
|
|
||||||
--popup-color: rgb(224, 224, 224);
|
|
||||||
--accent-color: #42b983;
|
|
||||||
--hover-color: rgb(165, 165, 165);
|
|
||||||
--accent-background-hover: rgb(124, 140, 236);
|
|
||||||
--overlay-color: rgba(0, 0, 0, 0.7);
|
|
||||||
--border-color: rgb(100, 100, 100);
|
|
||||||
--highlight-backdrop: rgb(143, 134, 192);
|
|
||||||
--hint-color: rgb(174, 210, 221);
|
|
||||||
--PI: 3.14159265358979;
|
|
||||||
}
|
|
||||||
|
|
||||||
:root.dark {
|
|
||||||
--primary-color: white;
|
|
||||||
--accent-background: rgb(56, 56, 112);
|
|
||||||
--secondary-color: white;
|
|
||||||
--background-color: rgb(32, 32, 32);
|
|
||||||
--popup-color: rgb(58, 58, 58);
|
|
||||||
--accent-color: #42b983;
|
|
||||||
--hover-color: rgb(83, 83, 83);
|
|
||||||
--accent-background-hover: #4380a8;
|
|
||||||
--overlay-color: rgba(104, 104, 104, 0.575);
|
|
||||||
--border-color: rgb(190, 190, 190);
|
|
||||||
--highlight-backdrop: rgb(85, 63, 207);
|
|
||||||
--hint-color: rgb(88, 91, 110);
|
|
||||||
}
|
|
||||||
|
|
||||||
@media ( prefers-color-scheme: dark ) {
|
|
||||||
:root {
|
|
||||||
--primary-color: white;
|
|
||||||
--accent-background: rgb(56, 56, 112);
|
|
||||||
--secondary-color: white;
|
|
||||||
--background-color: rgb(32, 32, 32);
|
|
||||||
--popup-color: rgb(58, 58, 58);
|
|
||||||
--accent-color: #42b983;
|
|
||||||
--hover-color: rgb(83, 83, 83);
|
|
||||||
--accent-background-hover: #4380a8;
|
|
||||||
--overlay-color: rgba(104, 104, 104, 0.575);
|
|
||||||
--border-color: rgb(190, 190, 190);
|
|
||||||
--highlight-backdrop: rgb(85, 63, 207);
|
|
||||||
--hint-color: rgb(88, 91, 110);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.material-symbols-outlined {
|
.material-symbols-outlined {
|
||||||
font-variation-settings:
|
font-variation-settings:
|
||||||
'FILL' 0,
|
'FILL' 0,
|
||||||
@@ -60,6 +11,7 @@ body, html {
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
@@ -145,7 +97,8 @@ body {
|
|||||||
width: 80%;
|
width: 80%;
|
||||||
margin: 2px;
|
margin: 2px;
|
||||||
padding: 1vh;
|
padding: 1vh;
|
||||||
border: 1px var( --border-color ) solid;
|
border: 1px white solid;
|
||||||
|
background-color: rgba( 0, 0, 0, 0.4 );
|
||||||
}
|
}
|
||||||
|
|
||||||
.song-details-wrapper {
|
.song-details-wrapper {
|
||||||
@@ -172,13 +125,26 @@ body {
|
|||||||
user-select: none;
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.current-song {
|
.current-song-wrapper {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
height: 55vh;
|
height: 55vh;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
margin-bottom: 0.5%;
|
||||||
|
margin-top: 0.5%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.current-song {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: column;
|
||||||
|
margin-top: 2vh;
|
||||||
|
padding: 1vh;
|
||||||
|
text-align: center;
|
||||||
|
background-color: rgba( 0, 0, 0, 0.4 );
|
||||||
}
|
}
|
||||||
|
|
||||||
.fancy-view-song-art {
|
.fancy-view-song-art {
|
||||||
@@ -196,4 +162,11 @@ body {
|
|||||||
|
|
||||||
#app {
|
#app {
|
||||||
background-color: rgba( 0, 0, 0, 0 );
|
background-color: rgba( 0, 0, 0, 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
#progress {
|
||||||
|
background-color: rgba(45, 28, 145);
|
||||||
|
width: 30vw;
|
||||||
|
border: none;
|
||||||
|
border-radius: 50px;
|
||||||
}
|
}
|
||||||
@@ -14,12 +14,14 @@
|
|||||||
<body>
|
<body>
|
||||||
<div class="content" id="app">
|
<div class="content" id="app">
|
||||||
<div v-if="hasLoaded" style="width: 100%">
|
<div v-if="hasLoaded" style="width: 100%">
|
||||||
<div class="current-song">
|
<div class="current-song-wrapper">
|
||||||
<span class="material-symbols-outlined fancy-view-song-art" v-if="!playingSong.hasCoverArt">music_note</span>
|
<span class="material-symbols-outlined fancy-view-song-art" v-if="!playingSong.hasCoverArt">music_note</span>
|
||||||
<img v-else :src="'/getSongCover?filename=' + playingSong.filename" class="fancy-view-song-art">
|
<img v-else :src="'/getSongCover?filename=' + playingSong.filename" class="fancy-view-song-art">
|
||||||
<progress max="1000" id="progress" :value="progressBar"></progress>
|
<div class="current-song">
|
||||||
<h1>{{ playingSong.title }}</h1>
|
<progress max="1000" id="progress" :value="progressBar"></progress>
|
||||||
<p>{{ playingSong.artist }}</p>
|
<h1>{{ playingSong.title }}</h1>
|
||||||
|
<p>{{ playingSong.artist }}</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="song-list-wrapper">
|
<div class="song-list-wrapper">
|
||||||
<div v-for="song in songQueue" class="song-list">
|
<div v-for="song in songQueue" class="song-list">
|
||||||
@@ -37,6 +39,9 @@
|
|||||||
<h3>{{ song.title }}</h3>
|
<h3>{{ song.title }}</h3>
|
||||||
<p>{{ song.artist }}</p>
|
<p>{{ song.artist }}</p>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="time-until">
|
||||||
|
{{ getTimeUntil( song ) }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- <img :src="" alt=""> -->
|
<!-- <img :src="" alt=""> -->
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -27,6 +27,22 @@ createApp( {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
},
|
||||||
|
getTimeUntil( ) {
|
||||||
|
return ( song ) => {
|
||||||
|
let timeRemaining = 0;
|
||||||
|
for ( let i = this.queuePos; i < this.songs.length; i++ ) {
|
||||||
|
if ( this.songs[ i ] == song ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
timeRemaining += parseInt( this.songs[ i ].duration );
|
||||||
|
}
|
||||||
|
if ( timeRemaining === 0 ) {
|
||||||
|
return 'Currently playing';
|
||||||
|
} else {
|
||||||
|
return 'Playing in less than ' + Math.ceil( timeRemaining / 60 - this.pos / 60 ) + 'min';
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@@ -34,12 +50,12 @@ createApp( {
|
|||||||
this.startTime = new Date().getTime();
|
this.startTime = new Date().getTime();
|
||||||
this.timeTracker = setInterval( () => {
|
this.timeTracker = setInterval( () => {
|
||||||
this.pos += 0.075;
|
this.pos += 0.075;
|
||||||
this.progressBar = this.pos / this.playingSong.duration * 1000;
|
this.progressBar = ( this.pos / this.playingSong.duration ) * 1000;
|
||||||
}, 75 );
|
}, 75 );
|
||||||
|
|
||||||
this.timeCorrector = setInterval( () => {
|
this.timeCorrector = setInterval( () => {
|
||||||
this.pos = this.oldPos + ( new Date().getTime() - this.startTime ) / 1000;
|
this.pos = this.oldPos + ( new Date().getTime() - this.startTime ) / 1000;
|
||||||
this.progressBar = this.pos / this.playingSong.duration * 1000;
|
this.progressBar = ( this.pos / this.playingSong.duration ) * 1000;
|
||||||
}, 5000 );
|
}, 5000 );
|
||||||
},
|
},
|
||||||
stopTimeTracker () {
|
stopTimeTracker () {
|
||||||
@@ -47,6 +63,20 @@ createApp( {
|
|||||||
clearInterval( this.timeCorrector );
|
clearInterval( this.timeCorrector );
|
||||||
this.oldPos = this.pos;
|
this.oldPos = this.pos;
|
||||||
},
|
},
|
||||||
|
// getTimeUntil( song ) {
|
||||||
|
// let timeRemaining = 0;
|
||||||
|
// for ( let i = this.queuePos; i < this.songs.length; i++ ) {
|
||||||
|
// if ( this.songs[ i ] == song ) {
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// timeRemaining += parseInt( this.songs[ i ].duration );
|
||||||
|
// }
|
||||||
|
// if ( timeRemaining === 0 ) {
|
||||||
|
// return 'Currently playing';
|
||||||
|
// } else {
|
||||||
|
// return 'Playing in about ' + Math.ceil( timeRemaining / 60 ) + 'min';
|
||||||
|
// }
|
||||||
|
// },
|
||||||
connect() {
|
connect() {
|
||||||
let source = new EventSource( '/clientDisplayNotifier', { withCredentials: true } );
|
let source = new EventSource( '/clientDisplayNotifier', { withCredentials: true } );
|
||||||
source.onmessage = ( e ) => {
|
source.onmessage = ( e ) => {
|
||||||
@@ -62,9 +92,9 @@ createApp( {
|
|||||||
this.songs = data.data.songQueue ?? [];
|
this.songs = data.data.songQueue ?? [];
|
||||||
this.pos = data.data.pos ?? 0;
|
this.pos = data.data.pos ?? 0;
|
||||||
this.oldPos = data.data.pos ?? 0;
|
this.oldPos = data.data.pos ?? 0;
|
||||||
|
this.startTime = new Date().getTime();
|
||||||
this.progressBar = this.pos / this.playingSong.duration * 1000;
|
this.progressBar = this.pos / this.playingSong.duration * 1000;
|
||||||
this.queuePos = data.data.queuePos ?? 0;
|
this.queuePos = data.data.queuePos ?? 0;
|
||||||
if ( this.isPlaying ) this.startTimeTracker();
|
|
||||||
getColourPalette( '/getSongCover?filename=' + data.data.playingSong.filename ).then( palette => {
|
getColourPalette( '/getSongCover?filename=' + data.data.playingSong.filename ).then( palette => {
|
||||||
this.colourPalette = palette;
|
this.colourPalette = palette;
|
||||||
this.handleBackground();
|
this.handleBackground();
|
||||||
@@ -109,7 +139,8 @@ createApp( {
|
|||||||
}, false );
|
}, false );
|
||||||
},
|
},
|
||||||
handleBackground() {
|
handleBackground() {
|
||||||
// TODO: Consider using mic and realtime-bpm-analyzer
|
// TODO: Add hotkeys
|
||||||
|
// TODO: Check that colours are not too similar
|
||||||
let colours = {};
|
let colours = {};
|
||||||
if ( this.colourPalette[ 0 ] ) {
|
if ( this.colourPalette[ 0 ] ) {
|
||||||
for ( let i = 0; i < 3; i++ ) {
|
for ( let i = 0; i < 3; i++ ) {
|
||||||
@@ -117,23 +148,17 @@ createApp( {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
$( '#background' ).css( 'background', `conic-gradient( ${ colours[ 0 ] }, ${ colours[ 1 ] }, ${ colours[ 2 ] }, ${ colours[ 0 ] } )` );
|
$( '#background' ).css( 'background', `conic-gradient( ${ colours[ 0 ] }, ${ colours[ 1 ] }, ${ colours[ 2 ] }, ${ colours[ 0 ] } )` );
|
||||||
// if ( this.playingSong.bpm && this.isPlaying ) {
|
if ( this.playingSong.bpm && this.isPlaying ) {
|
||||||
// $( '.beat' ).show();
|
$( '.beat' ).show();
|
||||||
// $( '.beat' ).css( 'animation-duration', 60 / this.playingSong.bpm );
|
$( '.beat' ).css( 'animation-duration', 60 / this.playingSong.bpm );
|
||||||
// $( '.beat' ).css( 'animation-delay', this.pos % ( 60 / this.playingSong.bpm * this.pos ) );
|
$( '.beat' ).css( 'animation-delay', this.pos % ( 60 / this.playingSong.bpm * this.pos ) + this.playingSong.bpmOffset - ( 60 / this.playingSong.bpm * this.pos / 2 ) );
|
||||||
// } else {
|
} else {
|
||||||
// $( '.beat' ).hide();
|
$( '.beat' ).hide();
|
||||||
// }
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.connect();
|
this.connect();
|
||||||
// Initialize Web Audio API components
|
|
||||||
const audioContext = new ( window.AudioContext || window.webkitAudioContext )();
|
|
||||||
// Start audio analysis
|
|
||||||
navigator.mediaDevices.getUserMedia( { audio: true } ).then( ( stream ) => {
|
|
||||||
|
|
||||||
} );
|
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
isPlaying( value ) {
|
isPlaying( value ) {
|
||||||
|
|||||||
@@ -124,7 +124,7 @@
|
|||||||
import FancyView from './fancyView.vue';
|
import FancyView from './fancyView.vue';
|
||||||
import Notifications from './notifications.vue';
|
import Notifications from './notifications.vue';
|
||||||
import SliderView from './sliderView.vue';
|
import SliderView from './sliderView.vue';
|
||||||
import * as realtimeBPM from 'realtime-bpm-analyzer';
|
import { guess } from 'web-audio-beat-detector';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
@@ -140,6 +140,7 @@ export default {
|
|||||||
durationBeautified: '--:--',
|
durationBeautified: '--:--',
|
||||||
hasLoadedSongs: false,
|
hasLoadedSongs: false,
|
||||||
isShowingFancyView: false,
|
isShowingFancyView: false,
|
||||||
|
notifier: null,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
@@ -193,15 +194,14 @@ export default {
|
|||||||
const audioContext = new AudioContext();
|
const audioContext = new AudioContext();
|
||||||
fetch( 'http://localhost:8081/getSongFile?filename=' + filename ).then( res => {
|
fetch( 'http://localhost:8081/getSongFile?filename=' + filename ).then( res => {
|
||||||
res.arrayBuffer().then( buf => {
|
res.arrayBuffer().then( buf => {
|
||||||
// The file is uploaded, now we decode it
|
|
||||||
audioContext.decodeAudioData( buf, audioBuffer => {
|
audioContext.decodeAudioData( buf, audioBuffer => {
|
||||||
// The result is passed to the analyzer
|
guess( audioBuffer ).then( ( data ) => {
|
||||||
realtimeBPM.analyzeFullBuffer( audioBuffer ).then( topCandidates => {
|
this.playingSong.bpm = data.bpm;
|
||||||
// Do something with the BPM
|
this.playingSong.accurateTempo = data.tempo;
|
||||||
this.playingSong.bpm = topCandidates[ 0 ].tempo;
|
this.playingSong.bpmOffset = data.offset;
|
||||||
this.sendUpdate( 'playingSong' );
|
this.sendUpdate( 'playingSong' );
|
||||||
} );
|
} );
|
||||||
});
|
} );
|
||||||
} );
|
} );
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
@@ -250,12 +250,16 @@ export default {
|
|||||||
this.playbackPosBeautified += secondCount;
|
this.playbackPosBeautified += secondCount;
|
||||||
}
|
}
|
||||||
}, 0.02 );
|
}, 0.02 );
|
||||||
|
this.progressTracker = setInterval( () => {
|
||||||
|
this.sendUpdate( 'pos' );
|
||||||
|
}, 5000 );
|
||||||
this.sendUpdate( 'isPlaying' );
|
this.sendUpdate( 'isPlaying' );
|
||||||
} else if ( action === 'pause' ) {
|
} else if ( action === 'pause' ) {
|
||||||
this.$emit( 'update', { 'type': 'playback', 'status': false } );
|
this.$emit( 'update', { 'type': 'playback', 'status': false } );
|
||||||
musicPlayer.pause();
|
musicPlayer.pause();
|
||||||
try {
|
try {
|
||||||
clearInterval( this.progressTracker );
|
clearInterval( this.progressTracker );
|
||||||
|
clearInterval( this.notifier );
|
||||||
} catch ( err ) {};
|
} catch ( err ) {};
|
||||||
this.isPlaying = false;
|
this.isPlaying = false;
|
||||||
this.sendUpdate( 'isPlaying' );
|
this.sendUpdate( 'isPlaying' );
|
||||||
|
|||||||
Reference in New Issue
Block a user