普通视图

Received before yesterday

Bilibili、YouTube等视频网站频繁出现缓冲卡顿的解决方案

2025年6月9日 23:05

某一天开始,我发现电脑在使用外接 USB 音响播放 B 站视频时,大约在播放 1、2 分钟后,会突然卡住,缓冲一段时间后再开始播放,之后就一直重复缓冲、播放几秒到十几秒再次缓冲的过程,之后发现不仅仅是 bilibili,其实 YouTube 等其他视频网站都存在这个问题。
在一番搜索查找后终于知道问题所在:这个看似是网络卡顿的现象,居然是瑞昱(Realtek)的音频驱动导致的,不用 Realtek 驱动就可以解决问题。

Bilibili、YouTube等视频网站频繁出现缓冲卡顿的解决方案


播放缓冲卡顿故障表现细节

故障前提

  1. 必须是win10或win11系统
  2. 使用瑞昱(Realtek)声卡并安装了 Realtek 官方驱动

故障表现

  1. 在使用外接USB音响、蓝牙耳机、有线耳机、笔记本自己的音响等播放 Bilibili、YouTube、奈飞 等视频网站内视频时。如果视频一直在播放大概率不会出问题。
  2. 如果中间暂停视频一段时间后再播放,再次播放一段时间后会突然卡住,显示正在缓冲,缓冲一段时间后再开始播放,之后就一直重复缓冲、播放几秒到十几秒再次缓冲的过程。(如果暂停后马上恢复播放则大概率不会出现问题)

  3. 此时网络实际很通畅、使用视频网站的测试工具也显示不存在网络问题。

  4. USB音响可以通过拔下再插上恢复正常,蓝牙耳机可以通过关闭蓝牙再打开恢复正常,最不济可以通过重启电脑恢复正常。

  5. 但是过一段时间又出现上述状况,而且浏览器类型(起码我测试chrome、edge、Firefox都一样)、浏览器扩展(无痕模式、安全模式都有这个问题)、网络情况(获取直链后用工具下载时无任何问题)、用什么播放器(用potplayer播放网络URL也会出现这个问题)等等都无关。

故障解决

定位故障点

这个问题困扰了我很久,但奇怪的是我用蓝牙耳机播放时几乎从来不会出现这个问题,不过因为我一般都是用蓝牙耳机为主,对我影响不大,所以这个问题也就一直放着没管。

直到我看到了这篇文章《如何解决B站暂停视频后一直缓冲问题 – 龙鲲博客》 如同醍醐灌顶,我电脑的现象和博主的简直如出一辙。至于为何我用蓝牙耳机反而不会像原文所说的那样有问题呢,可能因为我使用了替换的蓝牙驱动吧。

卸载Realtek(R) Audio 的官方驱动

简单说就是 Realtek(R) Audio 的官方驱动有bug,卸载官方驱动后换成 Windows 自带的通用驱动,并防止 Windows 自动更新将驱动为 Realtek(R) Audio 官方驱动即可。

  1. 在开始菜单按钮上右键或在开始菜单里搜索「设备管理器」,找到「设备管理器」启动。
  2. 点开「声音、视频和游戏控制器」,找到「Realtek(R) Audio」,右键单击,选择「更新驱动程序」
    更新驱动程序

  3. 点击 「浏览我的计算机以查找驱动程序软件」

  4. 点击 「让我从计算机上的可用驱动程序列表中选择」

  5. 取消勾选「显示兼容硬件」,在左侧厂商框里找到并点击「Microsoft」,在右侧型号框内找到「High Definition Audio 设备 版本:XX.XX.XXX.YYYY [YYYY/MM/DD]」,选择版本号最大,日期最近的那个。

进阶步骤

因为有可能 windows 系统更新时还会自动安装 Realtek(R) Audio 的官方驱动,所以最好还是禁止一下。

通过组策略禁止自动更新驱动

仅限 Windows 专业版、企业版、服务器版等有组策略的系统
1. 按 「Win + R」,输入 「gpedit.msc」,回车打开「组策略编辑器」

  1. 依次展开:「计算机配置」 → 「管理模板」 → 「Windows 组件」 → 「Windows 更新」 → 「管理从 Windows 更新提供的更新」 → 双击左侧的「Windows 更新不包括驱动程序」 → 选择 已启用 → 点击「确定」

  1. (可选步骤)以管理员身份,在命令行中执行 gpupdate /force 让组策略强制生效。

