File caching service for videos
| 14 | |
| 15 | |
| 16 | class FileCache: |
| 17 | """File caching service for videos""" |
| 18 | |
| 19 | def __init__( |
| 20 | self, |
| 21 | cache_dir: str = "tmp", |
| 22 | default_timeout: int = 7200, |
| 23 | proxy_manager=None, |
| 24 | flow_client=None, |
| 25 | ): |
| 26 | """ |
| 27 | Initialize file cache |
| 28 | |
| 29 | Args: |
| 30 | cache_dir: Cache directory path |
| 31 | default_timeout: Default cache timeout in seconds (default: 2 hours) |
| 32 | proxy_manager: ProxyManager instance for downloading files |
| 33 | """ |
| 34 | self.cache_dir = Path(cache_dir) |
| 35 | self.cache_dir.mkdir(exist_ok=True) |
| 36 | self.default_timeout = max(0, int(default_timeout)) |
| 37 | self.proxy_manager = proxy_manager |
| 38 | self.flow_client = flow_client |
| 39 | self._cleanup_task = None |
| 40 | self._download_locks: Dict[str, asyncio.Lock] = {} |
| 41 | |
| 42 | def _is_cleanup_disabled(self) -> bool: |
| 43 | return self.default_timeout <= 0 |
| 44 | |
| 45 | def _get_request_fingerprint(self) -> Optional[Dict[str, Any]]: |
| 46 | """读取当前请求链路里绑定的浏览器指纹。""" |
| 47 | if not self.flow_client or not hasattr(self.flow_client, "get_request_fingerprint"): |
| 48 | return None |
| 49 | |
| 50 | try: |
| 51 | fingerprint = self.flow_client.get_request_fingerprint() |
| 52 | if isinstance(fingerprint, dict) and fingerprint: |
| 53 | return fingerprint |
| 54 | except Exception as e: |
| 55 | debug_logger.log_warning(f"Get request fingerprint failed: {str(e)}") |
| 56 | |
| 57 | return None |
| 58 | |
| 59 | async def _resolve_download_proxy( |
| 60 | self, |
| 61 | media_type: str, |
| 62 | fingerprint: Optional[Dict[str, Any]] = None, |
| 63 | ) -> Optional[str]: |
| 64 | """根据媒体类型解析下载代理地址。""" |
| 65 | if isinstance(fingerprint, dict): |
| 66 | fingerprint_proxy = str(fingerprint.get("proxy_url") or "").strip() |
| 67 | if fingerprint_proxy: |
| 68 | return fingerprint_proxy |
| 69 | |
| 70 | if not self.proxy_manager: |
| 71 | return None |
| 72 | |
| 73 | try: |