diff --git a/package.json b/package.json index b726740..cc2c1f0 100644 --- a/package.json +++ b/package.json @@ -182,11 +182,13 @@ "name": "播放限速", "description": "外网播放媒体库视频时,自动对下载器进行限速。", "labels": "网络", - "version": "1.2", + "version": "1.3", "icon": "Librespeed_A.png", "author": "Shurelol", "level": 1, "history": { + "v1.3": "修复bug;增加预留带宽设置", + "v1.2.1": "修复多下载器时限速比例计算错误问题", "v1.2": "增加不限速路径配置,以应对网盘直链播放的情况" } }, diff --git a/plugins/speedlimiter/__init__.py b/plugins/speedlimiter/__init__.py index 517f683..62db177 100644 --- a/plugins/speedlimiter/__init__.py +++ b/plugins/speedlimiter/__init__.py @@ -23,7 +23,7 @@ class SpeedLimiter(_PluginBase): # 插件图标 plugin_icon = "Librespeed_A.png" # 插件版本 - plugin_version = "1.2" + plugin_version = "1.3" # 插件作者 plugin_author = "Shurelol" # 作者主页 @@ -48,6 +48,7 @@ class SpeedLimiter(_PluginBase): _noplay_up_speed: float = 0 _noplay_down_speed: float = 0 _bandwidth: float = 0 + _reserved_bandwidth: float = 0 _allocation_ratio: str = "" _auto_limit: bool = False _limit_enabled: bool = False @@ -72,6 +73,10 @@ class SpeedLimiter(_PluginBase): try: # 总带宽 self._bandwidth = int(float(config.get("bandwidth") or 0)) * 1000000 + self._reserved_bandwidth = int(float(config.get("reserved_bandwidth") or 0)) * 1000000 + # 减去预留带宽 + if self._reserved_bandwidth: + self._bandwidth -= self._reserved_bandwidth # 自动限速开关 if self._bandwidth > 0: self._auto_limit = True @@ -319,6 +324,23 @@ class SpeedLimiter(_PluginBase): } } ] + }, + { + 'component': 'VCol', + 'props': { + 'cols': 12, + 'md': 6 + }, + 'content': [ + { + 'component': 'VTextField', + 'props': { + 'model': 'reserved_bandwidth', + 'label': '预留带宽(应对突发流量和额外开销)', + 'placeholder': 'Mbps' + } + } + ] } ] }, @@ -452,6 +474,8 @@ class SpeedLimiter(_PluginBase): # 未设置不限速范围,则默认不限速内网ip elif not IpUtils.is_private_ip(session.get("RemoteEndPoint")) \ and session.get("NowPlayingItem", {}).get("MediaType") == "Video": + logger.debug(f"当前播放内容:{session.get('NowPlayingItem').get('FileName')}," + f"比特率:{int(session.get('NowPlayingItem', {}).get('Bitrate') or 0)}") total_bit_rate += int(session.get("NowPlayingItem", {}).get("Bitrate") or 0) elif media_server == "jellyfin": req_url = "[HOST]Sessions?api_key=[APIKEY]" @@ -505,6 +529,7 @@ class SpeedLimiter(_PluginBase): total_bit_rate += int(session.get("bitrate") or 0) if total_bit_rate: + logger.debug(f"比特率总计:{total_bit_rate}") # 开启智能限速计算上传限速 if self._auto_limit: play_up_speed = self.__calc_limit(total_bit_rate) @@ -512,6 +537,7 @@ class SpeedLimiter(_PluginBase): play_up_speed = self._play_up_speed # 当前正在播放,开始限速 + logger.debug(f"上传限速:{play_up_speed} KB/s") self.__set_limiter(limit_type="播放", upload_limit=play_up_speed, download_limit=self._play_down_speed) else: @@ -535,7 +561,8 @@ class SpeedLimiter(_PluginBase): """ 计算智能上传限速 """ - if not self._bandwidth: + # 当前总比特率大于总带宽,则设置为最低限速 + if not self._bandwidth or total_bit_rate > self._bandwidth: return 10 return round((self._bandwidth - total_bit_rate) / 8 / 1024, 2) @@ -554,71 +581,67 @@ class SpeedLimiter(_PluginBase): try: cnt = 0 + text = "" for download in self._downloader: + if cnt != 0: + text = f"{text}\n====================" + text = f"{text}\n下载器:{download}" + upload_limit_final = 0 if self._auto_limit and limit_type == "播放": # 开启了播放智能限速 if len(self._downloader) == 1: # 只有一个下载器 - upload_limit = int(upload_limit) + upload_limit_final = int(upload_limit) else: # 多个下载器 if not self._allocation_ratio: # 平均 - upload_limit = int(upload_limit / len(self._downloader)) + upload_limit_final = int(upload_limit / len(self._downloader)) else: # 按比例 allocation_count = sum([int(i) for i in self._allocation_ratio.split(":")]) - upload_limit = int(upload_limit * int(self._allocation_ratio.split(":")[cnt]) / allocation_count) + upload_limit_final = int(upload_limit * int(self._allocation_ratio.split(":")[cnt]) / allocation_count) + logger.debug(f"下载器:{download} 分配比例:{self._allocation_ratio.split(':')[cnt]}/{allocation_count} 分配上传限速:{upload_limit_final} KB/s") cnt += 1 - if upload_limit: - text = f"上传:{upload_limit} KB/s" + if upload_limit_final: + text = f"{text}\n上传:{upload_limit_final} KB/s" else: - text = f"上传:未限速" + text = f"{text}\n上传:未限速" if download_limit: text = f"{text}\n下载:{download_limit} KB/s" else: text = f"{text}\n下载:未限速" if str(download) == 'qbittorrent': if self._qb: - self._qb.set_speed_limit(download_limit=download_limit, upload_limit=upload_limit) - # 发送通知 - if self._notify: - title = "【播放限速】" - if upload_limit or download_limit: - subtitle = f"Qbittorrent 开始{limit_type}限速" - self.post_message( - mtype=NotificationType.MediaServer, - title=title, - text=f"{subtitle}\n{text}" - ) - else: - self.post_message( - mtype=NotificationType.MediaServer, - title=title, - text=f"Qbittorrent 已取消限速" - ) + self._qb.set_speed_limit(download_limit=download_limit, upload_limit=upload_limit_final) else: if self._tr: - self._tr.set_speed_limit(download_limit=download_limit, upload_limit=upload_limit) - # 发送通知 - if self._notify: - title = "【播放限速】" - if upload_limit or download_limit: - subtitle = f"Transmission 开始{limit_type}限速" - self.post_message( - mtype=NotificationType.MediaServer, - title=title, - text=f"{subtitle}\n{text}" - ) - else: - self.post_message( - mtype=NotificationType.MediaServer, - title=title, - text=f"Transmission 已取消限速" - ) + self._tr.set_speed_limit(download_limit=download_limit, upload_limit=upload_limit_final) + # 发送通知 + self._notify_message(text, bool(upload_limit or download_limit), limit_type) except Exception as e: logger.error(f"设置限速失败:{str(e)}") + def _notify_message(self, text: str, is_limit: bool, limit_type: str): + """ + 发送通知 + """ + if self._notify: + title = "【播放限速】" + if is_limit: + subtitle = f"{limit_type},开始限速" + self.post_message( + mtype=NotificationType.MediaServer, + title=title, + text=f"{subtitle}\n{text}" + ) + else: + self.post_message( + mtype=NotificationType.MediaServer, + title=title, + text=f"{limit_type},取消限速" + ) + @staticmethod def __allow_access(allow_ips: dict, ip: str) -> bool: """