diff --git a/index.html b/index.html index ab14adf..905c15b 100644 --- a/index.html +++ b/index.html @@ -140,7 +140,7 @@ // Use relative path for API proxy to avoid CORS issues // Nginx forwards /api/ to sync-server, which proxies /music-api to music-dl.sayqz.com - const API_BASE = "/music-api"; + const API_BASE = "/api/music-api"; // Use relative path for sync service, assuming Nginx proxy is configured to forward /api/kv to the sync service const SYNC_API_BASE = "/api"; @@ -270,15 +270,8 @@ return { results: [], total: 0 }; } }, - getSongUrl:async (id, source, br = '320k') => { - try { - const res = await fetch(`${API_BASE}?source=${source}&id=${id}&type=url&br=${br}`); - const data = await res.json(); - return data.url; - } catch (e) { - console.error("Get song url failed", e); - return null; - } + getSongUrl: (id, source, br = '320k') => { + return `${API_BASE}?source=${source}&id=${id}&type=url&br=${br}`; }, getPicUrl: (id, source) => { return `${API_BASE}?source=${source}&id=${id}&type=pic`; @@ -1277,43 +1270,31 @@ }, [playlist, currentSong, mode, volume, quality]); useEffect(() => { - let isMounted = true; if (currentSong) { const audio = audioRef.current; if (!audio) return; - - const fetchAndPlay = async () => { - // Update URL when quality changes or song changes - const url = await api.getSongUrl(currentSong.id, currentSong.platform || currentSong.source, quality); - - if (!isMounted || !url) return; - - // Check if song changed while fetching - if (currentSongRef.current?.id !== currentSong.id) return; - - // Only update src if it's different to avoid reloading same song on re-render (unless quality changed) - // Note: audioRef.current.src returns full absolute URL - const currentSrc = audio.src; - const wasPlaying = isPlaying; - const deferOnIOS = autoNextPendingRef.current; - autoNextPendingRef.current = false; - - // Simple check if src changed significantly (avoiding minor encoding diffs if possible, but exact match is safer) - if (currentSrc !== url) { - audio.src = url; - if (wasPlaying) { - playAudioWithFallback(audio, { deferOnIOS }); - } - } else if (deferOnIOS && wasPlaying) { - playAudioWithFallback(audio, { deferOnIOS: true }); - } - }; + // Update URL when quality changes or song changes + const url = api.getSongUrl(currentSong.id, currentSong.platform || currentSong.source, quality); - fetchAndPlay(); + // Only update src if it's different to avoid reloading same song on re-render (unless quality changed) + // Note: audioRef.current.src returns full absolute URL + const currentSrc = audio.src; + const wasPlaying = isPlaying; + const deferOnIOS = autoNextPendingRef.current; + autoNextPendingRef.current = false; + + // Simple check if src changed significantly (avoiding minor encoding diffs if possible, but exact match is safer) + if (currentSrc !== url) { + audio.src = url; + if (wasPlaying) { + playAudioWithFallback(audio, { deferOnIOS }); + } + } else if (deferOnIOS && wasPlaying) { + playAudioWithFallback(audio, { deferOnIOS: true }); + } } else { autoNextPendingRef.current = false; } - return () => { isMounted = false; }; }, [currentSong, quality]); // Re-run when quality changes useEffect(() => { @@ -1429,16 +1410,11 @@ if (options.immediate) { const audio = audioRef.current; if (!audio || !nextSong) return; - api.getSongUrl(nextSong.id, nextSong.platform || nextSong.source, quality).then(url => { - if (!url) return; - // Ensure we are still trying to play the same song - if (currentSongRef.current?.id === nextSong.id) { - if (audio.src !== url) { - audio.src = url; - } - playAudioWithFallback(audio, { deferOnIOS: options.deferOnIOS }); - } - }); + const url = api.getSongUrl(nextSong.id, nextSong.platform || nextSong.source, quality); + if (audio.src !== url) { + audio.src = url; + } + playAudioWithFallback(audio, { deferOnIOS: options.deferOnIOS }); } }; diff --git a/nginx.conf.example b/nginx.conf.example index fec9438..c355501 100644 --- a/nginx.conf.example +++ b/nginx.conf.example @@ -10,16 +10,32 @@ server { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } + # 音乐 API 代理 (解决 HTTPS 握手和 Host 问题) + location /music-api { + # 将 /music-api 映射到 /api + # 例如: /music-api?source=... -> https://music-dl.sayqz.com/api?source=... + rewrite ^/music-api/?(.*)$ /api/$1 break; + + proxy_pass https://music-dl.sayqz.com; + + # [关键] 开启 SSL Server Name Indication (SNI),否则 HTTPS 握手会失败 + proxy_ssl_server_name on; + + # [关键] 设置正确的 Host 头,或者直接删掉这行让 Nginx 自动使用 proxy_pass 的域名 + # 千万不要设置为 $host,因为对方服务器不认识你的域名 + proxy_set_header Host music-dl.sayqz.com; + + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + } + # 同步服务 API 代理 - # 将 /api/kv/... 转发到 sync-service 的 7482 端口 - # 注意:这里去掉了 /api 前缀,因为 sync-service 直接监听 /kv location /api/ { proxy_pass http://127.0.0.1:7482/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - # 允许跨域 (如果前端和后端不在同一个域) add_header 'Access-Control-Allow-Origin' '*'; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';