GTX690战术核显卡导弹 - 编程
type: channel
link: https://www.nekopara.uk/category/%E7%BC%96%E7%A8%8B/
items: 断网自动重连！用Go实现广西大学校园网断网自动登录
items: 调用API实现Typecho博客VisitorLoggerPro插件IP信息更新
items: 用 Python 破解网易云 iframe 反爬，全自动构建本地音乐库
items: Linux下自定义NVIDIA GPU的风扇转速曲线
items: 试玩FreeMote，把二次元老婆搬上浏览器
items: Python实现浪潮SA5212M4风扇根据温度自动调节
items: 本地Ollama跑LLM并接入QQBot
items: 开新坑：入 门 Golang ！
items: 自建Jellyfin私人媒体服务器，告别屌毛网易云！

断网自动重连！用Go实现广西大学校园网断网自动登录
type: item
date: 2025-12-20T15:56:00+08:00
description: 广西大学校园网断网自动重连程序因为广西某211高校校园网有时候会不稳定波动，导致设备掉线。而如果在需要挂机进行一些工作的场合出现这个问题，将会相当蛋疼。再加上在宿舍每天晚上断网后，第二天都要手动重新登录着实有点麻烦，于是乎我就用我入门级中的入门级Go编程能力写了这个程序。程序实现登录方法查找因为学校推荐是使用浏览器打开认真网页进行登录，而经过抓包后，我发现相比于大一的时候，校园网的网页传输数据进行了加密。也就是，如果我要通过逆向网页JavaScript脚本获得登录请求发送逻辑，代价有点大。不过好在你西还是关照到了无GUI Linux服务器使用校园网的问题，在官网挂出了登录方法：linux系统宽带客户端-2024.12.30日后使用这就好办了嘛，只需要构造这个URL请求：http://172.17.0.2:801/eportal/portal/login?callback=dr1003&login_method=1&user_account=账号@cmcc&user_password=密码&wlan_user_ip=终端IP&wlan_user_ipv6=&wlan_user_mac=000000000000&wlan_ac_ip=&wlan_ac_name=&jsVersion=4.2.1&terminal_type=1&lang=zh-cn&v=5574&lang=zh发送给认证服务器就可以登录校园网了。不过我注意到了这个请求URL里面，MAC填写了000000000000，按理来说这部分应该填写设备的MAC，用于保持登录状态和后续无感知登录。这样填写无效的MAC后面大概率会因为校园网波动或者短暂断联掉登录，所以在我的程序逻辑上，这部分应该补上。现在需要发送的校园网认证信息就理清楚了：账号密码线路类型设备IP设备MAC我只需要写一个程序获取到以上信息，然后持续不断判断网络通断状态，当检测到断网后构造认证的URL并发送，就可以实现校园网断网自动重连了。用Go实现校园网自动登录其实之前我就用Python写过一版校园网自动登录程序，但是因为Python的效率和占用确实有点感人了，所以我觉得还是选择编译型语言来进行构建吧。好巧不巧之前学了一些Golang，要不就拿这个试试看？实现思路因为Go是编译型语言，登录的配置就不能像Python那样让用户打开源代码写在对应的变量里面了，得写一个配置文件机制。也就是首次运行创建一个文本的配置文件，然后用户填写了相关的信息，再运行程序，程序从配置文件读取信息并且执行校园网认证和断网自动重连工作。那这样看，实现思路就很清晰了：程序首次运行，输出配置文件模板，提示用户填写用户填写好后，读取配置文件并进行基础的校验，确保参数填写无误实现校园网登录认证的函数，网络通断检测函数，以及上网时段判断函数避免在非上网时段反复尝试重连对于配置文件的部分，我想采用类似ini配置文件的格式，这是模板：# 校园网登录脚本信息设置：（注意请不要改变格式） # 用户名：（填写示例：User=1807210721） User= # 密码：（填写示例：Password=www.nekopara.uk） Password= # 运营商选择，留空选择校园网，如果需要选择运营商，电信填写telecom，联通填写unicom，移动填写cmcc Net_Type= # 是否开启学生上网时段模式？1为开启，0为关闭，开启后周一到周五0:00-6:00将不会尝试重连 Student_Mode=0 # 开启路由器登录模式： # 如果填写以下两个参数（均非空），则使用指定的路由器IP和MAC进行认证。 # 否则使用本机IP和MAC。 # 示例： # Router_IP=172.16.6.6 # Router_MAC=36:88:8A:99:A4:CC Router_IP= Router_MAC=考虑到为了便于小白使用，我输出的是.txt文件，可以直接记事本打开。以及，添加一个命令行启动参数支持，可以让程序作为服务运行和部署，例如：./GXU_Net_AutoLogin -user 1807210721 -passwd mypassword -nettype telecom -studentmode -ip 172.16.6.6 -mac 36:88:8A:99:A4:CC现在技术架构想清楚了，开始编程吧！实现代码package main import ( "bufio" "fmt" "os" "strings" "net/http" "net" "net/url" "time" "io" "flag" ) const configFileName = "config.txt" // Config 结构体保存配置 type Config struc…

