修改容器的重启策略为
需要修改容器的重启策略为 --restart always。由于容器已经存在,您有两个选择: 方法1:重新创建容器(推荐) 首先停止并删除当前容器: docker stop nginx-proxy-manager docker rm nginx-proxy-manager 然后用正确的重启策略重新创建容器。您需要回想或查找最初创建容器时使用的完整命令,并添加 --restart always 参数。 方法2:使用 docker update 命令 如果您的 Docker 版本较新,可以直接更新运行中的容器: docker update --restart always nginx-proxy-manager 然后重启容器: docker restart nginx-proxy-manager 验证重启策略 检查重启策略是否已生效: docker inspect nginx-proxy-manager | grep -A 5 "RestartPolicy" 您应该看到类似这样的输出: "RestartPolicy": { "Name": "always", "MaximumRetryCount": 0 }, 其他重启选项 除了 always,还有其他重启策略: no - 不自动重启(默认) always - 总是重启 unless-stopped - 除非手动停止,否则总是重启 on-failure - 仅在非正常退出时重启 建议使用方法2,因为它最简单且不会丢失容器配置。
Sub‑Store(GitHub 仓库)README 中整理的支持协议/节点类型
下面是基于 Sub‑Store(GitHub 仓库)README 中整理的支持协议/节点类型 + 支持目标平台/格式的 综合表格。 注意:部分协议可能标为「支持 = 作为输入/输出/部分支持」,项目中并未为所有组合明确标注,因此表中采用“✔/部分/—”表示。 协议/节点类型 说明 支持目标平台/格式 备注 SS (Shadowsocks) 常见代理协议 多平台 ✔ (例如 QX、Loon、Surge、Clash.Meta 等) ([GitHub][1]) 基础支持较好 SSR (ShadowsocksR) SS 的扩展协议 多平台 ✔ (QX、Loon、Stash/Clash 等) ([GitHub][1]) 有支持但可能因客户端限制造限 VMess 核心协议(V2Ray 系) 多平台 ✔ (例如 QX、Loon、Surge、Clash.Meta) ([GitHub][1]) 支持良好 VLESS V2Ray 系的新协议 多平台 ✔ (Surge、Clash.Meta 等) ([GitHub][1]) 支持在不断更新中 Trojan 又一种代理协议 多平台 ✔ (例如 QX、Loon、Clash.Meta) ([GitHub][1]) 支持情况较好 HTTP / SOCKS5 基本代理类型 多平台 ✔ (Surge/Clash.Meta 等) ([GitHub][1]) 注意 “HTTP(s) 不具有标准 URI 格式” 提醒 ([GitHub][1]) WireGuard VPN 型协议 多平台 ✔/部分支持 (Surge、Clash.Meta) ([GitHub][1]) 部分平台支持特定版本 Hysteria / Hysteria 2 较新加速协议 多平台 ✔/部分支持 (例如 Loon、Clash.Meta、Surge) ([GitHub][1]) 新协议,支持可能略有差别 TUIC 新一代协议 多平台 ✔/部分支持 (Clash.Meta、Stash 等) ([GitHub][1]) 较新协议,可能在某些平台表现不同 Snell 较少见协议 多平台 ✔/部分支持 (Surge、Clash.Meta 等) ([GitHub][1]) 使用较少,兼容性可能略逊 SSH (Password auth) 传统 SSH 隧道 支持 ≈ Surge (macOS) 等 ([GitHub][1]) 限于特定平台或场景 AnyTLS / Reality / etc 更前沿传输/混淆协议 部分支持 ✔ (Clash.Meta、Egern 等) ([GitHub][1]) 常见于 “包含官方/商店版不支持的协议” 开关中 支持的目标平台/格式(输出) 下面是 Sub‑Store 明确列出的支持输出平台/格式: Plain JSON ([GitHub][1]) Stash ([GitHub][1]) Clash.Meta (mihomo) ([GitHub][1]) Surfboard ([GitHub][1]) Surge (含 SurgeMac) ([GitHub][1]) Loon ([GitHub][1]) Egern ([GitHub][1]) Shadowrocket ([GitHub][1]) QX (Quantumult X) ([GitHub][1]) sing‑box ([GitHub][1]) V2Ray / V2Ray URI ([GitHub][1]) (已弃用)Clash 原始格式 ([GitHub][1])
合并多个源码/配置文件
✅ 功能: 合并多个源码/配置文件为一个 .txt。 将所有原始文件(保留从 D:\Android\project 开始的相对路径结构)压缩为 .zip。 同时将生成的合并文本文件也一并加入压缩包中(只保留其文件名)。 ✅ 最终完整脚本:含相对路径与合并输出文件打包 import os from datetime import datetime import zipfile # 要合并和压缩的文件路径列表 file_paths = [ r"D:\Android\project\WebPlayerTV\app\src\main\java\com\example\webplayertv\CardPresenter.kt", r"D:\Android\project\WebPlayerTV\app\src\main\java\com\example\webplayertv\Channel.kt", r"D:\Android\project\WebPlayerTV\app\src\main\java\com\example\webplayertv\MainActivity.kt", r"D:\Android\project\WebPlayerTV\app\src\main\java\com\example\webplayertv\MainFragment.kt", r"D:\Android\project\WebPlayerTV\app\src\main\java\com\example\webplayertv\PlaybackActivity.kt", r"D:\Android\project\WebPlayerTV\app\src\main\java\com\example\webplayertv\PlaybackVideoFragment.kt", r"D:\Android\project\WebPlayerTV\app\src\main\AndroidManifest.xml", r"D:\Android\project\WebPlayerTV\app\src\main\res\layout\fragment_player.xml", r"D:\Android\project\WebPlayerTV\app\build.gradle.kts", r"D:\Android\project\WebPlayerTV\settings.gradle.kts" ] # 项目根路径(用于保留相对路径结构) project_root = r"D:\Android\project" # 时间戳 timestamp = datetime.now().strftime("%y-%m-%d-%H-%M-%S") # 合并输出文件路径(.txt) output_path_txt = fr".\webplayertv_merged_output_{timestamp}.txt" # 压缩输出文件路径(.zip) output_path_zip = fr".\webplayertv_merged_output_{timestamp}.zip" # 合并逻辑 with open(output_path_txt, 'w', encoding='utf-8') as outfile: for path in file_paths: outfile.write(f"\n\n==================== {path} ====================\n\n") try: with open(path, 'r', encoding='utf-8') as infile: outfile.write(infile.read()) except Exception as e: outfile.write(f"<< 无法读取文件: {e} >>\n") print(f"文件已合并保存到: {output_path_txt}") # 压缩逻辑(保留从 project_root 开始的相对路径结构 + 添加合并输出文件) with zipfile.ZipFile(output_path_zip, 'w', zipfile.ZIP_DEFLATED) as zipf: for file in file_paths: if os.path.exists(file): arcname = os.path.relpath(file, start=project_root) zipf.write(file, arcname=arcname) else: print(f"跳过不存在的文件: {file}") # 添加合并生成的文本文件(只保留文件名) zipf.write(output_path_txt, arcname=os.path.basename(output_path_txt)) print(f"文件已压缩保存到: {output_path_zip}") 📦 示例 .zip 文件内容结构: WebPlayerTV/app/src/main/java/com/example/webplayertv/CardPresenter.kt WebPlayerTV/app/src/main/java/com/example/webplayertv/... WebPlayerTV/app/src/main/AndroidManifest.xml WebPlayerTV/app/build.gradle.kts WebPlayerTV/settings.gradle.kts webplayertv_merged_output_25-08-08-14-22-00.txt <-- 这个是合并文件(无路径)
Flutter + Kotlin 只禁用 Activity 里的某个 WebView 控件
不是禁用整个 MainActivity 的触摸,而是只禁用 这个 Activity 里的某个 WebView 控件。 那就不需要用 window.addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) 因为那个会直接把整个 Activity 的触摸事件都屏蔽掉。 WebView 局部禁用触摸的方式 如果你拿到 WebView 实例,可以这样: 方式 1:直接拦截触摸事件 webView.setOnTouchListener { _, _ -> true // 返回 true 表示消费掉事件,不再传给 WebView } 方式 2:继承 WebView 并重写触摸分发 class NonTouchableWebView(context: Context, attrs: AttributeSet?) : WebView(context, attrs) { override fun onTouchEvent(event: MotionEvent?): Boolean { return false // 不处理触摸 } } 然后在布局里用这个自定义 WebView。 方式 3:让 WebView 不可点击 / 不可获得焦点 webView.isClickable = false webView.isFocusable = false webView.isFocusableInTouchMode = false 但这种方式对部分内嵌滚动的 WebView 可能仍会响应滑动,要配合 setOnTouchListener 效果最好。 如果你是在 Flutter 项目里用 WebView 插件(比如 webview_flutter), 想要在 原生端 禁用,可以通过 平台通道 或直接在插件的 Android 源码里对 WebView 加上 setOnTouchListener 拦截。
Dockerfile with APT and NPM configured to use Aliyun mirrors
✅ 1. Dockerfile with APT and NPM configured to use Aliyun mirrors This is a complete Dockerfile example with: APT sources replaced with Aliyun mirrors NPM registry set to Aliyun’s npmmirror Optional installation of 7z Clean-up of APT cache FROM node:20-bullseye-slim ENV DEBIAN_FRONTEND=noninteractive \ TZ=Asia/Shanghai # Replace APT sources with Aliyun mirrors and install dependencies RUN sed -i 's|http://deb.debian.org|http://mirrors.aliyun.com|g' /etc/apt/sources.list && \ sed -i 's|http://security.debian.org|http://mirrors.aliyun.com|g' /etc/apt/sources.list && \ apt-get update && \ apt-get install -y p7zip curl ca-certificates && \ apt-get clean && rm -rf /var/lib/apt/lists/* # Configure npm to use Aliyun registry RUN npm config set registry https://registry.npmmirror.com WORKDIR /app COPY package*.json ./ RUN npm install COPY . . EXPOSE 12345 CMD ["node", "index.js"] ✅ 2. docker-compose + custom script for mirror configuration You can also use docker-compose to start the container and run a script inside it to configure mirrors at runtime. 🧱 Recommended directory structure: . ├── docker-compose.yml ├── Dockerfile └── scripts/ └── set_aliyun_sources.sh 📄 docker-compose.yml example: version: '3.9' services: mihomo-subserver: build: context: . dockerfile: Dockerfile container_name: mihomo-subserver network_mode: host volumes: -…
HLS调整参数
配置是: hls_fragment 2; # 每个 TS 片段 2 秒 hls_playlist_length 10; # 播放列表保留最近 10 秒的内容 实际效果 TS 文件数量 计算方式:hls_playlist_length / hls_fragment 这里 10s / 2s = 5,所以 大约会有 5 个 TS 文件(而不是 10 个)。 播放列表行为 每 2 秒生成一个新的 .ts 文件。 .m3u8 播放列表始终包含最近 10 秒的 TS 文件(即 5 个)。 旧的 TS 文件会被自动清理(除非 hls_cleanup off)。 延迟 & 性能影响 延迟:客户端通常会有 hls_fragment * 1.5 左右的延迟(约 3s)。 服务器负载:比 hls_fragment 1 更节省 CPU/IO,比默认 hls_fragment 3 延迟更低。 网络适应性:2s 片段比 1s 更稳定,适合大多数直播场景。 是否需要调整? ✅ 适合的情况 希望 降低延迟(2s 片段比 3s 更快)。 想 减少 TS 文件数量(5 个左右,而不是默认 20 个)。 适用于 普通直播、视频会议等中等延迟需求。 ⚠️ 潜在问题 如果 hls_playlist_length 10 太小,可能导致: 播放器缓冲不足(网络差时容易卡顿)。 快进/回放时内容太少(HLS DVR 功能受限)。 推荐优化方案 1. 平衡延迟 & 流畅性 hls_fragment 2; # 2s 片段(降低延迟) hls_playlist_length 20; # 保留 20s 内容(10 个 TS 文件) 延迟:~3s TS 文件数:10 个 适合:大多数直播场景 2. 超低延迟模式 hls_fragment 1; # 1s 片段(最低延迟) hls_playlist_length 10; # 保留 10s 内容(10 个 TS 文件) 延迟:~1.5s TS 文件数:10 个 缺点:CPU/IO 负载较高 3. 节省资源模式 hls_fragment 3; # 3s 片段(默认) hls_playlist_length 30; # 保留 30s 内容(10 个 TS 文件) 延迟:~4.5s TS 文件数:10 个 适合:高并发、节省服务器资源 总结 你的当前配置(hls_fragment 2; hls_playlist_length 10)会生成 5 个…
The meaning of code modifications with `-` and `+`
The meaning of code modifications with - and + In code modifications, the - and + symbols are typically used to indicate changes in the code, commonly seen in diff comparisons (e.g., in version control tools like Git): - (minus sign): Indicates a deleted line (old code) + (plus sign): Indicates an added line (new code) Example: - console.log("Hello World"); // This line was deleted + console.log("Hello GitHub"); // This line was added Other Common Scenarios: Git Diff: When reviewing code changes, - and + highlight modifications. Code Review: On platforms like GitHub/GitLab, red/green colors distinguish deletions/additions in PRs/MRs. Patch Files: .patch files use - and + to mark changes. Advanced Usage: @@ -x,y +a,b @@ indicates the location of changes (y lines starting from line x in the old file, b lines starting from line a in the new file). Three minus signs --- represent the old file, while three plus signs +++ represent the new file. Need a more specific explanation or code example? Let me know the actual context you're looking at.
Variable Scope in JavaScript
--- ### **Variable Scope in JavaScript** In JavaScript, the scope of a variable determines its accessibility within the code. Based on scope, variables can be classified into **global variables** and **local variables (internal variables)**. Below are their definitions and usage methods: --- ### **1. Global Variables** Global variables can be accessed from anywhere in the script and are typically defined outside of functions. #### **Definition:** ```javascript // Global variables var globalVar = "I am a global variable"; let globalLet = "I am also a global variable"; const globalConst = "I am still a global variable"; ``` #### **Characteristics:** - **Scope:** The entire script file. - **Lifetime:** From the point of definition until the page is closed. - **Important Notes:** - Global variables declared with `var` are attached to the `window` object (in browser environments), which may pollute the global namespace. - Global variables declared with `let` and `const` are **not** attached to the `window` object. #### **Example:** ```javascript var globalVar = "I am a global variable"; function test() { console.log(globalVar); // Can access the global…
Installing the Argon theme or plugin for WordPress
Installing the Argon theme or plugin for WordPress is very simple. Here are the detailed steps: --- ### **Method 1: Install via WordPress Admin** 1. **Log in to WordPress Admin** Open your WordPress website, enter your admin username and password, and access the admin dashboard (usually `yourwebsite.com/wp-admin`). 2. **Go to the Plugin/Theme Installation Page** - If installing the **Argon theme**: Click **Appearance** > **Themes** > **Add New** in the left-hand menu. - If installing the **Argon plugin**: Click **Plugins** > **Add New** in the left-hand menu. 3. **Search for Argon** Type **"Argon"** in the search bar and press Enter. 4. **Install and Activate** - Once you find the Argon theme or plugin, click **Install**, and after installation, click **Activate**. --- ### **Method 2: Manual Upload** If you cannot find Argon through the admin search, you can manually download and upload it. 1. **Download the Argon Theme or Plugin** - Visit the official GitHub page or website for Argon and download the latest version of the Argon theme or plugin (usually a `.zip` file). - Argon…
Python download curl
Improved Code ```python def download_7z_file(config): """ Download a 7z file with support for retries, timeout, SSL verification, redirects, and custom headers. :param config: A dictionary containing download configurations. Supported keys: - max_retries: Maximum number of retries, default is 3. - timeout: Timeout in seconds, default is 30. - verify_ssl: Whether to verify SSL certificates, default is True. - allow_redirects: Whether to allow redirects, default is True. - headers: Custom HTTP headers, default is None. :return: Returns True if the download is successful, otherwise False. """ global common_config, IS_WINDOWS # Get the list of download URLs urls = common_config.get('urls', []) if not urls: print("Error: No download URLs found in the configuration.") return False # Get the output file path output_file = common_config.get('output_7z_path', {}).get(IS_WINDOWS) if not output_file: print("Error: No valid output file path found in the configuration.") return False # Default configuration default_config = { 'max_retries': 3, 'timeout': 30, 'verify_ssl': True, 'allow_redirects': True, 'headers': { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36' } } # Merge user configuration with default configuration…