笔记 · 7 分钟
把 QQ 的 SILK 语音拆开,再拼成 WAV
SILK 是 Skype 留下的窄带编码,QQ 一直用。它不是标准 WAV,文件头有时是 #!SILK_V3,有时什么都没有,所以第一步不是解码,是认它到底是什么。
认出来之后用 pysilk 解,得到的是 24kHz 单声道 PCM,再交给 wave 写成 WAV。24kHz 已经比原始语音高,够听,也不用重采样成 44.1k 自欺欺人。
批量的时候,文件名比音频更容易出问题:Windows 不接受冒号,中文路径可能被截断,重名会互相覆盖。所以先清洗、再编号,失败的文件单独列出来,不藏。
整个过程在本地跑完,不上传,也不删原文件。这不是技术选择,是礼貌。
技术 · 9 分钟
一张图片里,最多能藏下多大的压缩包
把数据追加到文件末尾,图片仍然能被正常打开,因为解码器读到图像数据结束就停了,后面的字节它不看。能藏多少,取决于文件系统和你能接受多大的「图片」。
FAT32 单文件上限 4GB,NTFS 理论上很大,但实际瓶颈是传输:微信、网盘、邮件附件都有各自的天花板。所以程序里不承诺「无限大」,只告诉你导出后大了多少。
另一个隐形成本在缩略图。Windows 资源管理器会缓存预览图,替换之后如果没刷新,你会以为失败;这不是藏得不够深,是缓存没跟上。
最后,加密是必须的。AES-256 之后密文看起来就是随机噪声,就算有人发现尾部有东西,也拿不到内容。
实践 · 6 分钟
用 cloudflared 给本地视频开一扇临时的门
需求很简单:把本机一个视频发给别人看,又不想上传到任何平台。Flask 起一个只监听 127.0.0.1 的服务,cloudflared 把它映射到公网,链接带随机 token,过期作废。
关键在 Range 请求。没有它,浏览器只能从头播,进度条拖不动;加上之后,Flask 按分片返回,才像一个正常的视频源。
隧道建立要几秒,这期间链接打不开。界面必须说「正在开门」,而不是让人对着 502 猜。关闭程序时记得把 cloudflared 子进程一起收掉,否则隧道会一直挂着。
免费隧道带宽有限,大文件会卡。这不是 bug,是价格。
打包 · 12 分钟
从 .py 到安装包:PyInstaller 与 Inno Setup 踩坑记
PyInstaller 负责把 Python 变成 exe,Inno Setup 负责把 exe 变成「能装、能卸、有开始菜单」的安装包。前者解决依赖,后者解决体面。
坑一:数据文件。ffmpeg、图标、模板不会自己进去,得在 spec 里写 datas,运行时还要用 sys._MEIPASS 找路径,不能用 __file__——这条最容易忘。
坑二:杀毒软件。无签名的新 exe 很容易被拦,体积越大越可疑。能做的只有两件事:别加壳,给出校验值。
坑三:卸载。Inno Setup 默认只删安装目录,用户的数据要显式保留;反过来,程序留下的进程要显式结束。写清楚这两件事,比多一个炫酷的安装动画重要。
最后一次打包,我坐在旁边看进度条走了四分钟。那四分钟比写代码更让人踏实。
设计 · 4 分钟
为什么我的每个小工具都是深色的
不是跟风。这些工具大多在晚上用:导语音、转 GIF、整理藏品,屏幕旁边通常只有一盏台灯。深色界面不刺眼,颜色也更容易做得安静。
另一个原因是图片。藏品柜和 GIF 工具里全是预览图,深底能把图片托起来,浅底反而会让图片边缘发灰。界面退后一点,内容就靠前一点。
但深色不是纯黑。纯黑会把阴影吃掉,让所有层次变成一块板;我用的是带一点绿或紫的深灰,留得住边界,也留得住呼吸。
当然,白天用也不是不能看。好的深色界面不该只在晚上成立。