1
0
mirror of https://github.com/hanxi/xiaomusic.git synced 2026-05-07 00:15:59 +08:00

fix: 支持代理 m3u8 格式链接 close #711

This commit is contained in:
涵曦
2026-01-19 15:35:58 +08:00
parent fefdae7ba6
commit ddb3e98f16
2 changed files with 37 additions and 8 deletions

View File

@@ -289,8 +289,13 @@ async def get_picture(request: Request, file_path: str, key: str = "", code: str
@router.get("/proxy", summary="基于正常下载逻辑的代理接口")
async def proxy(urlb64: str):
"""代理接口"""
async def proxy(urlb64: str, radio: bool = None):
"""代理接口
Args:
urlb64: Base64编码的URL
radio: 是否为电台直播流。None时自动识别True强制使用长超时False强制使用短超时
"""
try:
# 将Base64编码的URL解码为字符串
url_bytes = base64.b64decode(urlb64)
@@ -310,9 +315,14 @@ async def proxy(urlb64: str):
status_code=400, detail="无效的URL格式"
) from invalid_url_exc
# 创建会话并确保关闭
# 直播流使用更长的超时时间24小时普通文件使用10分钟
timeout_seconds = 86400 if radio else 600
log.info(
f"代理模式: {'电台直播流' if radio else '普通文件'}, 超时时间: {timeout_seconds}"
)
session = aiohttp.ClientSession(
timeout=aiohttp.ClientTimeout(total=600),
timeout=aiohttp.ClientTimeout(total=timeout_seconds, sock_read=300),
connector=aiohttp.TCPConnector(ssl=True),
)
@@ -363,8 +373,22 @@ async def proxy(urlb64: str):
finally:
await close_session()
# 提取文件名
filename = parsed_url.path.split("/")[-1].split("?")[0] or "output.mp3"
# 提取文件名根据URL扩展名智能判断
filename = parsed_url.path.split("/")[-1].split("?")[0]
if not filename:
# 根据URL扩展名或Content-Type设置默认文件名
path_lower = parsed_url.path.lower()
if path_lower.endswith(".m3u8"):
filename = "stream.m3u8"
elif path_lower.endswith(".m3u"):
filename = "stream.m3u"
else:
# 根据Content-Type推断
content_type = resp.headers.get("Content-Type", "").lower()
if "mpegurl" in content_type or "m3u8" in content_type:
filename = "stream.m3u8"
else:
filename = "output.mp3"
return StreamingResponse(
stream_generator(),

View File

@@ -1023,7 +1023,9 @@ class MusicLibrary:
# 是否需要代理
if self.config.web_music_proxy or url.startswith("self://"):
proxy_url = self._get_proxy_url(url)
# 判断是否为电台,传入 radio 参数
is_radio = self.is_web_radio_music(name)
proxy_url = self._get_proxy_url(url, radio=is_radio)
return proxy_url, url
return url, None
@@ -1044,11 +1046,12 @@ class MusicLibrary:
self.log.error(f"_get_url_from_api use api fail. name:{name}, url:{url}")
return url
def _get_proxy_url(self, origin_url):
def _get_proxy_url(self, origin_url, radio=None):
"""获取代理URL
Args:
origin_url: 原始URL
radio: 是否为电台直播流None时不传参数
Returns:
str: 代理URL
@@ -1057,6 +1060,8 @@ class MusicLibrary:
proxy_url = (
f"{self.config.hostname}:{self.config.public_port}/proxy?urlb64={urlb64}"
)
if radio is not None:
proxy_url += f"&radio={'true' if radio else 'false'}"
self.log.info(f"Using proxy url: {proxy_url}")
return proxy_url