调用API实现Typecho博客VisitorLoggerPro插件IP信息更新
type: item
date: 2025-12-17T23:30:06+08:00
description: 利用B站IP查询API更新访客记录IP地理信息偶然的一次机会，在群里面聊天的时候，群友指出纯真数据库的数据并不准确，并且说有一个可以免费调用的IP地理信息库——B站的IP查询API。据说还是用的ipip.net的企业版，这下得狠狠白嫖了。前置任务：修复VisitorLoggerPro插件BUG如果使用过这个插件一段时间，你就应该发现了，在国家统计图表这项，非常的混乱，似乎是只要记录的字符不一致，就会被当作不同的国家处理，例如美国加利福尼亚洛杉矶和美国纽约就被当作不同的国家列在上面。经过深挖代码斗智斗勇，我发现这个问题我无法从根本解决，因为整个代码太奇怪了，而且用的本地IP数据库也都是乱七八糟的，根本没有做好国家的细分地区分类，一股脑返回，导致所有的信息被集中在一起写进了国家字段。于是，我放弃治疗，直接在后面的调用代码中，增加分类逻辑进行分类：这是原来的代码，单独处理和提取了国内省份： foreach ($countryCountsResult as $row) { $countryName = $row['country'] ?: '未知'; $count = $row['count']; if (!isset($countryData[$countryName])) { $countryData[$countryName] = 0; $totalCountries++; } $countryData[$countryName] += $count; if (strpos($countryName, '中国') !== false) { foreach ($provinces as $province) { if (strpos($countryName, $province) !== false) { if (!isset($provinceData[$province])) { $provinceData[$province] = 0; } $provinceData[$province] += $count; break; } } } }我决定在返回国家信息的时候，进行提取合并并返回： foreach ($countryCountsResult as $row) { $rawCountry = $row['country'] ?? ''; $count = (int)($row['count'] ?? 0); if ($rawCountry === '') { $stdCountry = '未知'; } elseif (strpos($rawCountry, '中国') !== false) { // 所有含“中国”的都归为“中国” $stdCountry = '中国'; // 同时尝试提取省份 foreach ($provinces as $province) { if (strpos($rawCountry, $province) !== false) { if (!isset($provinceData[$province])) { $provinceData[$province] = 0; } $provinceData[$province] += $count; break; // 匹配到第一个即停止 } } } else { // 非中国：尝试匹配标准国家名（用于归一化，如“美国加州”→“美国”） $stdCountry = $rawCountry; // 默认保留原值 foreach ($countries as $country) { if (strpos($rawCountry, $country) !== false) { $stdCountry = $country; break; // 匹配到即停止（因列表已按长优先排序） } } } // 累计国家统计 if (!isset($countryData[$stdCountry])) { $countryData[$stdCountry] = 0; $totalCountries++; } $countryData[$stdCountry] += $count; }当然了，需要补上完整的国家地区列表： $countries = [ // 长名称国家（必须放前面） '波斯尼亚和黑塞哥维那', '赤道几内亚', '圣文森特和格林纳丁斯', '特立尼达和多巴哥', '圣多美和普林西比', '阿拉伯联合酋长国', '沙特阿拉伯', '巴布亚新几内亚', '所罗门群岛', '马绍尔群岛', '密克罗尼西亚联邦', '帕劳共和国', '瓦努阿图共和国', '基里巴斯共和国', '瑙鲁共和国', '图瓦卢', '美属萨摩亚', '英属维尔京群岛', '美属维尔京群…

用 Python 破解网易云 iframe 反爬，全自动构建本地音乐库
type: item
date: 2025-11-23T17:21:00+08:00
description: Python实现网易云音乐自动抓取整理事情的缘起很简单，我的jellyfin音乐库听腻的差不多了，想抓点新歌。虽然说之前已经抓取过1000多首歌曲，但是很多是我因为强迫症，为了媒体库的完整性，把整个专辑都抓下来了，实际上常听的就是两三百首。正因如此，我就想给我的媒体库补充点库存，于是开始折腾，有了这篇文章。媒体库的具体搭建教程可以去看这篇文章：自建Jellyfin私人媒体服务器，告别屌毛网易云！实现思路上次因为没能自动化搞下载，且因为心急，所以几乎是半自动半手动收集的，费时费力，花费了差不多一个星期。而这次，我决定使用Python自动化完成，下面是工作流实现思路：当遇到喜欢的音乐后，我就保存其网易云的URL到文本文件，例如https://music.163.com/#/song?id=1499823984你可以点开看看是什么曲子（，每个曲子放一行，随听随收集。读取这个歌曲列表文件，逐行解析，获取专辑的ID，例如https://music.163.com/#/album?id=99010037，取出99010037，以及歌手KOTOKO。然后去解析专辑的页面，获取其中所有歌曲的song?id，例如1499823984，1499826814，1499823975和1499826811。调用第三方API进行歌曲解析，获取音频文件，歌词和封面。例如这次我用的就是https://jx.chksz.top/按照jellyfin要求的格式保存歌曲文件，也就是歌手/专辑/01.歌曲.flac，如：[chocola@Neko-Server KOTOKO]$ tree . └── ネコぱら vol.4 OP ⁄ ED ├── 01.SWEET×SWEET.flac ├── 01.SWEET×SWEET.lrc ├── 02.NEGAIGOTO.flac ├── 02.NEGAIGOTO.lrc ├── 03.SWEET×SWEET (Instrumental).flac ├── 03.SWEET×SWEET (Instrumental).lrc ├── 04.NEGAIGOTO (Instrumental).flac ├── 04.NEGAIGOTO (Instrumental).lrc └── cover.jpg最后还要打上艺术家，专辑，歌曲名的标签既然确定了思路和方法，接下来开始逐个攻破吧！观察网页布局打开音乐网页，开启F12大法，检查元素，迅速就定位到了目标：其实，后面发现在页面的meta标签其实也有信息：对于专辑部分，抓取列表就好了：看起来并不难，使用Python的requests模块获取html，然后解析内容就好了。尝试实现爬虫逻辑和LLM友好交流后，得出了每一部分的代码逻辑函数，例如解析歌曲页面信息的：def extract_music_info(url): # 模拟浏览器请求头 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' } try: # 获取HTML内容 response = requests.get(url, headers=headers) response.raise_for_status() html = response.text print(html) # 提取艺术家（og:music:artist） artist_match = re.search(r'<meta property="og:music:artist" content="([^"]+)"', html) artist = artist_match.group(1) if artist_match else None # 提取专辑名称（og:music:album） album_name_match = re.search(r'<meta property="og:music:album" content="([^"]+)"', html) album_name = album_name_match.group(1) if album_name_match else None # 提取专辑ID（从music:album的URL中解析） album_url_match = re.search(r'<meta property="music:album" content="([^"]+)"', html) album_id = None if album_url_match: url_content = album_u…

Linux下自定义NVIDIA GPU的风扇转速曲线
type: item
date: 2025-07-28T16:19:00+08:00
description: 在Linux中自定义N卡的风扇转速曲线我个人对硬件的温度比较重视，认为是越低越好，显卡这玩意超过70度我觉得就已经是高温了。由于我已经主力使用Linux系统很久了，一直都是在需要给显卡上强度的时候，直接拉满显卡风扇。但是后面发现不是每时每刻都需要跑满的，没有负载的时候风扇还在呼呼吹确实是有点浪费了，于是就想搓一个bash脚本，用于显卡风扇控制。脚本本体没错，又是面向LLM编程！#!/bin/bash # 初始化上一次的风扇转速 last_speed=-1 while true; do # 获取 GPU 温度（单位：摄氏度） temp=$(nvidia-smi --query-gpu=temperature.gpu --format=csv,noheader,nounits -i 0) # 判断温度范围并计算风扇转速 if (( $(echo "$temp <= 40" | bc -l) )); then current_speed=40 elif (( $(echo "$temp >= 70" | bc -l) )); then current_speed=100 else # 线性插值：温度在 40~70°C 之间，速度从 40%~100% current_speed=$(echo "scale=0; 40 + 2 * ($temp - 40)" | bc) fi # 如果转速发生变化，才执行设置并输出调试信息 if [ "$current_speed" -ne "$last_speed" ]; then echo "GPU Temp: $temp°C → Fan Speed: $current_speed%" nvidia-settings -a "[gpu:0]/GPUFanControlState=1" -a "[fan:0]/GPUTargetFanSpeed=$current_speed" > /dev/null 2>&1 last_speed=$current_speed fi # 每秒检测一次 sleep 1 done脚本说明脚本逻辑：40度以下，转速40%，40度到70度，线性递增，到70度及以上时为100%。至于为什么不是停转？因为我的是涡轮卡，没法停（ ，需要的话请自行修改。使用方法：把代码保存为set_GPU_fan.sh，赋予执行权限后用root执行。建议配合tmux挂在后台。注意事项：这个脚本只针对单GPU，单风扇的情况，如果你是多GPU或者nvidia-settings厘米出现了多个风扇控制，就需要进行脚本的完善和修改。我这个脚本只在有桌面环境的情况下测试过没问题，对于无GUI的情况，我是没有测试过的，据说是要运行X Server才可以运行nvidia-settings。希望这个脚本可以更好的帮助你控制显卡温度。

试玩FreeMote，把二次元老婆搬上浏览器
type: item
date: 2025-07-18T21:51:00+08:00
description: 浅尝开源项目：FreeMote这是一个比较冷门的开源项目，可以看作是E-Mote的开源实现。之前我还是用Windows做主力机使用的Nekopara动态壁纸就是这个项目实现的，而现在我已经切换到Linux作为主力系统使用一坤年了，是时候想想办法把我的巧克力弄到我的桌面上了。Linux想搞动态壁纸，主要就是两种：视频和网页。而FreeMote-SDK就有网页的WebGL实现。很早之前我就尝试过一次，但是那时候技术力不足，而且没学会查看文档，失败了。这次，既然我都能写文章发出来了，那肯定是取得了阶段性的进展了。相比于Live2D，E-Mote的应用就比较少了，主要是几个Galgame在用，其中就包括NEKOPARA。而绝大部分网站的动态二次元看板娘都是Live2D实现的，E-mote几乎看不见。所以文档少，案例少，基本上是摸著石头过河。我主要是研究网页端的FreeMote，下面，就开始探索吧。Demo分析这是项目Project-AZUSA给的网页Demo project-azusa.github.io 基本上可以在网页实现E-mote的功能。不过看了一下FreeMote-SDK，文档约等于没有，只能自己根据网页Demo进行推断了。看描述，说是需要Pure(unencrypted) PSB文件，当然，此PSB不是Photoshop的文件，而是这一套工具的文件格式。为了得到这个文件，则需要FreeMote的这些工具进行转换。接下来就是那个Demo网页用到的文件，我已经爬取下来了：. ├── data │ └── emote_test2.pure.emtbytes ├── driver │ ├── emoteplayer.js │ └── FreeMoteDriver.js ├── img │ └── bg.jpg ├── index.html └── main.js 4 directories, 6 files从文件命名就可以看出，emote_test2.pure.emtbytes是模型文件。但是其格式却不是psb？但是也有可能只是换了一下后缀名。搞清楚了大概的情况，关键点就在于模型文件的获取，以及尝试去替换另一个模型。虽然FreeMote-SDK没有什么文档，但是FreeMote项目的文档还是相对比较完善的，对于生成特定的模型文件具有比较高的参考价值。Demo模型转换测试开始之前，只需要下载FreeMote的工具集即可，在Release里面就有下载了。首先是先要分析现有的文件，按照文档的说法，我决定先尝试解包实例Demo的模型文件：[chocola@chocola-sa5212m4 data]$ wine ../../Ulysses-FreeMoteToolkit-v4.0.3/PsbDecompile.exe ./emote_test2.pure.emtbytes 0024:fixme:mscoree:parse_supported_runtime sku=L".NETFramework,Version=v4.8" not implemented 0024:fixme:mscoree:parse_supported_runtime sku=L".NETFramework,Version=v4.8" not implemented 0024:fixme:ntdll:NtQuerySystemInformation info_class SYSTEM_PERFORMANCE_INFORMATION FreeMote PSB Decompiler by Ulysses, wdwxy12345@gmail.com 18 Plugins Loaded. Decompiling: emote_test2.pure Done. [chocola@chocola-sa5212m4 data]$ ls emote_test2.pure emote_test2.pure.emtbytes emote_test2.pure.json emote_test2.pure.resx.json [chocola@chocola-sa5212m4 data]$ tree . ├── emote_test2.pure │ └── tex-texture.png ├── emote_test2.pure.emtbytes ├── emote_test2.pure.json └── emote_test2.pure.resx.json 2 directories, 4 files [chocola@chocola-sa5212m4 data]$ 可以看到解包后有tex-texture.png纹理图片和emote_test2.pure.json设置文件，其中纹理图片和L…

Python实现浪潮SA5212M4风扇根据温度自动调节
type: item
date: 2025-03-19T20:43:00+08:00
description: 浪潮SA5212M4风扇调速Python脚本写脚本的原因之前每次开机都要进BMC把风扇转速调低，不然吵得要死。但是又不能调得太低，因为如果调的太低怕一不留神温度就飙上去了，导致硬件出问题。正好前几天看到了一个别人用Python写的简易风扇一键调节脚本，但是只能设置固定转速，没办法根据温度动态调节。于是我重构了这个脚本，做到了根据温度动态调节风扇转速。环境要求系统要求：Linux（Windows不可用，因为没有sensors软件包）软件环境：Python3环境，sensors软件包（用于获取CPU温度）Python源代码import subprocess import re import http.client import time # 全局变量用于存储会话连接和令牌 conn = None session_cookie = None def login(IP, User, Password): global conn, session_cookie if conn is not None: conn.close() # 关闭旧连接 conn = http.client.HTTPConnection(IP) payload = "WEBVAR_USERNAME=" + User + "&WEBVAR_PASSWORD=" + Password headers = { 'Content-Type': "application/x-www-form-urlencoded", 'Origin': "http://{}".format(IP), 'Referer': "http://{}/index.html".format(IP), 'User-Agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36 Edg/130.0.0.0", } conn.request("POST", "/rpc/WEBSES/create.asp", payload, headers) response = conn.getresponse().read().decode("utf-8") match = re.search(r"'SESSION_COOKIE' : '([^']*)'", response) if match: session_cookie = match.group(1) else: raise ValueError("SESSION_COOKIE not found in the string") def set_fan_speed(IP, fan_speeds): global conn, session_cookie # 设置风扇为手动模式 payload1 = "MODE=1" headers1 = { 'Content-Type': "application/x-www-form-urlencoded", 'Cookie': "BMC_IP_ADDR={}; SessionCookie=".format(IP) + session_cookie, } conn.request("POST", "/rpc/setfanmode.asp", payload1, headers1) conn.getresponse() # 调整风扇转速 headers2 = { 'Content-Type': "application/x-www-form-urlencoded", 'Cookie': "SessionCookie=" + session_cookie + "; BMC_IP_ADDR={}".format(IP), } for fan_ID, Speed_x in fan_speeds.items(): payload2 = "ID=" + fan_ID + "&PERCENT=" + Speed_x conn.request("POST", "/rpc/setfanspeed.asp", payload2, headers2) conn.getresponse() print("调整风扇{}转速{}%".format(fan_ID, Speed_x)) def get_package_temperatures(): output = subprocess.check_output(['sensors']).decode('utf-8') pattern = re.compile( r'^Package id (\d+):\s+\+([\d.]+)…

本地Ollama跑LLM并接入QQBot
type: item
date: 2025-02-10T21:30:00+08:00
description: 速通Golang后的想法前段时间我处于个人兴趣目的速通了Golang的基础知识，然后就想要干些什么玩一下，想到了我QQ群里面有一个Bot还在苟活，于是有点想改造一下。机器人使用的是ZeroBot-Plugin，项目是在Github开源的，使用的是Go语言编写，这下专业对口了。正好前几天折腾LLM本地部署，尝试了一下Ollama部署各种模型，觉得挺好玩的。然后想试试看NAS上的E3-1220v2能不能跑得动。一开始为选的1.5B的超小模型，跑起来速度挺快的，于是提高难度，用了3B的模型，速度变慢了，但是还行。试了一下回答的质量，感觉简单放群里面当个玩具还是可以的。最后，我选择的模型是Qwen2.5 3B。部署Ollama去Ollama的官网下载就行，对于Linux也有安装脚本。但是我还是更喜欢自己手动部署和管理。下载Ollama前往Github的Ollama项目界面，进入Release页面根据你的实际情况进行下载。我下载的是ollama-linux-amd64.tgz设置参数运行由于Ollama默认会把相关的文件放在你用户文件夹的.ollama文件夹下，一旦下大模型，系统盘将会爆炸。如果你Linux把/home放到了单独的数据分区或者你系统盘足够大就当我没说。我们需要改一下这个默认的目录，方法很简单，就是在当前目录文件夹新建一个用于放置数据的文件夹，然后设置环境变量指定HOME的目录：export HOME=./data/ ./bin/ollama serve把以上保持为run.sh放在Ollama的目录下，然后再在目录创建一个data文件夹，运行即可把相关文件保存在data文件夹中而不会放到你的Home目录。此时，Ollama已经启动了。测试Ollama接下来，就可以按照官方给的参数运行模型了。进入bin/目录，直接运行Ollama即可。例如运行Qwen5.2 3B模型：./ollama run qwen2.5:3b等待模型下载完成就可以运行了。爆改ZeroBot-Plugin在仔细品读代码后，我感觉好像也不是特别难，于是为就想试一下自己写一个插件来调用Ollama进行聊天。设置插件首先，下载ZeroBot-Plugin的源代码，建议是去Github的Release里面下。我用的是1.7.8版本，后面的版本似乎会有内存泄漏问题，而且相应变慢了，也不知道修了没有，反正一年前我用1.8.X的时候是这样的。下面就是插件的代码了，放到plugin/nekochat目录下，其中nekochat文件夹要自己创建。然后在nekochat文件夹创建一个nekochat.go文件：package nekochat import ( "bytes" "encoding/json" "net/http" //"github.com/FloatTech/imgfactory" ctrl "github.com/FloatTech/zbpctrl" "github.com/FloatTech/zbputils/control" zero "github.com/wdvxdr1123/ZeroBot" "github.com/wdvxdr1123/ZeroBot/message" ) var ( // 定义固定的前两条消息作为范例对话 fixedMessages = []Message{ { Role: "user", Content: "从现在开始你是猫娘，名字是亚托莉，要以猫娘的方式说话和思考问题。", }, { Role: "assistant", Content: "好的喵～，主人！ ୧(๑•̀⌄•́๑)૭ 亚托莉酱知道了，有什么需要本喵帮忙呢？", }, } // 使用固定消息初始化ChatContext context = NewChatContext(fixedMessages) //默认选择通义千问2.5 3B模型 model_choose = "qwen2.5:3b" ) // 定义最大消息数为11，但是前两条消息是固定的范例对话 const maxMessages = 12 // ChatContext 结构体用于保存聊天的上下文信息 type ChatContext struct { messages []Message // 消息列表，每个元素是一个 Message 结构体 } // Message 结构体表示一条消息，包含角色（如 user 或 assistant）和内容 type Message struct { Role string `json:"role"` // 角色字段，如 "user" 或 "assistant" Content string `json:"content"` // 内容字段，实际的消息文本 } /…

开新坑：入 门 Golang ！
type: item
date: 2025-01-26T23:11:00+08:00
description: 为什么学Go?其实之前就有点想学，因为听说这个编程语言，既有Python的简单和方便，又有C的运行高效。实际上第一次接触到GO,是因为向自己改一下ZeroBot-Plugin这个项目的一点点代码，也就是CPU核心读取不正常的问题，我找LLM修复了一下面向LLM编程(bushi。看了看代码，有Python的基础，挺多能看懂的。这也坚定了我想要学Golang的想法。于是，这个寒假，在整理完成歌曲库，升级完成NAS后闲得蛋疼，我决定开始学习GO。本页面会随着我的学习进度逐步更新，权当是当个笔记了。第一个Ciallo WorLd！一般编程语言学习，第一个程序都是Hello World，但是这次我向整点不一样的：package main import "fmt" func main() { fmt.Println("Ciallo World!") }另外，有一个写代码小技巧，选取多行，按Tab可以整行缩进，Shift+Tab可以反向操作。Ctrl+/可以多行进行注释，对Debug很有用。变量与数据类型局部变量和全局变量局部变量示例：package main import "fmt" func main() { var ss int = 233 fmt.Println("Ciallo World!",ss) }全局变量示例：package main import "fmt" var ss int = 233 func main() { fmt.Println("Ciallo World!",ss) }或者这样，更加简洁：package main import "fmt" var( ss = 2333 st = "sxsxsx" fl = 1234.555 fl2 = 2323E+2 ) func main() { fmt.Println("Ciallo World!",ss,st,fl.fl2) }值得注意的是，在Go中，如果变量只声明而不使用，编译就会报错。int数据类型在Go语言中，int 类型与 int8, int16, int32, 和 int64 都是用来表示整数的数据类型，但它们之间存在一些关键区别，主要体现在大小、范围和平台依赖性上。下面是这些类型的区别列表说明：类型占用空间数值范围适用场景int88位（1字节）-128 到 127需要节省内存且数值范围较小的场景int1616位（2字节）-32,768 到 32,767比int8更大的范围，但仍需控制内存使用时int3232位（4字节）-2,147,483,648 到 2,147,483,647处理更广泛的数值，例如时间戳或计算密集型应用int6464位（8字节）-9,223,372,036,854,775,808 到 9,223,372,036,854,775,807非常大的整数值或者需要精确到极大值的应用场景int取决于平台（32位系统上为4字节，在64位系统上为8字节）范围取决于系统的架构大小不考虑具体大小的通用情况，追求代码的可移植性和简洁性声明变量：直接赋值var a int8 = 10 // int8 类型变量a被赋予值10 var b int16 = -200 // int16 类型变量b被赋予值-200 var c int32 = 30000 // int32 类型变量c被赋予值30000 var d int64 = 400000 // int64 类型变量d被赋予值400000 var e int = -500 // 根据系统架构决定大小的int类型变量e被赋予值-500使用短变量声明f := int8(100) // 使用短变量声明为int8类型变量f赋值100 g := int16(-30000) // 使用短变量声明为int16类型变量g赋值-30000 h := int32(50000) // 使用短变量声明为int32类型变量h赋值50000 i := int64(600000) // 使用短变量声明为int64类型变量i赋值600000 j := int(-600) // 使用短变量声明为int类型变量j赋值-600float数据类型包括float32和float64：类型占用空间精度数值范围（大约）适用场景float3232位（4字节）小数点后约7位有效数字±1.5 × 10^-45 到 ±3.4 × 10^38对内存使用敏感且不需要高精度的场合，例如图形处理、物理仿真等需要大量浮点计算但对精度要求不是极高的应用float6464位（8字节）小数点后约15位有效数字±5.0 × 10^-324 到 ±1.7 × 10^308需要高精度的数值计算，如科学计算、金融计算等声明变量：直接赋值var k float32 = 123.456 // fl…

自建Jellyfin私人媒体服务器，告别屌毛网易云！
type: item
date: 2025-01-18T19:24:00+08:00
description: Jellyfin私人媒体服务器搭建指南成功搭建了jellyfin服务器，拥有了自己的私人媒体库，记录一下折腾过程。起因∶网易云无故被封促进我自建媒体库的原因，是因为网易云乱封号，两次把我的号给封了。理由居然是——播放数据异常真就是，想封你，随便编个理由，直接就封。纯脑残！其实之前我就有点想搞媒体服务器了，但是由于我看番都是用种子下载看番，而且番剧看一次也就过去了，我觉得也没用留着的必要。毕竟番剧的一话，1080P 60帧，都要差不多1GB了，看番多的话，文件破TB级那是轻轻松松。这次封号，算是坚定了我的想法。我觉得国内互联网公司绝大部分都是狗屎，让人无语。其实是2024年10月封的号，但是我2025年1月才开始折腾媒体服务器。因为之前都在学校，课业繁忙，乐的要死，因为整理音乐库费时费力，所以我打算放假再搞。事实证明我的想法是对的，我前前后后整理了快一个星期，整理了绝大部分，但是还有相当一部分歌曲还没整理。太累了，让我歇歇。目前已经整理了1300+首歌，文件夹已经90G+了。。。为什么选择了Jellyfin？免费，开源。开源，开源，开源，还是他妈的开源！我是支持GNU自由软件运动的人，自然更倾向于使用开源的解决方案，尤其是使用GPL协议的开源软件。顺带一提，我主力操作系统早就已经换成GNU/Linux了。部署Jellyfin下载Jellyfin直接前往官方网页下载即可，我用的最新版，目前是10.10.3。下载链接：repo.jellyfin.org/?path=/server/linux/latest-stable下载FFmpeg由于我服务器使用的是AlmaLinux8.10，是服务器发行版，其自带的FFmpeg比较老，新版的Jellyfin并不兼容。虽然可以通过yum包管理器直接安装对应版本的Jellyfin，并且不会出现兼容问题。但是旧版的Jellyfin并没有歌词支持，对我来说比较蛋疼，因为我主要想做的就是歌曲的媒体服务器。我下载的是7.0.2版本的，这种的话，我更倾向于使用最新版的前一个稳定版。下载地址：ffmpeg.org/releases/ffmpeg-7.0.2.tar.xz自定义环境变量，以使用自定义的ffmpeg我的做法是，把FFmpeg和Jellyfin解压后，分别放到了不同的文件夹，然后在根目录文件夹放了一个启动脚本。以下是启动脚本的内容：#!/bin/bash # 定义FFmpeg二进制文件所在的路径 FFMPEG_PATH="./ffmpeg/bin" # 将FFmpeg路径添加到PATH环境变量的最前面 export PATH="$FFMPEG_PATH:$PATH" # 启动Jellyfin ./jellyfin/jellyfin脚本保存为run.sh，然后再：chmod +x ./run.sh试一下执行这个脚本，看看Jellyfin有没有启动成功，如果启动成功后就完事了。配置Jellyfin初始化配置打开浏览器，输入服务器对应的ip+8096端口，例如：127.0.0.1:8096按照指引，设置用户名和密码。这部过于简单，有手就行，不多赘述。配置HTTPS访问这个Jellyfin比较特别，需要使用pfx证书，而不是常见的pem+key的证书组合。我们需要把pem和key证书转成pfx格式。下面是一个shell脚本，可以便利当前目录的pem+key证书，并且转换为pfx证书放到当前目录的pfx_cert/文件夹内：#!/bin/bash # 定义输出目录 OUTPUT_DIR="pfx_cert" # 创建输出目录（如果它不存在） mkdir -p "$OUTPUT_DIR" # 遍历所有的 .key 文件 for key in *.key; do # 获取不带扩展名的文件名 base_name="${key%.key}" # 检查对应的 .pem 文件是否存在 if [[ -f "${base_name}.pem" ]]; then echo "正在处理 $base_name..." # 转换为 PFX 格式 openssl pkcs12 -export \ -out "${OUTPUT_DIR}/${base_name}.pfx" \ -inkey "$key" \ -in "${base_name}.pem" \ -certfile le-chain.pem echo "已生成 ${OUTPUT_DIR}/${base_name}.pfx" else echo "警告：找不到与 $key 对应的 .pem 文件" fi done把以上内容保存到to_pfx.sh，然后：chmod +x ./to_pfx.sh ./to_pfx.sh当要求输入密码的时候，直接回车，不设置密码。在Jellyfin…