# -*- coding: utf-8 -*- """HTTP 会话复用与音频内容嗅探。 (自 music_downloader.py 拆出,行为与原实现一致。) """ from __future__ import annotations import threading from core import sync_http as requests # 同步门面(底层 aiohttp,替代 requests) # ============ HTTP 连接复用(提速核心) ============ # 常见浏览器 UA,避免直链 CDN 因空 UA 限速/拒绝 DEFAULT_UA = ( "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 " "(KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" ) # 音频流式下载分块大小(256KB):减少系统调用与磁盘 IO 次数,提升吞吐 DL_CHUNK_SIZE = 256 * 1024 # 线程本地 Session:同线程内复用 TCP/TLS 连接(keep-alive),批量并发显著提速 _SESSION_LOCAL = threading.local() # 下载内容嗅探的音频魔数(未知期望尺寸时唯一的内容防线) _AUDIO_MAGIC = (b'ID3', b'fLaC', b'OggS', b'RIFF') def _sniff_audio_header(path) -> bool: """读取文件头做基础音频魔数校验:MP3(ID3/裸帧)、FLAC、OGG/Opus、WAV(RIFF)、 M4A/MP4(ftyp)。未知期望尺寸的下载走"非空即通过"保留口径,本函数补上内容 防线——CDN 错误页/风控 JSON 不再能被存成音频交付。""" try: with open(path, 'rb') as f: head = f.read(16) except OSError: return False if not head: return False if any(head.startswith(m) for m in _AUDIO_MAGIC): return True if len(head) >= 8 and head[:4] == b'\x00\x00\x00' and head[4:8] == b'ftyp': return True return len(head) >= 2 and head[0] == 0xFF and (head[1] & 0xE0) == 0xE0 def get_http_session() -> requests.Session: """获取当前线程的共享同步会话(连接池由底层 aiohttp 统一维护)。""" session: requests.Session | None = getattr(_SESSION_LOCAL, "session", None) if session is None: session = requests.Session() session.headers.update({"User-Agent": DEFAULT_UA}) _SESSION_LOCAL.session = session return session