diff --git a/package-lock.json b/package-lock.json
index 9154b0d..c91eab0 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -36,8 +36,8 @@
"@types/pg": "^8.11.10",
"@types/qrcode-svg": "^1.1.5",
"@types/unist": "^3.0.3",
- "aplayer-ts": "^2.5.1",
- "astro-uploader": "^1.2.2",
+ "astro-netease-player": "^1.0.1",
+ "astro-uploader": "^1.2.3",
"bootstrap": "^5.3.3",
"photoswipe": "^5.4.4",
"photoswipe-dynamic-caption-plugin": "^1.2.7",
@@ -2595,14 +2595,24 @@
"sharp": "^0.33.3"
}
},
- "node_modules/astro-uploader": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/astro-uploader/-/astro-uploader-1.2.2.tgz",
- "integrity": "sha512-VmXJu8YPWW596G4SBJUry8mp3ojq5QSGZuGWLQjXJPpWEVK1aqxKsjuxT+tsMn3Xa1jkX/sIaTMbgy87PlzTAg==",
+ "node_modules/astro-netease-player": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/astro-netease-player/-/astro-netease-player-1.0.1.tgz",
+ "integrity": "sha512-k+5erGNLHyy/GRKLqUOuKiN7d2HeX6KHzbPKEa/oL0tda4s09Eu4Zzt29P05bO/QNs5EGJbsz9UGiUGeVevVmA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "mime": "^4.0.4",
+ "aplayer-ts": "^2.5.1"
+ }
+ },
+ "node_modules/astro-uploader": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/astro-uploader/-/astro-uploader-1.2.3.tgz",
+ "integrity": "sha512-5pdtx0kHa+qX1mcobt7S5DnB+mOJUehw1Sep0H5fiZ/ztVX63VY/Tn0CDdO0WeKYnCiurPheEkxV6f06TRu5rA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mime": "^4.0.6",
"opendal": "^0.47.7",
"rimraf": "^6.0.1"
}
diff --git a/package.json b/package.json
index 4bd8def..40a1613 100644
--- a/package.json
+++ b/package.json
@@ -69,8 +69,8 @@
"@types/pg": "^8.11.10",
"@types/qrcode-svg": "^1.1.5",
"@types/unist": "^3.0.3",
- "aplayer-ts": "^2.5.1",
- "astro-uploader": "^1.2.2",
+ "astro-netease-player": "^1.0.1",
+ "astro-uploader": "^1.2.3",
"bootstrap": "^5.3.3",
"photoswipe": "^5.4.4",
"photoswipe-dynamic-caption-plugin": "^1.2.7",
diff --git a/src/assets/scripts/globals.js b/src/assets/scripts/globals.js
index 62e94db..ac59a51 100644
--- a/src/assets/scripts/globals.js
+++ b/src/assets/scripts/globals.js
@@ -1,6 +1,5 @@
import PhotoSwipeSlideshow from '@/assets/scripts/photoswipe-slideshow.js';
import stickySidebar from '@/assets/scripts/sticky-sidebar.js';
-import APlayer from 'aplayer-ts';
import { actions, isInputError } from 'astro:actions';
import PhotoSwipe from 'photoswipe';
import PhotoSwipeDynamicCaption from 'photoswipe-dynamic-caption-plugin';
@@ -135,23 +134,6 @@ for (const dialog of document.querySelectorAll('.nice-dialog')) {
});
}
-// Netease music player.
-const ps = document.querySelectorAll('.aplayer');
-for (const p of ps) {
- APlayer().init({
- container: p,
- audio: [
- {
- name: p.dataset.name,
- artist: p.dataset.artist,
- url: p.dataset.url,
- cover: p.dataset.cover,
- theme: '#ebd0c2',
- },
- ],
- });
-}
-
// Search Bar.
const searchSidebar = document.querySelector('.search-sidebar');
if (typeof searchSidebar !== 'undefined' && searchSidebar !== null) {
diff --git a/src/assets/styles/globals.css b/src/assets/styles/globals.css
index 696fb4d..93be4b2 100644
--- a/src/assets/styles/globals.css
+++ b/src/assets/styles/globals.css
@@ -1,5 +1,4 @@
@import 'bootstrap/dist/css/bootstrap.min.css';
-@import 'aplayer-ts/src/css/base.css';
@import '@/assets/styles/reset.css';
@import '@/assets/styles/iconfont/iconfont.css';
@import 'photoswipe/style.css';
diff --git a/src/components/page/post/PostContent.astro b/src/components/page/post/PostContent.astro
index 431f251..8632dc5 100644
--- a/src/components/page/post/PostContent.astro
+++ b/src/components/page/post/PostContent.astro
@@ -1,8 +1,8 @@
---
import UnstyledAlbum from '@/components/album/UnstyledAlbum.astro';
import UnstyledImage from '@/components/image/UnstyledImage.astro';
-import UnstyledMusicPlayer from '@/components/player/UnstyledMusicPlayer.astro';
import { posts } from '@/helpers/schema';
+import UnstyledMusicPlayer from 'astro-netease-player/UnstyledMusicPlayer.astro';
interface Props {
slug: string;
diff --git a/src/components/player/MusicPlayer.astro b/src/components/player/MusicPlayer.astro
deleted file mode 100644
index bed42d3..0000000
--- a/src/components/player/MusicPlayer.astro
+++ /dev/null
@@ -1,17 +0,0 @@
----
-import { resolveSong, type MusicPlayerProps } from '@/components/player/resolver';
-
-interface Props extends MusicPlayerProps {}
-
-const { name, artist, url, pic } = await resolveSong(Astro.props);
----
-
-{
- url === '' ? (
-
歌曲加载失败
- ) : (
-
- 音乐正在加载中 ...
-
- )
-}
diff --git a/src/components/player/UnstyledMusicPlayer.astro b/src/components/player/UnstyledMusicPlayer.astro
deleted file mode 100644
index 41e3aae..0000000
--- a/src/components/player/UnstyledMusicPlayer.astro
+++ /dev/null
@@ -1,9 +0,0 @@
----
-import { resolveSong, type MusicPlayerProps } from '@/components/player/resolver';
-
-interface Props extends MusicPlayerProps {}
-
-const { url } = await resolveSong(Astro.props);
----
-
-{url !== '' && }
diff --git a/src/components/player/netease/config.ts b/src/components/player/netease/config.ts
deleted file mode 100644
index a509ba8..0000000
--- a/src/components/player/netease/config.ts
+++ /dev/null
@@ -1,726 +0,0 @@
-// An request token which is decoded from the Netease Android Player.
-const neteaseAnonymousToken =
- 'de91e1f8119d32e01cc73efcb82c0a30c9137e8d4f88dbf5e3d7bf3f28998f21add2bc8204eeee5e56c0bbb8743574b46ca2c10c35dc172199bef9bf4d60ecdeab066bb4dc737d1c3324751bcc9aaf44c3061cd18d77b7a0';
-
-// A selected IP set which locates in China.
-const chineseIPs = [
- '58.14.0.0',
- '58.16.0.0',
- '58.24.0.0',
- '58.30.0.0',
- '58.32.0.0',
- '58.66.0.0',
- '58.68.128.0',
- '58.82.0.0',
- '58.87.64.0',
- '58.99.128.0',
- '58.100.0.0',
- '58.116.0.0',
- '58.128.0.0',
- '58.144.0.0',
- '58.154.0.0',
- '58.192.0.0',
- '58.240.0.0',
- '59.32.0.0',
- '59.64.0.0',
- '59.80.0.0',
- '59.107.0.0',
- '59.108.0.0',
- '59.151.0.0',
- '59.155.0.0',
- '59.172.0.0',
- '59.191.0.0',
- '59.191.240.0',
- '59.192.0.0',
- '60.0.0.0',
- '60.55.0.0',
- '60.63.0.0',
- '60.160.0.0',
- '60.194.0.0',
- '60.200.0.0',
- '60.208.0.0',
- '60.232.0.0',
- '60.235.0.0',
- '60.245.128.0',
- '60.247.0.0',
- '60.252.0.0',
- '60.253.128.0',
- '60.255.0.0',
- '61.4.80.0',
- '61.4.176.0',
- '61.8.160.0',
- '61.28.0.0',
- '61.29.128.0',
- '61.45.128.0',
- '61.47.128.0',
- '61.48.0.0',
- '61.87.192.0',
- '61.128.0.0',
- '61.232.0.0',
- '61.236.0.0',
- '61.240.0.0',
- '114.28.0.0',
- '114.54.0.0',
- '114.60.0.0',
- '114.64.0.0',
- '114.68.0.0',
- '114.80.0.0',
- '116.1.0.0',
- '116.2.0.0',
- '116.4.0.0',
- '116.8.0.0',
- '116.13.0.0',
- '116.16.0.0',
- '116.52.0.0',
- '116.56.0.0',
- '116.58.128.0',
- '116.58.208.0',
- '116.60.0.0',
- '116.66.0.0',
- '116.69.0.0',
- '116.70.0.0',
- '116.76.0.0',
- '116.89.144.0',
- '116.90.184.0',
- '116.95.0.0',
- '116.112.0.0',
- '116.116.0.0',
- '116.128.0.0',
- '116.192.0.0',
- '116.193.16.0',
- '116.193.32.0',
- '116.194.0.0',
- '116.196.0.0',
- '116.198.0.0',
- '116.199.0.0',
- '116.199.128.0',
- '116.204.0.0',
- '116.207.0.0',
- '116.208.0.0',
- '116.212.160.0',
- '116.213.64.0',
- '116.213.128.0',
- '116.214.32.0',
- '116.214.64.0',
- '116.214.128.0',
- '116.215.0.0',
- '116.216.0.0',
- '116.224.0.0',
- '116.242.0.0',
- '116.244.0.0',
- '116.248.0.0',
- '116.252.0.0',
- '116.254.128.0',
- '116.255.128.0',
- '117.8.0.0',
- '117.21.0.0',
- '117.22.0.0',
- '117.24.0.0',
- '117.32.0.0',
- '117.40.0.0',
- '117.44.0.0',
- '117.48.0.0',
- '117.53.48.0',
- '117.53.176.0',
- '117.57.0.0',
- '117.58.0.0',
- '117.59.0.0',
- '117.60.0.0',
- '117.64.0.0',
- '117.72.0.0',
- '117.74.64.0',
- '117.74.128.0',
- '117.75.0.0',
- '117.76.0.0',
- '117.80.0.0',
- '117.100.0.0',
- '117.103.16.0',
- '117.103.128.0',
- '117.106.0.0',
- '117.112.0.0',
- '117.120.64.0',
- '117.120.128.0',
- '117.121.0.0',
- '117.121.128.0',
- '117.121.192.0',
- '117.122.128.0',
- '117.124.0.0',
- '117.128.0.0',
- '118.24.0.0',
- '118.64.0.0',
- '118.66.0.0',
- '118.67.112.0',
- '118.72.0.0',
- '118.80.0.0',
- '118.84.0.0',
- '118.88.32.0',
- '118.88.64.0',
- '118.88.128.0',
- '118.89.0.0',
- '118.91.240.0',
- '118.102.16.0',
- '118.112.0.0',
- '118.120.0.0',
- '118.124.0.0',
- '118.126.0.0',
- '118.132.0.0',
- '118.144.0.0',
- '118.178.0.0',
- '118.180.0.0',
- '118.184.0.0',
- '118.192.0.0',
- '118.212.0.0',
- '118.224.0.0',
- '118.228.0.0',
- '118.230.0.0',
- '118.239.0.0',
- '118.242.0.0',
- '118.244.0.0',
- '118.248.0.0',
- '119.0.0.0',
- '119.2.0.0',
- '119.2.128.0',
- '119.3.0.0',
- '119.4.0.0',
- '119.8.0.0',
- '119.10.0.0',
- '119.15.136.0',
- '119.16.0.0',
- '119.18.192.0',
- '119.18.208.0',
- '119.18.224.0',
- '119.19.0.0',
- '119.20.0.0',
- '119.27.64.0',
- '119.27.160.0',
- '119.27.192.0',
- '119.28.0.0',
- '119.30.48.0',
- '119.31.192.0',
- '119.32.0.0',
- '119.40.0.0',
- '119.40.64.0',
- '119.40.128.0',
- '119.41.0.0',
- '119.42.0.0',
- '119.42.136.0',
- '119.42.224.0',
- '119.44.0.0',
- '119.48.0.0',
- '119.57.0.0',
- '119.58.0.0',
- '119.59.128.0',
- '119.60.0.0',
- '119.62.0.0',
- '119.63.32.0',
- '119.75.208.0',
- '119.78.0.0',
- '119.80.0.0',
- '119.84.0.0',
- '119.88.0.0',
- '119.96.0.0',
- '119.108.0.0',
- '119.112.0.0',
- '119.128.0.0',
- '119.144.0.0',
- '119.148.160.0',
- '119.161.128.0',
- '119.162.0.0',
- '119.164.0.0',
- '119.176.0.0',
- '119.232.0.0',
- '119.235.128.0',
- '119.248.0.0',
- '119.253.0.0',
- '119.254.0.0',
- '120.0.0.0',
- '120.24.0.0',
- '120.30.0.0',
- '120.32.0.0',
- '120.48.0.0',
- '120.52.0.0',
- '120.64.0.0',
- '120.72.32.0',
- '120.72.128.0',
- '120.76.0.0',
- '120.80.0.0',
- '120.90.0.0',
- '120.92.0.0',
- '120.94.0.0',
- '120.128.0.0',
- '120.136.128.0',
- '120.137.0.0',
- '120.192.0.0',
- '121.0.16.0',
- '121.4.0.0',
- '121.8.0.0',
- '121.16.0.0',
- '121.32.0.0',
- '121.40.0.0',
- '121.46.0.0',
- '121.48.0.0',
- '121.51.0.0',
- '121.52.160.0',
- '121.52.208.0',
- '121.52.224.0',
- '121.55.0.0',
- '121.56.0.0',
- '121.58.0.0',
- '121.58.144.0',
- '121.59.0.0',
- '121.60.0.0',
- '121.68.0.0',
- '121.76.0.0',
- '121.79.128.0',
- '121.89.0.0',
- '121.100.128.0',
- '121.101.208.0',
- '121.192.0.0',
- '121.201.0.0',
- '121.204.0.0',
- '121.224.0.0',
- '121.248.0.0',
- '121.255.0.0',
- '122.0.64.0',
- '122.0.128.0',
- '122.4.0.0',
- '122.8.0.0',
- '122.48.0.0',
- '122.49.0.0',
- '122.51.0.0',
- '122.64.0.0',
- '122.96.0.0',
- '122.102.0.0',
- '122.102.64.0',
- '122.112.0.0',
- '122.119.0.0',
- '122.136.0.0',
- '122.144.128.0',
- '122.152.192.0',
- '122.156.0.0',
- '122.192.0.0',
- '122.198.0.0',
- '122.200.64.0',
- '122.204.0.0',
- '122.224.0.0',
- '122.240.0.0',
- '122.248.48.0',
- '123.0.128.0',
- '123.4.0.0',
- '123.8.0.0',
- '123.49.128.0',
- '123.52.0.0',
- '123.56.0.0',
- '123.64.0.0',
- '123.96.0.0',
- '123.98.0.0',
- '123.99.128.0',
- '123.100.0.0',
- '123.101.0.0',
- '123.103.0.0',
- '123.108.128.0',
- '123.108.208.0',
- '123.112.0.0',
- '123.128.0.0',
- '123.136.80.0',
- '123.137.0.0',
- '123.138.0.0',
- '123.144.0.0',
- '123.160.0.0',
- '123.176.80.0',
- '123.177.0.0',
- '123.178.0.0',
- '123.180.0.0',
- '123.184.0.0',
- '123.196.0.0',
- '123.199.128.0',
- '123.206.0.0',
- '123.232.0.0',
- '123.242.0.0',
- '123.244.0.0',
- '123.249.0.0',
- '123.253.0.0',
- '124.6.64.0',
- '124.14.0.0',
- '124.16.0.0',
- '124.20.0.0',
- '124.28.192.0',
- '124.29.0.0',
- '124.31.0.0',
- '124.40.112.0',
- '124.40.128.0',
- '124.42.0.0',
- '124.47.0.0',
- '124.64.0.0',
- '124.66.0.0',
- '124.67.0.0',
- '124.68.0.0',
- '124.72.0.0',
- '124.88.0.0',
- '124.108.8.0',
- '124.108.40.0',
- '124.112.0.0',
- '124.126.0.0',
- '124.128.0.0',
- '124.147.128.0',
- '124.156.0.0',
- '124.160.0.0',
- '124.172.0.0',
- '124.192.0.0',
- '124.196.0.0',
- '124.200.0.0',
- '124.220.0.0',
- '124.224.0.0',
- '124.240.0.0',
- '124.240.128.0',
- '124.242.0.0',
- '124.243.192.0',
- '124.248.0.0',
- '124.249.0.0',
- '124.250.0.0',
- '124.254.0.0',
- '125.31.192.0',
- '125.32.0.0',
- '125.58.128.0',
- '125.61.128.0',
- '125.62.0.0',
- '125.64.0.0',
- '125.96.0.0',
- '125.98.0.0',
- '125.104.0.0',
- '125.112.0.0',
- '125.169.0.0',
- '125.171.0.0',
- '125.208.0.0',
- '125.210.0.0',
- '125.213.0.0',
- '125.214.96.0',
- '125.215.0.0',
- '125.216.0.0',
- '125.254.128.0',
- '134.196.0.0',
- '159.226.0.0',
- '161.207.0.0',
- '162.105.0.0',
- '166.111.0.0',
- '167.139.0.0',
- '168.160.0.0',
- '169.211.1.0',
- '192.83.122.0',
- '192.83.169.0',
- '192.124.154.0',
- '192.188.170.0',
- '198.17.7.0',
- '202.0.110.0',
- '202.0.176.0',
- '202.4.128.0',
- '202.4.252.0',
- '202.8.128.0',
- '202.10.64.0',
- '202.14.88.0',
- '202.14.235.0',
- '202.14.236.0',
- '202.14.238.0',
- '202.20.120.0',
- '202.22.248.0',
- '202.38.0.0',
- '202.38.64.0',
- '202.38.128.0',
- '202.38.136.0',
- '202.38.138.0',
- '202.38.140.0',
- '202.38.146.0',
- '202.38.149.0',
- '202.38.150.0',
- '202.38.152.0',
- '202.38.156.0',
- '202.38.158.0',
- '202.38.160.0',
- '202.38.164.0',
- '202.38.168.0',
- '202.38.176.0',
- '202.38.184.0',
- '202.38.192.0',
- '202.41.152.0',
- '202.41.240.0',
- '202.43.144.0',
- '202.46.32.0',
- '202.46.224.0',
- '202.60.112.0',
- '202.63.248.0',
- '202.69.4.0',
- '202.69.16.0',
- '202.70.0.0',
- '202.74.8.0',
- '202.75.208.0',
- '202.85.208.0',
- '202.90.0.0',
- '202.90.224.0',
- '202.90.252.0',
- '202.91.0.0',
- '202.91.128.0',
- '202.91.176.0',
- '202.91.224.0',
- '202.92.0.0',
- '202.92.252.0',
- '202.93.0.0',
- '202.93.252.0',
- '202.95.0.0',
- '202.95.252.0',
- '202.96.0.0',
- '202.112.0.0',
- '202.120.0.0',
- '202.122.0.0',
- '202.122.32.0',
- '202.122.64.0',
- '202.122.112.0',
- '202.122.128.0',
- '202.123.96.0',
- '202.124.24.0',
- '202.125.176.0',
- '202.127.0.0',
- '202.127.12.0',
- '202.127.16.0',
- '202.127.40.0',
- '202.127.48.0',
- '202.127.112.0',
- '202.127.128.0',
- '202.127.160.0',
- '202.127.192.0',
- '202.127.208.0',
- '202.127.212.0',
- '202.127.216.0',
- '202.127.224.0',
- '202.130.0.0',
- '202.130.224.0',
- '202.131.16.0',
- '202.131.48.0',
- '202.131.208.0',
- '202.136.48.0',
- '202.136.208.0',
- '202.136.224.0',
- '202.141.160.0',
- '202.142.16.0',
- '202.143.16.0',
- '202.148.96.0',
- '202.149.160.0',
- '202.149.224.0',
- '202.150.16.0',
- '202.152.176.0',
- '202.153.48.0',
- '202.158.160.0',
- '202.160.176.0',
- '202.164.0.0',
- '202.164.25.0',
- '202.165.96.0',
- '202.165.176.0',
- '202.165.208.0',
- '202.168.160.0',
- '202.170.128.0',
- '202.170.216.0',
- '202.173.8.0',
- '202.173.224.0',
- '202.179.240.0',
- '202.180.128.0',
- '202.181.112.0',
- '202.189.80.0',
- '202.192.0.0',
- '203.18.50.0',
- '203.79.0.0',
- '203.80.144.0',
- '203.81.16.0',
- '203.83.56.0',
- '203.86.0.0',
- '203.86.64.0',
- '203.88.32.0',
- '203.88.192.0',
- '203.89.0.0',
- '203.90.0.0',
- '203.90.128.0',
- '203.90.192.0',
- '203.91.32.0',
- '203.91.96.0',
- '203.91.120.0',
- '203.92.0.0',
- '203.92.160.0',
- '203.93.0.0',
- '203.94.0.0',
- '203.95.0.0',
- '203.95.96.0',
- '203.99.16.0',
- '203.99.80.0',
- '203.100.32.0',
- '203.100.80.0',
- '203.100.96.0',
- '203.100.192.0',
- '203.110.160.0',
- '203.118.192.0',
- '203.119.24.0',
- '203.119.32.0',
- '203.128.32.0',
- '203.128.96.0',
- '203.130.32.0',
- '203.132.32.0',
- '203.134.240.0',
- '203.135.96.0',
- '203.135.160.0',
- '203.142.219.0',
- '203.148.0.0',
- '203.152.64.0',
- '203.156.192.0',
- '203.158.16.0',
- '203.161.192.0',
- '203.166.160.0',
- '203.171.224.0',
- '203.174.7.0',
- '203.174.96.0',
- '203.175.128.0',
- '203.175.192.0',
- '203.176.168.0',
- '203.184.80.0',
- '203.187.160.0',
- '203.190.96.0',
- '203.191.16.0',
- '203.191.64.0',
- '203.191.144.0',
- '203.192.0.0',
- '203.196.0.0',
- '203.207.64.0',
- '203.207.128.0',
- '203.208.0.0',
- '203.208.16.0',
- '203.208.32.0',
- '203.209.224.0',
- '203.212.0.0',
- '203.212.80.0',
- '203.222.192.0',
- '203.223.0.0',
- '210.2.0.0',
- '210.5.0.0',
- '210.5.144.0',
- '210.12.0.0',
- '210.14.64.0',
- '210.14.112.0',
- '210.14.128.0',
- '210.15.0.0',
- '210.15.128.0',
- '210.16.128.0',
- '210.21.0.0',
- '210.22.0.0',
- '210.23.32.0',
- '210.25.0.0',
- '210.26.0.0',
- '210.28.0.0',
- '210.32.0.0',
- '210.51.0.0',
- '210.52.0.0',
- '210.56.192.0',
- '210.72.0.0',
- '210.76.0.0',
- '210.78.0.0',
- '210.79.64.0',
- '210.79.224.0',
- '210.82.0.0',
- '210.87.128.0',
- '210.185.192.0',
- '210.192.96.0',
- '211.64.0.0',
- '211.80.0.0',
- '211.96.0.0',
- '211.136.0.0',
- '211.144.0.0',
- '211.160.0.0',
- '218.0.0.0',
- '218.56.0.0',
- '218.64.0.0',
- '218.96.0.0',
- '218.104.0.0',
- '218.108.0.0',
- '218.185.192.0',
- '218.192.0.0',
- '218.240.0.0',
- '218.249.0.0',
- '219.72.0.0',
- '219.82.0.0',
- '219.128.0.0',
- '219.216.0.0',
- '219.224.0.0',
- '219.242.0.0',
- '219.244.0.0',
- '220.101.192.0',
- '220.112.0.0',
- '220.152.128.0',
- '220.154.0.0',
- '220.160.0.0',
- '220.192.0.0',
- '220.231.0.0',
- '220.231.128.0',
- '220.232.64.0',
- '220.234.0.0',
- '220.242.0.0',
- '220.248.0.0',
- '220.252.0.0',
- '221.0.0.0',
- '221.8.0.0',
- '221.12.0.0',
- '221.12.128.0',
- '221.13.0.0',
- '221.14.0.0',
- '221.122.0.0',
- '221.129.0.0',
- '221.130.0.0',
- '221.133.224.0',
- '221.136.0.0',
- '221.172.0.0',
- '221.176.0.0',
- '221.192.0.0',
- '221.196.0.0',
- '221.198.0.0',
- '221.199.0.0',
- '221.199.128.0',
- '221.199.192.0',
- '221.199.224.0',
- '221.200.0.0',
- '221.208.0.0',
- '221.224.0.0',
- '222.16.0.0',
- '222.32.0.0',
- '222.64.0.0',
- '222.125.0.0',
- '222.126.128.0',
- '222.128.0.0',
- '222.160.0.0',
- '222.168.0.0',
- '222.176.0.0',
- '222.192.0.0',
- '222.240.0.0',
- '222.248.0.0',
-];
-
-// The User Agents which are used for each request. You can add or delete this for matching your needs.
-const userAgents = {
- mobile: [
- 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_5_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1.1 Mobile/15E148 Safari/604.1',
- 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0 Mobile/15E148 Safari/604.',
- 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_5_1 like Mac OS X) AppleWebKit/602.1.50 (KHTML like Gecko) Mobile/14A456 QQ/6.5.7.408 V1_IPH_SQ_6.5.7_1_APP_A Pixel/750 Core/UIWebView NetType/4G Mem/103',
- 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_5_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/7.0.15(0x17000f27) NetType/WIFI Language/zh',
- 'Mozilla/5.0 (Linux; Android 9; PCT-AL10) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.64 HuaweiBrowser/10.0.3.311 Mobile Safari/537.36',
- 'Mozilla/5.0 (Linux; U; Android 9; zh-cn; Redmi Note 8 Build/PKQ1.190616.001) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/71.0.3578.141 Mobile Safari/537.36 XiaoMi/MiuiBrowser/12.5.22',
- 'Mozilla/5.0 (Linux; Android 10; YAL-AL00 Build/HUAWEIYAL-AL00; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.62 XWEB/2581 MMWEBSDK/200801 Mobile Safari/537.36 MMWEBID/3027 MicroMessenger/7.0.18.1740(0x27001235) Process/toolsmp WeChat/arm64 NetType/WIFI Language/zh_CN ABI/arm64',
- 'Mozilla/5.0 (Linux; U; Android 8.1.0; zh-cn; BKK-AL10 Build/HONORBKK-AL10) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/66.0.3359.126 MQQBrowser/10.6 Mobile Safari/537.36',
- ],
- pc: [
- 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:80.0) Gecko/20100101 Firefox/80.0',
- 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.30 Safari/537.36',
- 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1.2 Safari/605.1.15',
- 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:80.0) Gecko/20100101 Firefox/80.0',
- 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.30 Safari/537.36',
- 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/13.10586',
- ],
-};
-
-export type CryptoMethod = 'weapi' | 'linuxapi' | 'eapi';
-export type UserAgentType = 'mobile' | 'pc';
-export type HttpMethod = 'POST' | 'GET' | 'HEAD' | 'OPTIONS' | 'DELETE' | 'TRACE' | 'PATCH' | 'PUT' | 'CONNECT';
-
-export { chineseIPs, neteaseAnonymousToken, userAgents };
diff --git a/src/components/player/netease/encrypt.ts b/src/components/player/netease/encrypt.ts
deleted file mode 100644
index 4155b01..0000000
--- a/src/components/player/netease/encrypt.ts
+++ /dev/null
@@ -1,75 +0,0 @@
-import type { HttpMethod } from '@/components/player/netease/config';
-import { Buffer } from 'node:buffer';
-import crypto from 'node:crypto';
-
-const iv = Buffer.from('0102030405060708');
-const presetKey = Buffer.from('0CoJUm6Qyw8W8jud');
-const linuxapiKey = Buffer.from('rFgB&h#%2?^eDg:Q');
-const base62 = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
-const publicKey =
- '-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDgtQn2JZ34ZC28NWYpAUd98iZ37BUrX/aKzmFbt7clFSs6sXqHauqKWqdtLkF2KexO40H1YTX8z2lSgBBOAxLsvaklV8k4cBFK9snQXE9/DDaFt6Rr7iVZMldczhC0JNgTz+SHXT6CBHuX3e9SdB1Ua44oncaTWz7OBGLbCiK45wIDAQAB\n-----END PUBLIC KEY-----';
-const eapiKey = 'e82ckenh8dichen8';
-
-const aesEncrypt = (
- buffer: Buffer | Uint8Array,
- mode: string,
- key: Buffer | Uint8Array | string,
- iv: Buffer | string,
-) => {
- const cipher = crypto.createCipheriv(`aes-128-${mode}`, key, iv);
- return Buffer.concat([cipher.update(buffer), cipher.final()]);
-};
-
-const rsaEncrypt = (buffer: Buffer | Uint8Array, key: string) => {
- return crypto.publicEncrypt(
- { key: key, padding: crypto.constants.RSA_NO_PADDING },
- Buffer.concat([Buffer.alloc(128 - buffer.length), buffer]),
- );
-};
-
-export const weapi = (form: Record): Record => {
- const text = JSON.stringify(form);
- const secretKey = crypto.randomBytes(16).map((n) => base62.charAt(n % 62).charCodeAt(0));
-
- return {
- params: aesEncrypt(
- Buffer.from(aesEncrypt(Buffer.from(text), 'cbc', presetKey, iv).toString('base64')),
- 'cbc',
- secretKey,
- iv,
- ).toString('base64'),
- encSecKey: rsaEncrypt(secretKey.reverse(), publicKey).toString('hex'),
- };
-};
-
-export const linuxapi = (method: HttpMethod, url: string, form: Record): Record => {
- const request = {
- method: method,
- url: url.replace(/\w*api/, 'api'),
- params: form,
- };
-
- const text = JSON.stringify(request);
- return {
- eparams: aesEncrypt(Buffer.from(text), 'ecb', linuxapiKey, '').toString('hex').toUpperCase(),
- };
-};
-
-export const eapi = (
- url: string,
- form: Record,
- header: Record,
-): Record => {
- const request = {
- ...form,
- header: header,
- };
-
- const text = JSON.stringify(request);
- const message = `nobody${url}use${text}md5forencrypt`;
- const digest = crypto.createHash('md5').update(message).digest('hex');
- const data = `${url}-36cd479b6b5-${text}-36cd479b6b5-${digest}`;
- return {
- params: aesEncrypt(Buffer.from(data), 'ecb', eapiKey, '').toString('hex').toUpperCase(),
- };
-};
diff --git a/src/components/player/netease/request.ts b/src/components/player/netease/request.ts
deleted file mode 100644
index 6462fcd..0000000
--- a/src/components/player/netease/request.ts
+++ /dev/null
@@ -1,150 +0,0 @@
-// The request is a rewritten file which is type safe to dispatch the netease music requests.
-// We will try to use three types of requests here. The weapi, linuxapi and eapi.
-
-import {
- chineseIPs,
- neteaseAnonymousToken,
- userAgents,
- type CryptoMethod,
- type HttpMethod,
- type UserAgentType,
-} from '@/components/player/netease/config';
-import { eapi, linuxapi, weapi } from '@/components/player/netease/encrypt';
-import { customAlphabet } from 'nanoid/non-secure';
-
-const nanoid = customAlphabet('1234567890abcdef', 32);
-
-const chooseUserAgent = (ua?: UserAgentType) => {
- const agents = ua === undefined ? [...userAgents.mobile, ...userAgents.pc] : userAgents[ua];
- return agents[Math.floor(Math.random() * agents.length)];
-};
-
-const randomChineseIP = () => chineseIPs[Math.floor(Math.random() * chineseIPs.length)];
-
-export type RequestOptions = {
- cookie?: Record;
- ua?: UserAgentType;
- crypto: CryptoMethod;
- url?: string;
-};
-
-export const request = async (
- method: HttpMethod,
- url: string,
- form: Record,
- options: RequestOptions,
-) => {
- // Generate the fundamental request headers.
- const headers: Record = { 'User-Agent': chooseUserAgent(options.ua) };
- const ip = randomChineseIP();
- headers['X-Real-IP'] = ip;
- headers['X-Forwarded-For'] = ip;
- if (method === 'POST' || method === 'PUT') {
- headers['Content-Type'] = 'application/x-www-form-urlencoded';
- }
- if (url.includes('music.163.com')) {
- headers.Referer = 'https://music.163.com';
- }
-
- // Append cookies to header.
- let cookies = options.cookie ? options.cookie : {};
- cookies = {
- ...cookies,
- _remember_me: true,
- _ntes_nuid: nanoid(),
- };
- if (!cookies.MUSIC_U) {
- // This is a guest request.
- if (!cookies.MUSIC_A) {
- cookies.MUSIC_A = neteaseAnonymousToken;
- }
- }
- headers.Cookie = Object.keys(cookies)
- .map((key) => `${encodeURIComponent(key)}=${encodeURIComponent(cookies[key])}`)
- .join('; ');
-
- // Try to choose encrypt method for generating the fetch request.
- let decryptedForm: Record;
- let decryptedURL: string;
-
- if (options.crypto === 'weapi') {
- const csrfToken = (headers.Cookie || '').match(/_csrf=([^(;|$)]+)/);
- form.csrf_token = csrfToken ? csrfToken[1] : '';
-
- decryptedForm = weapi(form);
- decryptedURL = url.replace(/\w*api/, 'weapi');
- } else if (options.crypto === 'linuxapi') {
- headers['User-Agent'] =
- 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36';
-
- decryptedForm = linuxapi(method, url, form);
- decryptedURL = 'https://music.163.com/api/linux/forward';
- } else if (options.crypto === 'eapi') {
- // Generate new cookies.
- const header: Record = {
- osver: cookies.osver,
- deviceId: cookies.deviceId,
- appver: cookies.appver || '8.7.01',
- versioncode: cookies.versioncode || '140',
- mobilename: cookies.mobilename,
- buildver: cookies.buildver || Date.now().toString().substring(0, 10),
- resolution: cookies.resolution || '1920x1080',
- __csrf: cookies.__csrf || '',
- os: cookies.os || 'android',
- channel: cookies.channel,
- requestId: `${Date.now()}_${Math.floor(Math.random() * 1000)
- .toString()
- .padStart(4, '0')} `,
- MUSIC_U: cookies.MUSIC_U,
- MUSIC_A: cookies.MUSIC_A,
- };
- headers.Cookie = Object.keys(header)
- .map((key) => `${encodeURIComponent(key)}=${encodeURIComponent(header[key])}`)
- .join('; ');
- if (options.url === undefined) {
- throw new Error('eapi is required to have a url options.');
- }
-
- decryptedForm = eapi(options.url, form, header);
- decryptedURL = url.replace(/\w*api/, 'eapi');
- } else {
- throw new Error(`Unsupported crypto method ${options.crypto}`);
- }
-
- let settings: Record> = {
- method,
- headers,
- body: new URLSearchParams(decryptedForm).toString(),
- };
-
- if (options.crypto === 'eapi') {
- settings = {
- ...settings,
- responseType: 'arraybuffer',
- };
- }
-
- let res: Response;
- let count = 0;
- let result = {};
- do {
- res = await fetch(decryptedURL, settings);
- if (options.crypto === 'eapi') {
- const enc = new TextDecoder();
- result = JSON.parse(enc.decode(await res.arrayBuffer()));
- } else {
- result = await res.json();
- }
- count++;
- if (count > 1) {
- console.log(`Request ${count} times.`);
- }
- if (count > 5) {
- console.error('Max retries exceeded.');
- break;
- }
- await new Promise((resolve) => setTimeout(resolve, 100));
- } while (res.status === -460);
-
- return result;
-};
diff --git a/src/components/player/netease/song.ts b/src/components/player/netease/song.ts
deleted file mode 100644
index 5064de4..0000000
--- a/src/components/player/netease/song.ts
+++ /dev/null
@@ -1,87 +0,0 @@
-import { request } from '@/components/player/netease/request';
-
-type SongUrl = {
- url?: string;
-};
-
-type SongUrlResponse = {
- data: SongUrl[];
-};
-
-export interface SongArtist {
- albumSize: number;
- id: number;
- img1v1Id: number;
- img1v1Url: string;
- musicSize: number;
- name: string;
- picId: number;
- picUrl: string;
- topicPerson: number;
- alias?: string[];
-}
-
-type SongInfo = {
- al: {
- id: number;
- name: string;
- picUrl: string;
- };
- ar: SongArtist[];
- dt: number;
- id: number;
- name: string;
- publishTime: number;
- fee?: number;
- status?: number;
-};
-
-type SongInfoResponse = {
- songs?: SongInfo[];
-};
-
-export const getSongUrl = async (id: number) => {
- const data = {
- ids: `[${id}]`,
- level: 'standard',
- encodeType: 'flac',
- };
-
- const res = await request('POST', 'https://interface.music.163.com/eapi/song/enhance/player/url/v1', data, {
- crypto: 'eapi',
- url: '/api/song/enhance/player/url/v1',
- cookie: {},
- });
- const url = (res as SongUrlResponse).data[0]?.url?.replace('http://', 'https://');
-
- return url || `https://music.163.com/song/media/outer/url?id=${id}.mp3`;
-};
-
-const mapSongList = (songs: SongInfo[]) => {
- return songs.map((song) => {
- const artists = song.ar || [];
- return {
- title: song.name,
- author: artists.reduce((i, v) => (i ? `${i} / ` : i) + v.name, ''),
- pic: song?.al?.picUrl,
- url: song.id,
- lrc: song.id,
- };
- });
-};
-
-export const getSongInfo = async (id: number) => {
- const ids = [id];
- const data = {
- c: `[${ids.map((id) => `{"id":${id}}`).join(',')}]`,
- };
- const res = (await request('POST', 'https://music.163.com/api/v3/song/detail', data, {
- crypto: 'weapi',
- })) as SongInfoResponse;
-
- if (!res.songs) {
- throw res;
- }
-
- return mapSongList(res.songs);
-};
diff --git a/src/components/player/resolver.ts b/src/components/player/resolver.ts
deleted file mode 100644
index 7d7a326..0000000
--- a/src/components/player/resolver.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-import { getSongInfo, getSongUrl } from '@/components/player/netease/song';
-
-export type Song = {
- name: string;
- artist: string;
- url: string;
- pic: string;
-};
-
-// The props for music player. We support both netease music and direct linked music.
-export interface MusicPlayerProps {
- netease?: number;
- song?: Song;
-}
-
-const emptySong = { name: '', artist: '', url: '', pic: '' };
-
-const song = async (props: MusicPlayerProps): Promise => {
- const { netease, song } = props;
-
- if (netease) {
- const info = await getSongInfo(netease);
- const url = await getSongUrl(netease);
-
- // Check the return result.
- return { name: info[0].title, artist: info[0].author, url: url, pic: info[0].pic };
- }
-
- if (song) {
- return song;
- }
-
- console.error('No song information is provided, check your code.');
- return emptySong;
-};
-
-export const resolveSong = async (props: MusicPlayerProps): Promise => {
- // Try-catch for avoiding the unexpected errors.
- try {
- return await song(props);
- } catch (e) {
- return emptySong;
- }
-};
diff --git a/src/layouts/PageLayout.astro b/src/layouts/PageLayout.astro
index 533912a..e07d0a6 100644
--- a/src/layouts/PageLayout.astro
+++ b/src/layouts/PageLayout.astro
@@ -7,11 +7,11 @@ import LikeButton from '@/components/like/LikeButton.astro';
import PageMeta from '@/components/meta/PageMeta.astro';
import Friends from '@/components/page/friend/Friends.astro';
import TableOfContents from '@/components/page/toc/TableOfContents.astro';
-import MusicPlayer from '@/components/player/MusicPlayer.astro';
import type { Page } from '@/helpers/schema';
import { urlJoin } from '@/helpers/tools';
import BaseLayout from '@/layouts/BaseLayout.astro';
import options from '@/options';
+import MusicPlayer from 'astro-netease-player/MusicPlayer.astro';
interface Props {
page: Page;
diff --git a/src/layouts/PostLayout.astro b/src/layouts/PostLayout.astro
index e96e07e..892f9cf 100644
--- a/src/layouts/PostLayout.astro
+++ b/src/layouts/PostLayout.astro
@@ -6,13 +6,13 @@ import LikeButton from '@/components/like/LikeButton.astro';
import LikeShare from '@/components/like/LikeShare.astro';
import PostMeta from '@/components/meta/PostMeta.astro';
import TableOfContents from '@/components/page/toc/TableOfContents.astro';
-import MusicPlayer from '@/components/player/MusicPlayer.astro';
import Sidebar from '@/components/sidebar/Sidebar.astro';
import { formatLocalDate } from '@/helpers/formatter';
import { getTag, posts, tags, type Post } from '@/helpers/schema';
import { urlJoin } from '@/helpers/tools';
import BaseLayout from '@/layouts/BaseLayout.astro';
import options from '@/options';
+import MusicPlayer from 'astro-netease-player/MusicPlayer.astro';
interface Props {
post: Post;