通过注册表禁止自动更新驱动

  1. 按 「Win + R」,输入 「regedit」,回车,同意 UAC 提示。(如果有的话)
  2. 依次展开:计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate
    在窗口右侧,右键 → 新建 → [DWORD (32 位) 值」,命名为 ExcludeWUDriversInQualityUpdate

  1. 双击该值,将数值数据改为 「1」 → 点击 「确定」
  2. 重启系统生效。

(可选) 进行一次【完全重启】

因为 windows 从 win8 开始默认会开一个叫“快速启动”的小功能。
快速启动结合了传统关机和休眠模式的特点:在系统关闭或重启时,会仅将内核会话和设备驱动状态保存到硬盘的 hiberfil.sys 文件中。

如果你的系统硬件较新,系统也是比较新的win10、win11版本,理论上系统会在你更改驱动后自动将下一次启动进行完整重启,不执行“快速启动”。
但是这只是理论上,偶尔还是会出现。更新了驱动,系统还是来个快速启动,直接获取保存的驱动状态,就有可能导致音频驱动加载出错, Realtek(R) Audio 音频设备直接消失。如果出现了这个情况请再尝试下边的步骤解决问题。

方案一:彻底关闭快速启动
  1. 右键点击 开始菜单 → 选择 “终端(以管理员身份运行)” 或 “命令提示符(以管理员身份运行)”。
  2. 以管理员身份运行powercfg /h off此命令会同时禁用休眠和快速启动。如需重新开启,输入 powercfg /h on
  3. 代价就是每次系统启动需要的时间多了5、6秒(SSD),如果你是机械硬盘可能会更久比如20多秒。
方案二:只完整重启一次,不关闭快速启动
  1. 点击开始菜单的 “电源”图标 → 按住 Shift键 同时点击 “重启”。
  2. 系统进入 “高级启动”界面 → 选择 “继续退出并进入Windows”。

The post Bilibili、YouTube等视频网站频繁出现缓冲卡顿的解决方案 appeared first on 秋风于渭水.

  •  

如何正确拉取超大体积的git项目——开发小技巧

2025年5月14日 15:48

最近遇到一个体积相当大的仓库(40GB+),结果在安利给群内小伙伴时,很多人遇到了直接使用 git clone 克隆仓库到本地时,对本地网络的稳定性有巨大挑战,一旦网络波动导致传输中断,就只能从头下载。
很多人拉项目时习惯git clone一把梭哈,这并不是一个很好的习惯,众所周知国内访问github属于玄学,而且有些项目非常大,搞不好需要好几个小时才能拉取完,长时间+不稳定的网络,很容易出意外。本文就是介绍两种应对超大体积项目的拉取的办法「Git LFS」和「Git fetch」。


Git 的 git clone 命令本身是不直接支持断点续传的,git clone 本质上是创建一个新仓库,并一次性拉取远程所有数据(包括提交历史、分支、标签等)。如果中途中断本地目录会处于不完整状态,直接重试 git clone 会失败,如果你退出终端本地目录也会被清空。

使用 Git Large File Storage(Git LFS)

简单介绍一下 Git LFS

Git Large File Storage(Git LFS)是一个用于管理大型文件的Git扩展工具,旨在解决Git原生对大文件支持不足的问题。

Git LFS 优点

  • Git LFS用轻量级文本指针(如oid sha256:…)替换实际大文件,避免仓库臃肿。
  • 大文件内容存储在专用服务器(如GitHub LFS、块储存、自建储存、CDN),仅按需下载。
  • 支持单个文件GB级别存储,突破Git对文件大小的限制。(比如 github 是单文件小于100MB,单文件大于50MB会出现警告)
  • 因为大文件实际是分离储存的,可以优化拉取速度。
  • 安装Git LFS 并配置好后,日常 git 操作时,几乎是无感的,Git LFS 会自动处理大文件。

Git LFS 缺点

  • 需要项目创建者配合从一开始就使用 Git LFS,如果项目没有采用,对于想要克隆拉取项目的人是没有办法去使用 Git LFS 的。
  • 额外的大文件储存和下载都是需要开发者额外掏钱的,像是GitHub就只有10 GiB的免费空间和流量可用,超过的部分需要额外收费。(如果你是pth之类的AI模型文件,huggingface之类的平台给了免费的 LFS 空间)

不要 git clone 一把梭哈,改用 git fetch 分步拉取

简单介绍一下 git fetch 分步拉取

Git LFS 更多面对的是项目中部分文件体积很大的情况,比如Unity项目中的.asset文件、PSD源文件、CSV数据集。但还有一种情况,项目中每个文件体积都不大,可能只有几兆到十几兆,但是项目中文件数量极多,几百上千个,加到一起后整个项目体积也到了 GB 规模。这个时候更适合分步拉取的方式。

和 git clone 相比 git fetch 的优势

  • git fetch 基于 Git 对象模型,天然支持断点续传。
  • 即使多次中断,只要本地 .git 目录未损坏,均可通过反复执行 git fetch 逐步补全数据。
  • 如果中断期间远程仓库新增了提交,git fetch 会同时下载新增内容和未完成的旧内容,最终保持本地与远程一致。

和 git clone 相比 git fetch 的缺点

除了操作稍微多了几个步骤,没任何额外的缺点。

git fetch 分布拉取的方法

  1. 先手动创建空仓库并构建.git文件
mkdir your-repo && cd your-repo
git init
git remote add origin https://github.com/user/repo.git
  1. 分步拉取数据
git fetch origin --progress  # 如果中间传输中断,就在目录下再执行一次这个命令即可。
  1. 等待拉取完毕(以下仅为举例,请根据实现终端显示为准),这时候项目所有内容都会被打包在.git/objects/pack目录下的.pack文件内。
Resolving deltas: 100% (9999/9999), done.
From https://github.com/user/repo.git
 * [new branch]      master     -> origin/master
 * [new tag]         v1.0       -> v1.0
 * [new tag]         v1.1       -> v1.1
 * [new tag]         v1.2       -> v1.2
 * [new tag]         v2.0       -> v2.0
 * [new tag]         v2.1       -> v2.1
 * [new tag]         v2.2       -> v2.2
 * [new tag]         v2.3       -> v2.3
 * [new tag]         v2.4       -> v2.4
 * [new tag]         v3.0       -> v3.0
  1. 将需要的分支检出,比如我们检出 master 主分支。
git checkout master
  1. 其他优化建议

使用浅克隆减少首次下载量,比如只拉取最新分支

git clone --depth 1 https://github.com/user/repo.git

之后再补全历史(或者就干脆不补全,节约点空间)

git fetch --unshallow

总结

总的来说 Git LFS 主要是应对项目中出现几个巨大体积文件的情况,git fetch 主要是应对一次开机无法完成下载的超大型仓库或不稳定网络环境,比直接 git clone 一把梭哈更加灵活。

PS:顺带提一嘴,如果多次中断和重新拉取,可能会在.git/objects/pack目录下出现很多个.pack文件。如果需要清理的的话,在项目目录下执行git gc --auto
再PS:不用在意.pack文件的巨大体积,因为工作目录下你看到的具体文件,是通过硬链接、符号链接构建的,工作目录内的文件和 .pack 中的对象共享同一份数据,并不会真实占用双倍物理空间。实际占用大概是1.2~1.3倍空间,因为.pack文件还是有一定的压缩的。

The post 如何正确拉取超大体积的git项目——开发小技巧 appeared first on 秋风于渭水.

  •  

GitHub 阻止中文用户访问了 吗?(附临时解决方案)

2025年4月29日 14:43

引言

今天群里不小小伙伴都表示在访问 GitHub 时遇到了「对本网站的访问受到限制」 (access to this site has been restricted) 、「访问已被限制」(Access has been restricted)的提示。

之前 GitHub 曾因失误部署了屏蔽所有中国 IP 地址的规则,中国 IP 地址访问时会出现禁止访问提示,之后 GitHub 更新了规则,中国 IP 地址重新可以访问了。GitHub 给出的解释当初是部署错误。

如果之前是失误那现在肯定就是故意的了,这次如果你使用代理访问,并且使用的是中文 (仅限 zh_CN),那么你就有可能被 GitHub 阻止访问。



情况

那么问题来了,GitHub 是打算主动屏蔽所有中国用户吗?
经过我和群内小伙伴们的测试,答案是:应该不是,看起来更像是 GitHub 针对中文爬虫设定的反爬措施。

实际触发这个限制的条件逻辑是:
1. 基于IP或者UA等判断(比如是不是机房IP,代理IP,常见爬虫UA,模拟浏览器头)
2. 基于一些流量模型判断(比如访问频率过高,访问范围过广)
3. 是不是请求头的语言部分包含 zh_CN
4. 只有上边每一层检测,都触发了“是”,那么才会触发访问限制。
5. 并且这个限制是分功能的,不是完全不可用,有可能你可以在浏览器中浏览项目,编辑文件,但你这时却无法在 浏览器内 raw,无法在终端里 git clone。

也就是说,对于正常的中文用户,如果你的IP比较干净,不是使用奇形怪状的浏览器访问,都是可以正常访问 GitHub 的。

碎碎谈

感觉 GitHub 大概率是为了反爬虫、反抓取,毕竟现在 AI 训练爬虫在对 GitHub 疯狂抓取用来训练模型。微软虽然家大业大也没钱了嘛。不过国内爬虫是有多少啊,都能让 GitHub 把语言当作一个过滤条件了。之前那次屏蔽中国IP,搞不好起因也是这个,只是个某个管理错误的把中国的IP段全部给拉黑了。
不过把请求头语言项作为爬虫检查项,意义不大吧,这个特征也不难改……

如果你使用的代理 IP 质量不佳,IP 被万人骑,实在太黑了,导致被 GitHub 拦截了,比较简单的办法就是:
– 换个IP
– 使用一些浏览器请求头修改扩展,将请求头语言部分改成 accept-language = en_US,en;q=0.9,zh;q=0.8 (英语优先,中文备选)。
– 直接去浏览器设置里修改网页首选语言(所有网页都会收到影响,比如不登录状态下谷歌和bing就会给你返回英文网页和英文搜索结果优先了)

以Header Editor 4.1.1 为例,修改请求头

启用请求头修改前,部分位于https://camo.githubusercontent.com的图报HTTP429「Access has been restricted」

启用请求头修改后,马上恢复正常。

The post GitHub 阻止中文用户访问了 吗?(附临时解决方案) appeared first on 秋风于渭水.

  •  

如何快速批量检索损坏的图片文件—python开发学习笔记(一)

2025年3月19日 20:20

为了解决几十万量级图片库内异常图片的检测,折腾出了一个基于 python 的图片检测程序。


一、混乱的图片仓库

用前一段发现的本地 AI 图片视频搜索引擎 MaterialSearch 整理十几年间积累的几十万张图片时,遇到了一个令人崩溃的场景:有上百张图片报损坏,经过部分核查,很多文件打开后呈现诡异色块,亦或者只有半截图,还有些文件大小为 0 KB。这些损坏的图片零散的散布在数千个子文件夹中,手动一个一个检查无异于大海捞针,累死也搞不定。于是 VS code 启动!!


二、初版方案

用 Pillow 暴力验证,直接用 Pillow verify()看看是否报错来解决。

代码V1.0方案(基础检测逻辑)

from PIL import Image

def check_img_v1(path):
    try:
        Image.open(path).verify()
        return True
    except:
        return False

V1.0方案的情况
1. 误报文件:很多图片会报损坏,但是用图片浏览器打开却十分正常,经过研究之后才知道,原来大量网站在使用一种叫做渐进式JPEG的技术,通过将图像数据分为多个扫描逐层渲染,可以在网速不好时图片先绘制出低分辨率的模糊轮廓,随着数据被下载逐步变为清晰图像(现代图片编码如WEBP、AVIF也都有类似的渐进式加载机制)。这导致需要完整解码才能验证所有扫描数据。因此被verify()误认为损坏。
2. 漏检文件:未完整下载的图片有时也能通过验证。
3. 性能问题:慢,按照测试计算,10万张图片的检测起码需要耗时4、5小时了。


三、改进方案

经过对 MaterialSearch 日志报错图片的抽查,发现损坏的文件主要是文件不完整导致的半截图,于是我打算改为:先检查文件结尾是否存在结束符来判定图片是否损坏,然后再做进一步检查。

代码V2.0(尾部校验部分代码)

def check_img_v2(path):
    with open(path, 'rb') as f:
        f.seek(-32, 2) #只用获取文件最后32字节就行
        trailer = f.read()
        if path.lower().endswith('.jpg'):
            return trailer.endswith(b'\xff\xd9')  # JPEG的结束符
        elif path.lower().endswith('.png'):
            return trailer.endswith(b'\xaeB`\x82')  # PNG的IEND块

V2.0方案的情况
1. 捕获到了异常文件 :下载一半的文件确实被检测出来了。
2. 检测了个寂寞 :如果图片附加了元数据,图片文件很可能就不是以\xff\xd9结尾了,结果就是1000张的测试图片,在尾部检测部分逻辑,有800多张都报了损坏……想快速检查了个寂寞。


四、再次优化

使用img.load() 强制加载所有数据。对渐进式jpeg图片做特殊处理逻辑。

代码V3.0(验证部分的修改)

def check_img_v3(path):
    try:
        with open(path, 'rb') as f:  
            img = Image.open(f)
            img.load()  # 强制加载完整图片

            # 特殊处理渐进式JPEG
            if img.format == 'JPEG' and 'progressive' in img.info:
                img.tile = []  

            return True
    except Exception as e:
        print(f"损坏文件: {path} | 错误类型: {type(e).__name__}")
        return False

V3.0方案的情况
1. 漏报率下降了很多
2. 渐进式JPEG兼容处理
3. 打印异常类型方便处理
4. 实际代码中自己傻逼了在verify()之后调用load(),导致文件指针不可用,说人话就是:代码逻辑中verify()做完检查后,就把图片文件关闭了,load()啥也获取不到。
5. 性能就很一般了,基本和初版差不多的速度。


五、终局之战

又经过一番研究和查证其实 Pillow verify()对渐进式图片检测是没问题的,误报率并没有我在V1测试时那么高,只是我本地环境的 Pillow 版本不够新而已,但也确实会有漏报。只用load()也会有漏报,有一点误报可以接受,但是漏报就无法接受了,所以还是需要联合检查。

最终决定采用如下逻辑
1. 先检测文件路径是否存在,收集所有路径。
2. img.verify()先上
3. 同一个循环内使用img.load()再来一次检测
4. 并行处理加快处理速度
5. 不在控制台显示扫描 log,毕竟绝大部分图片都是好的,没问题的显示出来无意义,只显示有问题的又很容易看起来像是卡住了,所以用 tqdm 做个进度条。还能大概估计下完成时间。
6. 用 jinja2 做个 html 格式的检测报告,毕竟在终端里复制粘贴起来也不方便。

代码V4.0(完善使用)

实在太长了就放github上了:img_validator.py

命令:python img_validator.py <"目录路径"> [并发数]

ex:python img_validator.py "D:\Download\图片" 8

最终会在脚本的同级目录下生成 html 格式的检测报告image_validation_report.html

  • 路径最好用””框住
  • 并发数可以不填,默认使用CPU全部线程。除非你用非常大的图,不然全线程跑也费不了多少CPU占用。
  • 理论上 10W 张图片在 12 线程下,用时应该半小时都不到,不过实际上受制于仓库盘使用的是 HDD 只能到 20~40files/s,机械硬盘的读出速度跟不上检测速度,特别是到最后20%的时候,速度更是掉到只有个位数了。18W 张图片的文件夹,检测用时接近5个小时,平均速度 ≈ 11 files/s
  • windows 和 unix 系统都可用,代码会自动处理两者的路径差异。

为什么会有这么多图片损坏

自己十年前写的P站抓取代码不完善,如果因为网络超时导致图片下载失败,爬虫会重试,但是之前损坏的图片有可能并不会被正确清除(删除部分代码没有正确处理超长文件名和带特殊符号的文件名),虽然带问题代码只使用了从14年到16年这大约一坤年,但是也积累了接近 600 张问题文件。不过倒是挺奇怪的,抓全年龄的部分出现大量这种问题,抓R18的几乎就没出错过,这是又为什么呢,沉思中…………

The post 如何快速批量检索损坏的图片文件—python开发学习笔记(一) appeared first on 秋风于渭水.

  •  

Material Search — 本地 AI 图片视频搜索引擎部署教程

2025年2月28日 12:06

Material Search 是一个基于 AI 的本地素材搜索引擎。扫描本地的图片以及视频,可以用自然语言进行查找。
实现中文语义下的 以图搜图、截图搜视频、查找本地素材、根据文字描述匹配画面、视频帧搜索、根据画面描述搜索视频。找素材再也不用费力去一个个翻 tag 了。


源码部署(稳定推荐)

准备运行环境

首先,默认看本文的照片视频都是存在 windows 系统上的,以下都是基于 win 系统的操作
需要准备3个或2个东西
Python 3.11.7,Git ,CUDA(不是N卡的不用装CUDA),这三个的下载地址在文章的最前边。
视情况,你可能还需要一个魔法上网工具(假设你的魔法上网工具代理在127.0.0.1:6808)

安装 Python 3.11.7 与 pip

我这里采用直接系统内安装Python 3.11.7的方式(其实安装Python3.12.9也是可用的,看你需求了。)
如果你会用Miniconda,也可以用Miniconda实现Python多版本切换。

  1. 访问 Python3.11.7 下载页面
  2. 把页面拉到底,找到【Windows installer (64-bit)】点击下载

  3. 安装是注意,到这一步,需要如下图这样勾选 Add Python to PATH

    然后再点上边的 Install Now
    python

  4. 安装完成后,命令行里输入Python -V,如果返回Python 3.11.7那就是成功安装了。

  5. 命令行里输入 python -m pip install --upgrade pip安装升级pip到最新版。

安装 Git

  1. 访问 Git 下载页面

  2. 点击【Download for Windows】,【64-bit Git for Windows Setup】点击下载

  3. 一路下一步安装

  4. 命令行运行git --version,返回git version 2.XX.0.windows.1就是安装成功了。

安装 CUDA (nvidia显卡用户步骤,AMD 和 Intel 显卡用户请跳过这一步)

  1. 命令行运行nvidia-smi,看下自己显卡支持的 CUDA版本
    (升级显卡驱动可能会让你支持更高版本的 CUDA)

  2. 接下来前往英伟达 CUDA 官网,下载对应版本。
    注意请下载,你对应的版本号最高的版本,比如我的是11.7的,那就下11.7.1(这里最后的.1意思是,11.7版本的1号升级版)

  3. 选你自己的操作系统版本,注意下个离线安装包【exe [local]】,在线安装的话,速度还是比较堪忧的。

正式安装 Material Search

以下假设你当前文件目录是D:\github\

建立虚拟环境并安装依赖

避免玩其他 Python 项目时出现项目依赖冲突问题

  1. 安装虚拟环境工具(virtualenv)
pip install virtualenv
pip install virtualenvwrapper
# virtualenvwrapper一定要在virtualenv后安装
  1. 创建一个新的虚拟环境:
virtualenv MSWenv

这将在当前目录下创建一个名为”MSWenv”的虚拟环境。

  1. 激活虚拟环境:
D:\github\MSWenv\Scripts\activate

这将激活虚拟环境,并将您的终端提示符更改为虚拟环境名称类似这样

(MSWenv) D:\github> ▏

拉取 Material Search 源码并安装依赖

# 拉取仓库
git clone https://github.com/chn-lee-yumi/MaterialSearch.git

# 进入目录
cd MaterialSearch

# 安装全部依赖(N卡 GPU运行)
pip install -U -r requirements.txt --index-url=https://download.pytorch.org/whl/cu124 --extra-index-url=https://pypi.org/simple/

# 安装全部依赖(A卡、I卡 GPU运行)
pip install -U -r requirements_windows.txt

# 安装全部依赖(CPU运行)
pip install -U -r requirements.txt 

注意:
1. N卡 GPU运行里的cu124 如果你运行环境中的 CUDA 小于 12.4 的话,请写成你实际的版本
2. 如果你这会儿还拿不准用 GPU 还是 CPU 运行的话,请先按照【安装全部依赖(A卡、I卡 GPU运行)】执行,这样安装后也可以支持CPU运行。

  1. 最新的更新中作者引入了 torch-directml 实现兼容AMD 和 Intel 等非 nvida 显卡,这个东西咋说呢,torch-directml是用 DX12 作为中间层,构建了兼容 torch 的 API 接口,多少会有点性能损失,所以N卡用户还是老老实实用torch 2.X+CU12.X

尝试启动 Material Search

按照以下命令启动项目

python main.py
  • 首次运行会自动下载模型。下载速度可能比较慢,请耐心等待。如果网络不好,模型可能会下载失败,这个时候重新执行程序即可。
  • 如果想使用”下载视频片段”的功能,需要安装ffmpeg。如果是Windows系统,记得把ffmpeg.exe所在目录加入环境变量PATH,可以参考:Bing搜索
  • 如果不知道在你设备上 CPU 和 GPU 那个更快,可以在上边步骤中先走 【安装全部依赖(GPU运行)】,在依赖安装完毕后执行python benchmark.py,运行基准测试。

正式运行 Material Search

Material Search 配置设置

建议通过在项目根目录创建.env文件修改配置

.env文件配置示例

# 下面添加扫描路径,用英文半角逗号分隔
ASSETS_PATH=D:\Videos,D:\Pctures
# 如果路径或文件名包含这些字符串,就跳过,逗号分隔,不区分大小写
IGNORE_STRINGS=thumb,avatar,__MACOSX,icons,cache
# 图片最小宽度,小于此宽度则忽略。不需要可以改成0
IMAGE_MIN_WIDTH=64
# 图片最小高度,小于此高度则忽略。不需要可以改成0。
IMAGE_MIN_HEIGHT=64
# 视频每隔多少秒取一帧,视频展示的时候,间隔小于等于2倍FRAME_INTERVAL的算为同一个素材,同时开始时间和结束时间各延长0.5个FRAME_INTERVAL
FRAME_INTERVAL=2
# 视频搜索出来的片段前后延长时间,单位秒,如果搜索出来的片段不完整,可以调大这个值
VIDEO_EXTENSION_LENGTH=1
# 素材处理批次大小,过大会导致显存不足而无法运行或拖慢速度。
SCAN_PROCESS_BATCH_SIZE=4
# 支持的图片拓展名,逗号分隔,请填小写
IMAGE_EXTENSIONS=.jpg,.jpeg,.png,.gif,.heic,.webp,.bmp
# 支持的视频拓展名,逗号分隔,请填小写
VIDEO_EXTENSIONS=.mp4,.flv,.mov,.mkv,.webm,.avi
# 监听IP,如果想允许远程访问,把这个改成0.0.0.0
HOST=127.0.0.1
# 监听端口
PORT=8085
# 运行模式
DEVICE=cuda
# 使用模型
MODEL_NAME=OFA-Sys/chinese-clip-vit-base-patch16
# 数据库保存位置
SQLALCHEMY_DATABASE_URL=sqlite:///./instance/assets.db
# 是否web页启用登录验证功能,如需启用改为true
ENABLE_LOGIN=False
# 登录用户名
USERNAME=admin
# 登录密码
PASSWORD=123456
# 是否自动扫描设置路径下的文件变化,如果开启,则会在指定时间内进行扫描,每天只会扫描一次
AUTO_SCAN=False
# 自动扫描开始时间
AUTO_SCAN_START_TIME=22:30
# 自动扫描结束时间
AUTO_SCAN_END_TIME=8:00
# 是否启用文件校验(如果是,则通过文件校验来判断文件是否更新,否则通过修改时间判断)
ENABLE_CHECKSUM=False
  • 你发现某些格式的图片或视频没有被扫描到,可以尝试在IMAGE_EXTENSIONSVIDEO_EXTENSIONS增加对应的后缀。
  • 小图片没被扫描到的话,可以调低IMAGE_MIN_WIDTHIMAGE_MIN_HEIGHT重试

  • 运行模式(DEVICE)可以写的选项有auto/cpu/cuda/mps`四种,如果写 auto 的话,优先级是这样的:cuda > mps > directml > cpu

  • 一般来说默认的小模型就够用了,如果你显存大或者感觉小模型的精度不够,可以改成更大的模型
    更换模型需要删库重新扫描!否则搜索会报错。数据库路径见SQLALCHEMY_DATABASE_URL参数。

  • 模型越大,扫描速度越慢,且占用的内存和显存越大。
    如果显存较小且用了较大的模型,并在扫描的时候出现了”CUDA out of memory”,请换成较小的模型或者改小SCAN_PROCESS_BATCH_SIZE。如果显存充足,可以调大上面的SCAN_PROCESS_BATCH_SIZE来提高扫描速度。
    因为目前的N卡驱动,支持了内存显存融合,超过物理显存的模型会被放在内存中,不会直接炸显存,只要你电脑显存+内存还没满,超过物理显存后,只会体现为扫描速度非常的慢,大概会慢3倍左右的速度(比如,设置1线程,扫描用时100秒;设置成4线程,用时反而是300秒,线程越多速度反而越慢)
    所以,一定要确保扫描时电脑留有足够的可用显存,可以启动任务管理器——性能——GPU——专用GPU内存查看实际显存占用。不要让斜杠前的数字过于接近斜杠后的数字(比如:10.7/12GB就是良好配置,而11.8/12GB就不太好了)

    • 4G显存推荐参数:小模型,SCAN_PROCESS_BATCH_SIZE=8
    • 4G显存推荐参数:大模型,SCAN_PROCESS_BATCH_SIZE=2
    • 8G显存推荐参数1:小模型,SCAN_PROCESS_BATCH_SIZE=16
    • 8G显存推荐参数2:大模型,SCAN_PROCESS_BATCH_SIZE=4
    • 超大模型最低显存要求是6G,且SCAN_PROCESS_BATCH_SIZE=1
    • 其余显存大小请自行摸索搭配。
  • 支持的模型列表
    • 中文小模型: OFA-Sys/chinese-clip-vit-base-patch16
    • 中文大模型:OFA-Sys/chinese-clip-vit-large-patch14-336px
    • 中文超大模型:OFA-Sys/chinese-clip-vit-huge-patch14
    • 英文小模型: openai/clip-vit-base-patch16
    • 英文大模型:openai/clip-vit-large-patch14-336

构建 Material Search 一键启动脚本

  1. 目录下新建一个文件myrun.txt
  2. 打开填写以下内容
call D:\github\MSWenv\Scripts\activate
python main.py
pause
  1. 改后缀名为myrun.bat以后启动直接运行这个文件就好了。

  1. 注意不要关闭那个黑乎乎的CMD窗口,不用管那行红字,那只是提示工具的web页是用的Werkzeug运行的,只要你用这个工具库就会有这个提示。
  2. 打开浏览器访问最后提示的http://127.0.0.1:8085

windows 整合包(省事)

  1. 下载整合包
  2. 下载整合包后,使用最新版 7-Zip (V24.0),winRAR(V7.0)解压缩(注意:使用好压快压啥的软件解压缩,可能会报错)。

MaterialSearchWindows.7z整合包带OFA-Sys/chinese-clip-vit-base-patch16模型。MaterialSearchWindowsLarge.7z整合包带OFA-Sys/chinese-clip-vit-large-patch14-336px模型。

一般而言OFA-Sys/chinese-clip-vit-base-patch16模型已经足够日常使用,如果效果不佳并且显卡显存足够大(8G以上),可以尝试MaterialSearchWindowsLarge.7z整合包。

  1. 解压后请阅读里面的使用说明.txt。整合包会自动选择独显或核显进行加速。

docker 部署 (不是很推荐)

docker 想要搞GPU加速 比较容易遇到兼容性问题,除非你用于 NAS 等不方便源码部署的平台。

version: "3"

services:
  MaterialSearch:
    image: yumilee/materialsearch:latest # 支持amd64和arm64。
    # image: registry.cn-hongkong.aliyuncs.com/chn-lee-yumi/materialsearch:latest
    # 托管在阿里云的镜像,如果在国内访问 DockerHub 有困难可以用这个。
    # image: registry.cn-guangzhou.aliyuncs.com/chn-lee-yumi/materialsearch:latest
    # 托管在阿里云的镜像,仅作备份用,这个可能不是最新的。
    restart: always # 容器只要宕机了就重启
    ports:
      - "8085:8085" # 映射容器的8085端口到宿主的8085端口(宿主端口:容器端口)
    environment: # 下边的前边2行别动。想加配置项往后面续。
      - ASSETS_PATH=/home,/mnt
      - SKIP_PATH=/tmp
      #- DEVICE=cuda
      #- IGNORE_STRINGS=thumb,avatar,__MACOSX,icons,cache
      #- IMAGE_MIN_WIDTH=64
      #- IMAGE_MIN_HEIGHT=64
    volumes: # 将宿主的目录挂载到容器里(修改本地挂载路径请修改冒号前的路径,不要动冒号后的东西)
      - /srv/MaterialSearch/db:/MaterialSearch/instance/ #挂载数据库到本地
      - /home:/home # 挂home到本地
      - /mnt:/mnt # 挂mnt到本地
    # 如果使用GPU,就取消注释下面的内容,并在上面environment处添加DEVICE=cuda
    #deploy:
    #  resources:
    #    reservations:
    #      devices:
    #        - driver: nvidia
    #          count: all
    #          capabilities: [ gpu ]
  • docker部署仅amd64架构下支持GPU加速,arm64架构下只可用CPU,docker内模型为OFA-Sys/chinese-clip-vit-base-patch16
  • 想改具体配置可以参考 .env文件内容,往environment:项下加配置。

开始使用 Material Search

简单介绍一下

  1. 第一次使用需要先点击【扫描】按钮让程序本地素材做扫描生成数据库。
  2. 扫描速度,我写本文时用的 GPU 是 N卡 1650 ,大概 1图·1线程/秒。4G显存小模型可以开8线程,1小时理论可以扫2W多张图。视频处理速度大概是图片的三分之一,毕竟多了截取多个视频帧的步骤,默认是2秒一个关键帧,基本就是1小时的视频需要扫描1小时……
  3. 之后就可以用文字搜图,搜视频了,支持自然语言搜索,但描述请一定简单准确,毕竟用的模型参量也没那么大嘛
  4. 扫描图片需要的时间比较长,不过搜起来的速度还是很快的,我尝试在我的CPU:J4150,内存:8GB的 NAS 上部署,匹配阈值为0的情况下,大概1秒可以进行20000次图片匹配,如果提高匹配阈值为10,则大概可以提升到每秒大约35000次图片匹配。
  5. 搜视频时,如果结果中的视频很多且视频体积太大,电脑会卡。毕竟又不是剪辑工作站,一般人电脑那会同时开一堆视频的。所以建议搜索视频时,右侧那个【Top X】不要超过6个。

常见报错

报错 以一种访问权限不允许的方式做了一个访问套接字的尝试

说明默认端口8085已经被占用了,把.env文件中的PORT=8085随便改成一个 1开头的5位数试试。

报错 not enough memory: you tried to allocate 123456789 bytes.

内存不足,显存不足,最简单就是换个更好的电脑吧

报错 AssertionError: Torch not compiled with CUDA enabled

原因是 你试图用N卡的GPU跑,但是你安装的 Torch 不支持 CUDA,是仅支持 CPU 的版本
先执行命令:

python -c "import torch; print(torch.cuda.is_available())"

如果返回的是False,说明安装的 Torch 不支持CUDA,是仅支持CPU的,需要执行了下面的命令安装支持cuda的版本:

pip install torch>=2.0 -f --index-url=https://download.pytorch.org/whl/cu124

The post Material Search — 本地 AI 图片视频搜索引擎部署教程 appeared first on 秋风于渭水.

  •  

随机图片API:基于 Cloudflare Worker + 微博图床

2025年2月18日 15:01

一个全白嫖的免费随机图片 API 实现,通过使用免费的 Cloudflare Worker 与免费的微博相册实现。
通过使用 Cloudflare Worker 反向代理微博图床内图片实现:1、绕过微博防盗链。2、避免网页端看到微博图片链接从而查找到图片发布者的微博。

随机图片API:基于 Cloudflare Worker + 微博图床


初步实现随机图片 API

首先也是最简单的,随机从图片链接中抽一个,返回结果,简单粗暴,直接写进代码里,在图片数量在2K行以内基本不用太担心性能问题。

addEventListener('fetch', event => {
    event.respondWith(handleRequest(event.request))
})
async function handleRequest(request) {
    var background_urls = [
'https://ww2.sinaimg.cn/large/be6ad69bgw1eys2ubi8loj218g0p0h3y.jpg',
'https://ww4.sinaimg.cn/large/be6ad69bgw1eys2ubqm6ij218g0p0ql4.jpg',
'https://ww3.sinaimg.cn/large/be6ad69bgw1eys2ubroxej218g0p0nki.jpg',
'https://ww3.sinaimg.cn/large/be6ad69bgw1eys2ubpohkj218g0p01a1.jpg',
'https://ww2.sinaimg.cn/large/be6ad69bgw1eys2ubkx6ij218g0p07ht.jpg'
 /*需要随机到的图片的链接*/
    ]
    var index = Math.floor((Math.random()*background_urls.length));
    res = await fetch(background_urls[index])
    return new Response(res.body, {
        headers: { 'content-type': 'image/jpeg' },
    })
}

反代微博图床

为什么要反代微博图床的图片,而不是直接返回图片地址给客户,主要是两个原因,
1. 微博是有防盗链设置的,会判断请求的 referer 是否是微博
2. 通过微博图片地址是可以反查到图片发送者的,如果打算提供公开服务,且不想暴漏自己的微博的话,最好隐藏图片实际地址。

因为代码有点长就不写文章里了,去github看吧。
基本就是构建请求头,检查图片地址是微博的话,就修改 referer 解决微博的防盗链,然后反向代理图片,返回结果。

简单的 Cloudflare Workers 部署步骤

  1. 登录你的Cloudflare
  2. 在主页右侧找到【计算(Workers)】
  3. 点进【Norkers和Pages】选择一个预设的子域,点击【set up】之后,我们选择免费套餐。
  4. 点进【Workers】,选择【创建Workers】-【快速开始】-【部署】-【编辑代码】
  5. 把这里的代码(https://github.com/tjsky/randompic/blob/main/index.js) 粘贴到页面左侧的输入框
  6. 修改代码中这部分网址为你想用来随机的图片的网址
    var background_urls = [
'https://ww2.sinaimg.cn/large/be6ad69bgw1eys2ubi8loj218g0p0h3y.jpg',
'https://ww4.sinaimg.cn/large/be6ad69bgw1eys2ubqm6ij218g0p0ql4.jpg',
'https://ww3.sinaimg.cn/large/be6ad69bgw1eys2ubroxej218g0p0nki.jpg',
'https://ww3.sinaimg.cn/large/be6ad69bgw1eys2ubpohkj218g0p01a1.jpg',
'https://ww2.sinaimg.cn/large/be6ad69bgw1eys2ubkx6ij218g0p07ht.jpg'
 /*需要随机到的图片的链接,注意最后一行没英文逗号*/
  1. 点击【保存并部署】按钮,
  2. (非必须)单击你刚创建的Worker,选择重命名,起个好记好写的名字,比如pic
  3. 访问你的Worker的域名比如pic.tjsky.workers.dev就可以看到啦
  4. 因为众所周的原因Cloudflare Worker的默认域名国内是无法访问的,你可能需要套个自己的域名,
    可以参考这个文章《Cloudflare Workers 添加自定义域名 解决部分区域网络无法访问的问题

如果公开部署随机图片API还需要做点什么

以上基本自用就够了,但是如果你打算提供公开服务那么还需要在 Cloudflare 内考虑好这些事情
Worker那10W 次请求看起来很高,一天才 86400 秒够每秒1次多了,但如果有人反复刷或者用户极多的时候,还是很快就会没的了。最多的时候我的某个 API 后端怼了8个 Cloudflare Worker来满足前端需求,就这每天快到 UTC 0的时候还经常有额度接近 90% 的提醒。
1. 屏蔽爬虫。很多数据收集公司的采集爬虫是不管源站死活的,他会高频反复的采集网址。
2. 限制请求速率,防止有人恶意刷图。
3. 考虑缓存优化,现在每次刷新都是一张新图。

The post 随机图片API:基于 Cloudflare Worker + 微博图床 appeared first on 秋风于渭水.

  •  

年更话题:春运 12306 怎么抢票

2025年1月13日 10:21

又双叒叕要春运了,又要开始和其他人在 12306 搏斗抢票了。
基于多年的 12306 抢票经验,总结了一些抢票小技巧,希望能帮到你。


关于火车票的基础常识

  1. 携程,管家,分流最终还是用你的12306账号去12306给你买票的。分流比较纯净,携程那可是能干出往你账号里添加不认识的人,然后用你的账号给其他人抢票的事情的。亦或者广州到重庆没票,给你买个广州南到佛山西,但是APP内已完成订单最大的字写的是《广州-重庆》让你以为你买到了全程票,你上车后才发现7个小时的车程,实际有座的区间只有20分钟的抽象事。

  2. 12306 放票不是完全整点,可能会早2~3秒,所以别卡整点刷新。(因为网页和APP显示的时间是你设备的时间,并不是真·北京时间)

  3. 如果你发现 12306 放票后,该车次直接就没看到票,这不是被人秒买走了,而是你的区间没开始售票。如果你这个区间售票,你肯定能看到票。

  4. 提交候补也是有排队的,是按你交钱的时间算的,未来有票了,谁先交钱先给谁票。

春运 12306 火车票的售票机制

  1. 开售后 12306 只放出始发终到(始发站到终点站)和始发站到部分大站的票。也有可能只放出始发终到的票。(少部分车票会放给线下)
  2. 如果选择的区间开始售票了,那么12306 在1~2分钟内都只返回一个缓存结果(每个缓存CDN结果不一样),期间查票 12306 不会去后端查询余票数量,返回的都是缓存。只有在提交订单时,后端才会真实的为你查找车票余票情况。
  3. 如果有票 12306 开始对提交者排队,此时 APP 用户会优先于网页用户。
  4. 如果什么票都没看到的话说明:12306 就没放票! 12306 就没放票! 12306 就没放票!
  5. 你要是狂刷新(间隔小于2秒),持续超过15~30秒,你的IP会被拉黑,查什么都随便返回一个缓存。
  6. 对于乘车区间在预填单试点范围的,优先满足提前填写的人。
  7. 12306 等大家提交候补,谁先交钱谁先排上队。
  8. 在距离开车还剩7~12天时,逐步开售中间车站的票,在服务器空闲时段,优先根据候补订单付款顺序完成订单,但会留出部分余票会按比例放到 12306 和 车站与代售点。

正确的 12306 抢票流程

  1. 最好准备2个挨着的出发日期
  2. 查询出发城市的起售时间
  3. 12306 做了一个叫 “购票信息预填” 的功能。在车票起售当日,可以在起售时间之前预先填写乘车人、车次、席别等信息,在车票开始发售时,一键提交订单。
  4. 开售时刻刷新几次后,发现目标车次直接无票,说明今天不放票,马上提交候补并付款,候补是按付款时间算的,所以你付款的越早排队越靠前。
  5. 然后,尝试买长乘短。也就是尝试将到达地往后边的大站选。
  6. 如果买长没戏或者太亏,可以尝试买短,也就是到达地买到前边几站,上车后补票。
  7. 如果还没票,还可以从出发地的上游大站开始买,但此种方式购票前,请确定你所在城市的车站会让你进站…有些认死理的车站可能会以非本站车片为由不让你进站乘车。
  8. 如果这还没戏,不如去看看空铁联程,这年月飞机票很便宜的,搞不好算上机场建设费,燃油附加费,比卧铺都便宜。

一些春运抢票乘车小技巧

  1. 候补票的兑现顺序是按你的支付时间算的,所以起售第一时间抢到的候补,也要在第一时间支付。
  2. 抢了候补,也还是要刷票的,出于公平策略,每次兑现一批候补时,也会放出一部分直接购买的票。除非你是第一批候补兑现集团内的,不然一定会出现候补没兑现,结果自己买到票了。
  3. 如果全程秒无,那就是没放票,因为12306的缓存机制,哪怕只有1张票被放出来,也会在1~2分钟内一直看到这张票,而不是秒无的。
  4. 如果你有可挂机的电脑的话,分流抢票很好用的。
  5. 12306 官方 APP 手动抢是优先级最高的购票渠道。携程、分流、木鱼等抢票都是基于 12306 网页版的,目前网页版是降权状态。所以即使你使用了分流/携程的定时抢票,放票的时候也请使用 官方 APP 手动抢票。
  6. 如果你的乘车区间在预填单试点范围(京津、江浙沪、广东 – 四川、重庆),强烈建议使用!
  7. 支付宝铂金、钻石会员可以兑换高铁贵宾厅特权的,春运可能会限制部分特权,比如可能没小零食,时长从3小时变成1小时,但是走贵宾厅是可以提前检票的,不用人挤人的拖着行李在站台狂奔还是很舒适的。(可以带1个6岁以下的儿童的)
  8. 如果有65岁以上老人同行,或者你恰好需要轮椅,12306 APP内申请重点旅客,可以享受优先上车优先下车的待遇。
  9. 请提前足够长时间到车站候车…春节人多,意外变数也更多。除非确定能接受迟到导致无法乘车的结果。
  10. 不要同时打开同一个 12306 账号的网页和APP! 虽然这俩确实可以同时登陆并打开,但如果你这样做购票排队时很可能会被降权放在队伍末尾。(如果你用了木鱼/分流/携程,就不要再打开你的12306 APP了,除非你已经下好订单就剩付款了)
  11. 基于上一条和第五条,应该用账号A在携程、分流、木鱼等抢票软件内抢票。再使用家人的账号B在 APP 上手动抢票。而不是在网页和APP内都是用账号A。

The post 年更话题:春运 12306 怎么抢票 appeared first on 秋风于渭水.

  •  

给博客增加 文章归档 和 年度统计 功能

2024年12月30日 17:30

终于在建站11年的当下终于给博客增加了文章归档页。
是基于 Rank Math SEO 插件的 Sitemap Settings 功能实现了一个简单的文章归档页。
顺带在文章归档页内塞了一个额外的网站数据年度统计功能。
大概长这样:文章归档


起因 为什么想要加文章归档页了

起因是在《WindowTabs: 让几乎一切 Windows 窗口支持多标签功能》一文下,博友 ddw2019 在评论中提到我的站点“没有找到 Archive 页面,一个个翻页起来,感觉还是有点点费劲的呀。”

之前我一直感觉文章归档页的感知不强,我认为它的主要意义和好处是:系统化整理文章、提高可发现性、增强用户体验、SEO优化、展示创作历程这 5 个方面。

毕竟现在右侧有文章分类、随机文章、热门文章三个模块。系统化整理文章提高可发现性性上已经足够了。
SEO 优化上文章归档页固然归可以帮助搜索引擎更好地抓取和索引博客内容,不过在已经有 xml 站点地图的时候,文章归档页对于提供博客的 SEO 优化上作用不大,相较这种 html 格式站点地图,xml 格式的站点地图对搜索引擎会更加友好一些。

不过嘛,确实考虑到博客里确实是缺少一个展示创作历程和增强用户体验的东西。于是在2024年的年底,终于在建站 11 年后决定加上这个东西。

思考 实现文章归档页的方案

那么现在问题来了,如何多快好省的实现文章归档页 Archive 呢?
从这个博客的可以称之为极简的风格上估计大家都能看出,我并不太喜欢在美化折腾博客页面上消耗过多精力。

  • 方案一 网友 ddw2019 的博客中写到的方案 年度归档插件
    好处是省事的多,装个插件的事情。缺点是又双叒叕需要多装一个插件了,博客速度又要被拖累。
  • 方案二 利用现有插件 Rank Math SEO 的站点地图功能实现。
    好处是利用了现有插件,少装了一个插件,缺点是样式就简陋的多了,样式的自定义空间也小的多。

  • 方案三 自己实现一个页面
    优点是更加轻量,样式完全可以自定义。缺点是自己写东西需要费更多的时间。

权衡利弊后,我决定先用方案二顶上,先解决有无问题再说。

开干 实现文章归档

以下的必要前提是:你要有装 Rank Math SEO 这个插件,并且开启了他的 Sitemap 组件。
这里我只介绍必要的操作,如果想了解更多一点,这里有篇不错的文章 《家庭数据中心系列Rank Math SEO设置与优化-无敌的个人博客》

  1. 新建一个页面,起名叫文章归档并把固定链接设置为ex.your.domain/archives并发布。
    (是的,内容为空就行)
  2. 进入博客后台,左侧找到 Rank Math SEO 的 Sitemap Settings 部分,切换到 HTML Sitemap 标签,并开启开关。

  3. 将 Display Format (显示模式)设置为 Page 也就是页面模式。如果你想在文章归档页放入额外的东西,也可以设置为 Shortcode 模式,这样上一步时,需要在你想要插入文章归档页的地方写短代码[rank_math_html_sitemap] 即可。

  4. Sort by (排序方式),既然是文章归档页,那自然是选 Published Date (基于发表日期)啦。并且开启下边的 Show Dates (显示日期),这样文章后面就会显示发布日期了。

  5. Item Titles (项目标题),作为文章归档页,建议选 Item Titles (文章标题)而不是 SEO Titles (SEO用标题)这两者的区别是:SEO用标题是给搜索引擎和搜索结果用户看的,可能会比实际的文章标题会有些奇妙的拉长和缩短。比如文章实际标题很长,但是 SEO 标题可能会为了能保证在搜索结果页把关键词凸显出来会相对减少次要描述。也就是说 Item Titles (文章标题)更能反映文章内容。

  6. 最后保存即可,现在前边设定的固定链接看到一个比较简陋的,文章归档页了。
    类似本站这样:文章归档 (https://www.tjsky.net/archives)

增强 增加博客年度数据统计功能

本来事情就该结束了,结果中午的时候,我又在博友圈里看到了 ts小陈 的文章:《为WordPress网站添加年度数据汇总
我发现,“诶,这个东西不错嘛,可以很直观的展现每年博客的发展数据。”
随后尝试直接套用代码,然后果不其然的发现:事情并没有那么简单。
毕竟我现在用的主题上次更新已经是2022年了,主题并没有完美支持页面模板php文件。
并不能像他原文介绍的那样:

  • 将php文件上传到你主题的页面模板文件夹(pages文件夹)
  • 创建新页面选择该模板-年度数据
  • 发布页面,搞定。

于是我又研究了一下WordPress这个页面模板php文件应该怎么写,以及他代码具体是做了什么。
重新写了适配自己主题的页面模板文件。主要修改点是三个

  • 修改一下样式适配博客主题
    主要是套用原有page页的代码,改一个新的模板文件。还有些小修改,比如表格做成圆角啊,表格改个主题色啊,属于毫无技术含量的修改。
  • 修改其中统计字数的函数str_word_count()mb_strlen()
    中文不用空格来分隔单词,对于中文字符串,str_word_count()会将两个标点之间的整个字符串都视为一个单词,mb_strlen()则会根据当前PHP设定的编码自适应用基于UTF8或gbk等编码正确统计字数。所以改一下得到准确的字数统计。

//修改前的代码,在原文文件的第79行
word_count = str_word_count(strip_tags(content)); // 去除HTML标签后计算字数

//修改后的代码
word_count = mb_strlen(strip_tags(content)); // 去除HTML标签后计算中文字数

大部分面板和一键脚本部署的 PHP 应该默认就开了 mb_strlen 这个函数,不过对于用虚拟主机的可能需要注意下,这个 PHP 函数不一定被启用了。

  • 把缓存改成1天,30天有些长了。

原文写的是”数据使用 Memcached 缓存”,让人以为只能用于 Memcached。不过实际上,如果你用 Redis 或者其他什么缓存,只要你装了对应的缓存插件,比如用 Redis 并且装了 Redis Object Cache。可以保证wp_cache_get()wp_cache_set() 函数能正常工作就不需要注释掉缓存代码,不然每次都现场计算一次,这性能浪费不小。

最终效果如下图

很直观的数据
2017年上一个博客被我rm -rf */干没了之后,在 17 年 12月 底重建,18 年还在保持正常的更新,可惜博客没啥人看(看评论数量),外在驱动力不足 导致 19 ~ 21 年我基本上没更新过博客,21 年底,因为一些机缘巧合博客收获了一波较大流量,加之因为这个机缘巧合重新拾起写代码的乐趣,重新开始恢复正常的更新频率。

The post 给博客增加 文章归档 和 年度统计 功能 appeared first on 秋风于渭水.

  •  

我到底应该选多少键的键盘——机械键盘配列选择指南

2024年11月1日 21:15

机械键盘 配列选择指南

如果打算趁着双十一大促,购买一款新机械键盘,你最优先应该决定什么?轴体?外观?材质?连接方式?都不对,其实你最优先应该是根据自己实际需求去选择键盘的配列。

什么是配列?配列指的是键盘按键的装配序列,说人话就是键盘按键的数量和按键的布局。

我到底该选多少键的键盘呢 108 键、104 键、98 / 96 键、87 键、68 键?亦或者简洁的 42 键?

大配列键盘一切按键都在,甚至给你多加几个乃至一排的额外按键,是最实用的选择,但是缺点就是键盘又长又宽,缩减了鼠标的空间,有些多功能键盘增加的额外按键还导致键盘宽度变大,让使用者胳膊要长时间悬空,对于电脑桌尺寸较小,桌面空间有限的人来说简直是折磨。

小配列可以为鼠标留出更大的操作空间,节省桌面空间,但是许多功能键的消失,也会导致使用起来十分不便。

本文就是科普一些常见的键盘配列,希望能帮助到对此有选择困难症的小伙伴。

那么正文开始。


100 配列键盘

一般称呼为全尺寸键盘,100%配列键盘,常见是104键、108键两种款式。
键盘拥有四大区块:功能键区(ESC + F1~F12)、主键区(字母、数字、符号)、编辑键区(Home,End、PgUp,Prtsc,4个方向键等)和数字键区(数字小键盘)。
可以提供最全的按键功能,适合任何场景,包括办公、编程、游戏。

104 配列键盘

最最最最标准的键盘,该有的键都有,也不额外增加其他键。
部分产品可能会把很少用到的【菜单键】(在【右 Ctrl 键】的左边),替换成【Fn键】,通过【FN+F*】的组合按键来实现一些额外的多媒体键功能。

104 配列键盘

108 配列键盘

一般通过将104键位键盘右上角的指示灯区域利用起来,增加额外的按键。
大部分是增加,【WIN键锁定】、【音量-】,【音量+】,【静音】这4个按键,有些则会做个滚轴、旋钮用来调节音量。相对来说会更加实用一些。

108 配列键盘

大于 108 配列键盘

个别键盘甚至会直增加一整排的按键,最典型的就是罗技的MK200系列键鼠套装,直接在功能键区上方加了一排多媒体键。如果支持键盘自定义,搞点按键宏啥的还有点意义,单纯为了多媒体键加一排键十分不实用。反正我原来用的就是罗技这款键盘,用到上边多媒体键的次数屈指可数。

大于 108 配列键盘

90 ~ 100 配列键盘

通过将 104 配键键盘上利用率过低的键,比如【插入键】、【滚动锁定键】改成组合键,对键位排布进行优化,缩小键盘区域的间隙,在保留基本功能的前提下,比 104 配列键盘缩短 3 列按键的长度,使整个键盘显得更加紧凑。

这也是最万金油的配列,如果你希望键盘长度紧凑,同时还想要保留数字区域,这个配列就很合适你。
主要缺点就是你可能需要一段时间来适应新的按键布局,以及偶尔去用别人的电脑时,面对104配列的键盘会疯狂误触。最常见的就是按【Delete键】时按到【F12】,最下一排按键的误触。这也是我目前在用的键盘配列。

99 配列键盘、98 配列键盘

98和99基本是一样的,各家 98 键和 99 键的区别一般都是:有没有【Fn键】,要不要加个【音量旋钮】,【截图键】是放在数字键区还是主键区的上侧。上图是典型的 98 键布局,下图是典型的 99 + 1 旋钮布局。

98 配列键盘

99 配列键盘

96 配列键盘

各家主要的区别就是将单独的编辑区按键,只留【Page Up】、【Page Down】、【Delete】后,再从【Fn键】、【Print Screen】、【Home】、【End】、【Insert】键里选1、2个给你装上。
主键盘区和功能区和 104 键配列基本一致,大部分 96 键配列一般是为了让出右上角的指示灯区域,有些产品会在这里装个小屏幕。这种键盘相当于 104 配列键盘减少 2 列按键。

96 配列

85 ~ 90 配列键盘

在 104 键配键上取消了数字键区,布局与 100% 配列非常相似,不需重新适应按键位置。部分型号可通过额外的【Num lock键】开启数字区映射到主键盘区功能,用过小尺寸笔记本电脑的读者应该都见过这种设计。比较适合需要较大右侧鼠标操作空间,但又不常进行数值输入的用户,如程序员和一般办公人员。

87 配列键盘

最常见的就是 87 配列键盘。简单粗暴理解就是删掉数字区的 104 配键的全尺寸键盘,保留了大部分重要按键,只有少量功能键被移除或合并至其他键上。只要你不用数字区,键盘功能对你就是齐全的。部分人会再买个独立的数字小键盘,实现分体式键盘,摆放更加灵活。
87 配列基本和 98/99 配列的长度差不多,87 配列只稍稍短了一点。所以除非对编辑区完整按键有刚需,我个人建议还不如选 98/99 配列。

87 配列键盘

60~80 配列键盘

删了数字区还不够,继续删功能键和编辑键,让得键盘变得更加简约和小巧。

75 配列键盘

在 87 键配键的基础上,精简部分单独的编辑键,改成组合键,精简键盘。
功能区还在,有些会加个Fn键,映射一些编辑区按键,实现功能不缺失。
足足比 104 配列键盘的长度缩短了6列按键。

75 配列键盘

68 配列键盘

通过将 75 键配列上的功能键(F1~F12)也取消了,再次精简键盘。只保留主键区和个别常用的编辑键,键盘宽度也缩小了1行按键,这个尺寸的键盘基本是能直接揣包里的尺寸了。

68 配列键盘

61 配列键盘

将功能键区、编辑键区、方向键区能删的几乎全部删了,基本上只保留字母和数字输入功能,其他按键全部需要通过组合键触发。

61 配列键盘

40 ~ 55 配列键盘

日常使用这种键盘的人,请让我在这里叫你一声大神,现在连主键盘区域的数字输入也取消了。键盘也就比手机大点,真·口袋键盘。基本只有自制和客制化键盘可选。

42 配列键盘

The post 我到底应该选多少键的键盘——机械键盘配列选择指南 appeared first on 秋风于渭水.

  •  

Win10 / Win11 系统屏蔽驱动/补丁更新

2024年10月16日 21:12

使用微软官方工具《show or hide updates》隐藏特定驱动/补丁的更新,防止自己手残误操作或者系统自动给你升级了,也可以解决总提示有更新的强迫症问题。


起因

事情的起因是我手头上有个比较老的雷电3扩展坞,这个扩展坞在我从 Win10 升级到 Win11 后就不能用了。具体表现为:扩展坞上的 USB 设备都无法被识别,扩展坞只会给 USB 设备供电。折腾了一番还是无法解决。

找官方客服得到的答案是:不好意思,我们的这款扩展坞没有 win11 下的驱动,并且我们也不打算推出 win11 驱动了,您要不要考虑一下我们的其他新款扩展坞?懒得继续折腾,扩展坞就被我塞到柜子里了。

在束之高阁一年后,最近收拾抽屉时,又把扩展坞翻出来了,然后经过一通莫名奇妙的驱动更新、反复交叉循环安装多个不同版本驱动后,诶,扩展坞他被修好了(姑且算修好了,其实还有个小 bug,但不耽误用了)

结果刚才手贱点了Windows 更新 > 高级选项 > 可选更新 > 驱动程序更新,然后扩展坞他就又坏啦。

不过幸好 Windows Update 一共就更新了两个驱动,很快就锁定了问题所在:Asmedia USB Host Controller Driver的驱动从1.16.43.1被升级到1.16.44.1

定位了问题解决起来也容易,卸载驱动,重新装回1.16.43.1版。

但是作为强迫症患者,十分不能忍受 Windows 更新 里有个更新提示。

Windows 更新提示

解决

经过简单的搜索后,发现微软有个现成的小工具《show or hide updates》

  1. 下載官方工具 [Show or hide updates]
  2. 运行工具,无脑下一步

  3. 选择 Hide updates

Hide updates

  1. 勾选你想要屏蔽的更新,点下一步

选择你想要屏蔽的更新

  1. 解决问题,你所选择的驱动更新或系统补丁就不会再出现在 Windows 更新( Windows Update)里了,成功屏蔽隐藏了 驱动 or 补丁。

  2. 未来如果想恢复更新在第3步时选 Show hidden updates就行。

The post Win10 / Win11 系统屏蔽驱动/补丁更新 appeared first on 秋风于渭水.

  •  

近期大量个人博客被自动化繁体镜像搬运

2024年9月24日 11:32

最近陆陆续续很多个人博客被自动化繁体搬运 镜像 ,对方用多个域名,使用 CloudFlare Worker 作为基础设施,伪装为谷歌爬虫 UA ,实时反代并繁体翻译大量个人博客,积累域名 SEO 权重。
博客被恶意 镜像 不仅会影响站点的在搜索引擎的收录,排名,权重,更可能会被搜索引擎屏蔽!


如何发现自己博客被镜像了?

  1. 直接谷歌搜一下自己热门文章的标题,自己博客的简介,自己博客的标题,看看有没有奇怪的繁体版结果。
  2. 检查访问日志,找到所有自称是 Google bot PC的流量(UA显示为Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)),将其与 Google 公布的爬虫 IP 段进行对比。(后期不排除他仿冒其他UA访问,比如谷歌移动UA,百度UA,必应UAE等)

博客被镜像了怎么办?

网友们大致的处理措施是这样的

一、在网站页面中添加防镜像跳转代码

(function () {
    var validDomain = 'tjsky.net'; // 你的域名
    var redirectUrl = 'https://www.tjsky.net'; // 重定向链接
    var hostname = document.location.hostname;

    function createWatermark(text) {
        var watermarkDiv = document.createElement('div');
        watermarkDiv.style.pointerEvents = 'none';
        watermarkDiv.style.position = 'fixed';
        watermarkDiv.style.top = '0';
        watermarkDiv.style.left = '0';
        watermarkDiv.style.width = '100%';
        watermarkDiv.style.height = '100%';
        watermarkDiv.style.zIndex = '9999';
        watermarkDiv.style.opacity = '0.1';
        watermarkDiv.style.background = 'transparent';
        watermarkDiv.style.overflow = 'hidden';
        watermarkDiv.style.display = 'flex';
        watermarkDiv.style.justifyContent = 'center';
        watermarkDiv.style.alignItems = 'center';
        watermarkDiv.style.flexWrap = 'wrap';

        var watermarkText = document.createElement('div');
        watermarkText.innerText = text;
        watermarkText.style.color = 'black';
        watermarkText.style.fontSize = '30px';
        watermarkText.style.transform = 'rotate(-30deg)';
        watermarkText.style.whiteSpace = 'nowrap';
        watermarkText.style.margin = '20px';

        for (var i = 0; i < 100; i++) {
            watermarkDiv.appendChild(watermarkText.cloneNode(true));
        }

        document.body.appendChild(watermarkDiv);
    }

    if (hostname !== validDomain) {
        createWatermark(validDomain); // 给页面加上前边设置的域名为水印
        var userResponse = confirm("警告:您当前浏览的页面非官方页面,可能存在有害信息!建议您跳转至官方页面进行浏览!");
        if (userResponse) {
            window.location.replace(redirectUrl);
        }
    }
})();

这个代码的目的是,利用对方会无脑反代一切内容的机制,在所有页面内都插入检测 JS 代码,在网友访问时,检测当前域名是否为所设定自己博客的域名,如果不是所设定的博客域名则在网站背景中嵌入带域名水印并使用 confirm() 打断页面渲染,并弹出弹窗警示用户跳转回源站。
并且使用 JavaScript 动态插入水印 div 并不设置 id,class 等标识,防止对方通过u正则表达式匹配删除特定 div 元素。

反镜像代码触发时的效果示意

但是这里有几个问题
1. 域名和跳转链接为明文,对方可以自动化匹配
2. JS代码也为明文,对方可以检测到发生跳转自动化打断跳转执行。

解决办法很简单:使用 JavaScript 混淆,并将这段JS拼接到站点关键JS块内
让对方无法匹配到代码,而对方如果完全阻止JS,则会导致页面出现严重的渲染(比如部分样式通过JS来动态引入,而不是直接写在CSS里)问题。
至于怎么混淆这个工具就很多了,简单谷歌一下就有很多工具可用,比如这个那个

这里注意三个点
1. 记得勾选 Unicode 转义,不然后面的中文提示还是原文
2. 字符串加密方式可以选RC4这个相对base64不太常见的编码方式,加密密度选1(既所有都加密混淆)
3. 混淆会拖累执行性能,在保证加密混淆的前提下,尽可能混淆程度低一点。

二、阻止非验证的谷歌爬虫访问

有些安全插件,防火墙具有验证谷歌爬虫的选项,会对声明为谷歌爬虫的访问做 DNS 反查,确定爬虫访问 DNS 掩码符合谷歌公布的掩码,并且归属为谷歌公布的爬虫 IP 段才会允许爬取。

三、向域名注册商报告滥用

镜像他人网站是明显的恶意滥用行为,可以向对方的域名注册商投诉。

四、向CloudFlare报告滥用

对方时用的域名托管商和代码执行基础设置都是CloudFlare:举报页面

五、向域名的注册局报告滥用

一些被滥用比较多的域名比如.top是有滥用举报的,举报页面

六、向谷歌申请移除镜像站的搜索结果

因为它会原样照搬反代网页,那其实你可以通过HTML 标记验证方式在 Google Search Console 里把他的反代域名也认证到你自己名下,然后在Google Search Console 向谷歌申请移除搜索结果

七、在后端反制一下?

评论区给了我一个很好的提醒,既然他是通过特定IP和非谷歌归属IP的特定UA来抓取反代的,
其实你可以通过 nginx.conf 实现一些好玩的效果,比如只要 UA 显示为谷歌 PC bot,但 IP 段不在谷歌公布的 IP 段内,或者某指定 IP 访问时,就301跳走,返回特定页面,反代其他网站页面,在原始网页中加mu料ma。

以下仅为抛砖引玉,各位大佬可以开发更有意思的方式。

  1. 当抓取服务器154.39.149.128 (这是目前他的抓取服务器 IP )访问时,自动跳转到百度首页(百度首页只是个例子,你可改成其他奇 wei 怪 gui 的网站。实现让他的域名被降权或出现违规而被禁止)
server
{
    listen 80 XXXXXXXXXXX;
    listen 443 XXXXXXXXXX;
    server_name XXXXXXXXXXX;
    index XXXXXXXXXXX;
    root XXXXXXX;
#一般将下方代码按自己需求修改后,插入在你网站上边这一坨配置的后面就行

   #指定IP访问自动反代百度网页
    if ($remote_addr = 154.39.149.128) {
            proxy_pass http://www.baidu.com;
        }
   #指定IP访问自动反代百度网页结束

#你网站的其他配置
}
  1. 当UA显示为谷歌PC爬虫,但访问IP不在谷歌公布的IP段时,反代其他网页给他。
  • 首先在谷歌获取json格式的IP段列表:爬虫 IP 段
  • 然后将其转化为类似这样的格式(可以让 AI 帮你搞)
    34.165.18.176/28 1;
    192.178.5.0/27 1;
    34.126.178.96/28 1;
    
  • 放在nginx可以访问的地方,比如/usr/local/nginx/conf/firewall.conf
  • 修改nginx.conf

# 加载 IP 白名单文件
geo blocked_ip {
    default 0;
    include /usr/local/nginx/conf/firewall.conf;
}

# 检查特定 User-Agent 的访问
maphttp_user_agent is_special_ua {
    default 0;                    # 0,表示不匹配
    "~*Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 1;      # 指定爬虫UA
}

#将上方代码按自己需求修改后,插入在你网站下边这一坨配置的前面就行

server
{
    listen 80 XXXXXXXXXXX;
    listen 443 XXXXXXXXXX;
    server_name XXXXXXXXXXX;
    index XXXXXXXXXXX;
    root XXXXXXX;

#将下方代码按自己需求修改后,插入在你网站上边这一坨配置的后面就行

   #符合UA但不符合IP段时自动反代指定网页
        if (is_special_ua = 1) {
            if ($blocked_ip = 0) {
                proxy_pass http://www.baidu.com;
            }
        }
   #符合UA但不符合IP段时自动反代指定网页结束

#你网站的其他配置
}

吐槽

为啥我的这个主站没有被搬运,我另一个访问量很低的(日均PV只有几十),内容也比较无聊的在国内的站反而被他搬走了。

  1. 可能原因一:貌似对方不会镜像使用境外服务器的非备案站点。
  2. 可能原因二:他的访问因为没通过谷歌爬虫检查,被拦住了。

他的访问直接就被拦住了

  1. 对方只搬运流量相对小一点的站,以免被发现。

事态更新

  • 2024-07-18:第一次知道有人网站被镜像
  • 2024-08-20:服务器后端被拦截中出现镜像者所使用的IP:154.39.149.128,php 探针都没删。
  • 2024-08-28:镜像服务器迁移到:103.233.9.190,这次学精了,隐藏 PHP 控制台,设置了 IP 区域限制,只有非中国大陆IP访问才会正常显示内容。
  • 2024-09-05:他的服务器一度被人打到宕机
  • 2024-09-24:看到被镜像的人越来越多固有此文
  • 2024-10-09:增加两种基于 nginx 的反制措施思路

参考资料
网站被恶意镜像了该怎么办
我的个人博客网站再次被恶意镜像,这次手段高明了许多
网站被恶意镜像——如何保护博客流量及预防
保护您的博客不被恶意镜像
我的博客也有一天会被反代?
我的博客被完整地反向代理,并自动翻译成了繁体中文

The post 近期大量个人博客被自动化繁体镜像搬运 appeared first on 秋风于渭水.

  •  

Chrome 如何继续使用 uBlock Origin 等 Manifest V2 扩展

2024年8月16日 10:23

Chrome 如何继续使用 uBlock Origin 等 Manifest V2 扩展

谷歌将于 2024 年 6 月开始禁用 Manifest V2 扩展程序,强制开发者使用 Manifest V3 目前在127以上版本的 Chrome 中开始出现升级提示。但问题在于 Manifest V3 扩展的权限被大大缩减,很多知名扩展的功能受限,比如 uBlock Origin 在升级到 Manifest V3 后,将只能使用静态过滤规则、无法实现动态过滤、无法实现动态 URL 过滤等。反广告功能被大大限制。本文通过使用企业策略强制 Chrome 延长对 V2 扩展的支持。


步骤

  1. 在 Windows 10/11 搜索框中输入 regedit 打开 注册表编辑器
  2. 在注册表编辑器中打开:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\路径

  3. 右键单击 Policies

    • 新建项
    • 命名为 Google
  4. 右键单击 Google
    • 新建项
    • 命名为 Chrome
  5. 右键单击 Chrome
    • 新建 DWORD32 位值
    • 命名为 ExtensionManifestV2Availability
  6. 右键单击 ExtensionManifestV2Availability
    • 将键值修改为 2
    • 左键单击确定按钮

  1. 在 Chrome 中打开 chrome://policy/
    • 点击 【重新加载政策】按钮
    • 看到 Chrome Policies 项目出现如下图所示的政策即可。

总结

谷歌这一手,对扩展的能力的限制是非常大的,我常用的扩展被影响的就有:

  • Tampermonkey(篡改猴)
  • Proxy SwitchyOmega(自动切换代理服务器)
  • uBlock Origin (反广告扩展)
  • 划词翻译
  • Header Editor (管理浏览器请求,修改请求头和响应头、重定向请求、取消请求)

Manifest v3 直接阉割掉了他们很多功能的权限,即使他们推出了 V3 版本,功能也必然会比现在的版本有大量阉割。

通过本文启用企业策略的方式延长 Manifest v2 扩展程序的支持,咱们最多可以再延长一年的使用时间。所以如果后期没有大神发现更好的解决办法的话,也许换成不受限制的 Mozilla Firefox 浏览器会是个更好的选择吧。

The post Chrome 如何继续使用 uBlock Origin 等 Manifest V2 扩展 appeared first on 秋风于渭水.

  •  

解决绿色便携版 Chrome 打印预览失败问题

2024年7月18日 20:06

我的Chrome自从升级到125+的版本后,突然在Ctrl+P打印时无法打印网页了,提示打印预览失败,什么都不能做,既不能选择打印机,也不能打印网页。搜索了一番原来是文件权限的问题。只需要X步即可解决 Chrome 打印预览失败的问题。


解决 Chrome 绿色便携版打印预览失败

  1. 找到你的绿色版 Chrome 的 APP 文件夹,右键,选择“属性”
  2. 切换到“安全”标签

  3. 点击“编辑”按钮

  4. 点击“添加”按钮

  5. 在“输入对象名称来选择”框里输入ALL APPLICATION PACKAGES

  6. 点击“检查名称”按钮,确定左侧输入框里的输入增加了下划线。

  7. 关闭你的chrome,彻底退出chrome后 依次点击上述窗口的“确定”按钮。

  8. 如果你想问需要给ALL APPLICATION PACKAGES什么权限的话,答案是:保持默认即可,即勾选“读取和执行、列出文件夹内容、读取” 3项即可。

  9. 重新启动 chrome ,就可以正常使用打印功能了。

PS:其实问题不在于是不是便携版,而是chrome内核更新出来的“安全特性”,正常安装版的安装程序会自动帮你解决默认安装目录的权限。
如果你感觉上述方法比较麻烦,可以给chrome的快捷方式,添加启动参数--disable features=PrintCompostorLPAC。同样能够解决问题。

The post 解决绿色便携版 Chrome 打印预览失败问题 appeared first on 秋风于渭水.

  •  

RTranslator – 一款 Android 开源离线本地实时同传翻译 APP

2024年6月29日 10:54

RTranslator 介绍

RTranslator 是一款适用于 Android 的开源、免费、离线、实时的翻译应用程序。RTranslator 使用 Meta 的开源 AI 模型 NLLB 进行翻译,使用 OpenAi 的开源 AI 模型 Whisper 进行语音识别,是一款可以直接在手机上运行的开源离线本地实时 AI 同传翻译 APP,在境外也不用担心因为手机无信号或无流量而无法使用了。


对话模式

如果双方手机都安装了 RTranslator 这个模式可以实现(几乎)实时的语音翻译对话。适用于会议或者长对话场景。

  • 双方都启动 RTranslator ,点右下方的 Conversation Mode 进入对话模式,手机会自动查找附近的设备,一方发起连接请求,另一方选择接受,你们两个的手机进入对话模式。
  • 正常说话,你的手机(推荐带个蓝牙耳机,这样能精确识别说话人)将使用OpenAi 的开源 AI 模型 Whisper 进行语音识别,将语音识别为文字,显示在你的 RTranslator 界面内。
  • 识别到的文字被原文发送到对方手机,对方手机使用 Meta 的开源 AI 模型 NLLB 进行翻译,显示在他的 RTranslator 界面内。
  • 调用对方手机中的离线 TSS 将翻译后的文本读出来。
  • 这个过程不但可以这样一对一用,甚至可以多对多,将多个人的手机加进这个聊天室,互相翻译。
  • 影响翻译速度的主要是说话人本身手机的性能,AI 语音转文字需要至少2秒,而 AI 完成翻译几乎是瞬间的。

对讲机模式

对话模式更适合长对话,对讲机模式则适用于临时对话场景,比如问路或者买东西时的对话。

  • 启动 RTranslator ,点左下方的 Walkie Takie Mode 进入对讲机模式
  • 在屏幕最上方设置,双方所用的语言,比如中文、英文
  • 双方开始对话,RTranslator 会自动识别语言,在我们的例子中,RTranslator 会听到中文就翻译为英文并显示在右侧说话人,听到英文就翻译为中文并显示在左侧说话人。
  • 你可以点击最右边的扬声器 🔊 图标,决定是否开启TSS朗读功能。

文本翻译模式

就是个正常的翻译器,复制文字进去,选择什么语言翻译到什么语言,点翻译就给你翻译。

RTranslator 总结

  1. RTranslator 使用 Meta 的 NLLB 进行翻译,使用 OpenAi 的 Whisper 进行语音识别,这俩基本是目前(几乎)对应领域最先进的 AI 模型,收听和翻译质量嘛,很多句子翻译出来的效果只能说差强人意,要说多好算不上不过看懂还是没问题的,简单的沟通肯定是够用了。

  2. 作者已经对 AI 模型进行了大量优化,以最大限度地优化内存需求和运行时间,尽管如此还是至少需要你的手机有不小于 6GB RAM,模型本体和运行库之类的,需要占用手机大约 2G 的储存空间。运行速度嘛,骁龙870 + 8GB 内存的平板上,一句话从说完到翻译完大概需要5秒。

  3. RTranslator 使用的模型是 NLLB-Distilled-600M with KV cache 与 Whisper-Small-244M with KV cache,使用 OnnxRuntime 运行模型。

  4. 这个东西的意义主要是可以脱离网络的离线使用和不会上传任何数据的隐私安全,如果你想要更好的翻译质量,可以尝试 OpenAI,科大讯飞,Deepl 等厂家的在线翻译 APP。

The post RTranslator – 一款 Android 开源离线本地实时同传翻译 APP appeared first on 秋风于渭水.

  •  
❌