八年了,从一个随机数按钮到我的技术底座:豆子工具复盘

有些事,不做笔记真的意识不到已经过去了这么久。 最近在整理博客内容时,我翻到了**“豆子工具”小程序**的最早版本记录。那是 2018 年,最初的它简陋得甚至有点滑稽:整个页面只有一个按钮,点一下,生成一个随机数。 谁能想到,这颗“小豆子”一跑就是八年。 八年,它长成了我最趁手的“瑞士军刀” 这八年里,我在这款小程序上倾注了太多的时间和精力。它更像是我个人开发者生涯的一个“活化石”,记录了我每一个阶段遇到的问题和想出的方案。 我始终坚持一个原则:只做真正有用的。 现在的“豆子工具”已经从当年的随机数生成器,进化成了一个覆盖网络、多媒体、开发调试的全能工具箱: 网络与运维必备:获取 WIFI 公网地址、云厂商安全组管理、查服务端口、域名证书检测。 多媒体处理:音频格式转换(m4a 转 mp3)、图片格式转换(png 转 webp)、二维码识别与生成。 开发调试利器:局域网调试(TCP/UDP/WebSocket)、ESP 网络配置、时间戳转换、Base64 与 URL 编解码。 安全与提醒:私密密码本、事件邮件通知、微信服务通知、语音验证码。 这中间还有很多功能,比如查看上报信息、特定的算法实现等。当然,也有不少功能因为受众太小或者微信审核的边界问题,遗憾地消失在了版本更迭中。 它是工具,也是我的技术底座 很多人问过我,市面上工具软件那么多,为什么要自己写? 答案很简单:自由。 我可以为了适配一个特殊的局域网协议去写一套调试代码,也可以为了保护自己的隐私数据写一个加密密码本。这八年积累下来的不只是功能,更是对 Go、Rust、前端交互以及各种底层协议的深度理解。 关于未来的“深度复盘” 八年的积淀太厚,小程序那方寸之间已经装不下太多的原理说明。 所以,我决定在我的新博客中,为这些工具开辟专门的专栏。我会挑选出其中含金量最高、逻辑最有趣的工具,拆解它们的实现原理。比如: 多媒体黑盒:音频和图片格式转换在小程序前端是如何高效完成的? 网络深水区:局域网内的协议调试有哪些不为人知的坑? 消息推送系统:我是如何设计那套多端触发的事件通知系统的? 这些内容我会以“实战笔记”的形式,在这里逐一连载。 这颗“豆子”还会继续长下去,而关于它的故事,我们去博客细聊。

2018-01-03 · 1 min · Eagle

Wander 项目功能列表状态--列表形式

记录曾经存在的功能,列表形式展示。 音频转 MP3 可以将 IOS 的录音文件 m4a 格式转换为 mp3 格式,在老设备播放,或者其它特殊应用场景。 使用方法:搜索豆子工具小程序,点击音频格式转换。 推荐理由:方便用户在手机上操作,可以转换音频,还可以试听效果。 获取 AST 账户 AST 账户用于连接 Asterisk,是自助语音验证码重要的一个环节。 你可以搜索【豆子工具】小程序,获取自己的 AST 账户。 注意:AST 账户获取后并不是马上生效,它需要到次日方可使用。这是因为它在凌晨会进行一次同步,会同步到 Asterisk 数据库。 后续我们会讲下如何实现自助语音验证码。 获取识别码 识别码用于开放接口认证。专属 ID 码为自定义识别码,方便用户记忆。 目前开放接口为: 获取本机公网 IP 获取 IP 地址的归属地 你可以搜索【豆子工具】小程序,获取自己的识别码。 然后使用你喜爱的编程语言调用开放接口。 开放接口 API 请查看【豆子笔记】网站。 获取本机局域网 IP 状态:上架 上架原因:有适用场景,可用于获取手机的局域网 IP,排查问题时使用。 实现原理:调用小程序的本地获取 IP API。 获取网络打印机地址 状态:上架 上架原因:有适用场景,可用于获取局域网的网络打印机 IP 地址。 实现原理:调用小程序的 mdns API。 获取验证码 验证码用于访问豆子笔记网站认证使用。它是一次性码,用完即作废,5 分钟内有效。 豆子笔记网址:www.91demo.top 除了在豆子工具小程序获取验证码外,还有一个自助语音验证码,使用 Asterisk 实现。我们会在后续的章节进行讲解。 获取豆子点数 观看激励广告可获得豆子点数。 豆子点数用于使用小工具。添加豆子点数机制,是为了更好的促进豆子工具良性的发展。 除了观看激励广告获取豆子点数外,还可以使用九宫格大转盘抽取豆子点数, 报 IP 地址归属地也可以获取豆子点数奖励。 ...

2018-02-25 · 1 min · Eagle

实战笔记:为了管好那堆记不住的密码,我给自己写了个全加密密码本

虽然现在的 App 普遍支持手机号或微信一键登录,但对于开发者来说,GitHub、服务器、各类海外服务的登录依然离不开“邮箱+密码”的传统模式。 我曾经历过一段漫长的“密码管理进化史”: Excel 时代:最早用一个加密的 Excel 表格记录,在电脑端还凑合。 Flutter App 时代:为了手机查看方便,我曾写过一个简单的 Flutter App,支持指纹查看,但功能简陋,连“修改”功能都没有。 直到有一次,GitHub 要求我重新登录,由于我频繁重置密码且新旧密码不能重复,导致我彻底记混了。在另一台电脑前尝试了无数次失败后,我意识到:我需要一个足够安全、随时可用、功能完整的个人密码管理工具。 于是,“豆子工具”里的小程序版密码本诞生了。 1. 设计核心:绝对的隐私与自由 在设计之初,我就定下了两个原则:不联网、重加密。 纯离线运行:为了打消用户(包括我自己)对隐私的顾虑,我砍掉了所有联网备份功能。所有的密码数据仅存储在手机本地,备份只能通过聊天文件导出。 三重加密体系:这是我花费心血最多的地方。主密码(Master Password)不存储在设备上。 第一步:用主密码解密 RSA 私钥。 第二步:用私钥解密 AES 密钥。 第三步:用 AES 密钥解密具体的 JSON 序列化记录。 这种混合加密机制确保了即使手机丢失,只要主密码不泄露,数据依然是安全的。 2. 攻克开发中的“大山” 这个功能的开发过程远比我想象中痛苦。尤其是在小程序环境下处理文件缓存、二进制流转换和加解密逻辑,经常一个 Bug 就要调试好几天。 中途我好几次想过放弃,觉得用 Excel 也可以凑合。但每次想到反复重置密码的痛苦,还是咬牙坚持了下来。为了稳定性,我将原本不稳定的二进制存储改为了 UTF-8 编码的 JSON 序列化,最终实现了丝滑的操作体验。 3. 功能完善:不仅仅是“存一下” 相比之前的 Flutter 版本,这次我补全了所有短板: 增删改查:支持搜索功能,输入标题就能快速定位账号。 备份恢复:加入了完整的备份机制,更换手机时可以轻松迁移数据。 批量操作:支持导入和导出,方便从其他平台平替过来。 密码提示:为了防范“忘记主密码”这个终极灾难,我加入了密码提示功能(建议设一个只有自己懂的暗语)。 4. 字段灵活,满足多样需求 每一条记录都包含了:标题、URL、用户名、密码、备注。 无论是一个服务器的 SSH 密码,还是一个冷门网站的登录信息,都能井井有条地分类存放。 总结 这个密码本工具是我最用心、也觉得最实用的作品之一。它没有花哨的云同步,却给了我最踏实的安全感。 最后再次提醒: 由于是全离线存储,请务必定期通过“导出备份”功能保存你的数据,并牢记你的主密码。

2018-01-11 · 1 min · Eagle

实战笔记:为了不再漏掉任何一个域名到期提醒,我做了个自动化检测工具

在运维工作中,有一类事故极其低级却又杀伤力巨大:SSL 证书过期。 痛点:被动挨打的“救火”模式 由于业务需要,我手里管理着大量客户的域名。每个客户购买证书的渠道各异(阿里云、腾讯云或其他厂商),证书下来后通过微信或邮件发给运维,再手动配置到服务器上。 这套流程在客户少的时候还算正常。但随着客户增多,问题出现了:证书到期时间不一,全靠人工记忆。 总会有那么一两次,因为忙碌或者交接疏忽,某个域名证书悄悄过期了。直到客户反馈 APP 无法访问、浏览器弹出红色的安全告警,我们才急忙去“救火”。这种被动的局面不仅影响专业度,也给客户带来了实际损失。 方案:主动出击的自动化巡检 为了彻底根治这个“心病”,我决定做一个自动化的域名证书检测工具。 我的设想很简单:变“人找信息”为“信息找人”。 1. 实现原理 配置简单化:将所有需要监测的域名汇总成一个 txt 文件,每行一个域名,管理起来极其方便。 核心引擎(Go):使用 Go 语言开发后端服务,利用 cron 库开启定时任务,设定每天固定时间(如凌晨 4 点)执行一次巡检。 检测逻辑:程序自动循环读取域名列表,通过 TLS 握手获取证书的有效载荷,计算当前的剩余天数。 精准预警:我设定了一个“7天阈值”。一旦发现有域名将在 7 天内过期,程序会立即将这些域名汇总。 2. 消息触达:为什么选择机器人? 在小程序中,邮箱属于敏感隐私资料,审核往往比较严格。为了避开这个麻烦,同时也为了让通知更具实时性,我选择了钉钉机器人和企业微信机器人。 管理员或运营人员只需将机器人的 Webhook 地址配置好,每天早上一上班,就能在手机上收到一份清晰的到期清单。 价值:买到了最宝贵的“时间” 这个功能上线后,我们最直接的收获就是**“沟通时间”**: 提前预判:有了 7 天的缓冲期,运营人员可以气定神闲地与客户沟通续费。 提前操作:运维人员有了充裕的时间更换新证书,彻底杜绝了“半夜修证书”的尴尬。 总结 很多时候,自动化并不是为了追求多么高大上的技术,而是为了把人从那种机械、高风险的记忆工作中解放出来。 这个小工具的逻辑虽然简单,但它是我内容生态中非常重要的一环。它验证了:只要抓住了痛点,简单的技术组合也能产生巨大的生产力。

2018-01-10 · 1 min · Eagle

实战笔记:为了不再发错下载链接,我给工具箱加了“扫码鉴定”

在软件发布流程中,最尴尬的事情莫过于:宣传图已经发出去了,用户扫码后却发现链接打不开,或者下载了一个旧版本的安装包。 我就亲身经历过这么一次“翻车”事故。 事故现场:一个 URL 引起的麻烦 我曾经碰到这样一个情况,网站上附带有二维码,用于下载安卓 APP。某天,用户反馈扫码下载的安卓 APP 没有新开发的功能。经过排查才发现是二维码的问题。 使用网站点击下载的用户正常,使用手机扫二维码下载的安卓 APP 没有新功能。原因为扫码下载还是使用的老链接地址,使用的上一个版本。这个时候,测试如果不细心的话,就不会发现这个问题。如果你手边有个可以识别二维码内容的小工具,那么你大概率不会在这种问题上栽跟头。 虽然这只是一个低级错误,但它让我意识到:在二维码挂载后、正式发布前,必须有一个极简的“内容鉴定”环节。 痛点:如何快速、无痛地校验? 通常我们校验二维码,习惯性地直接拿手机扫一下。但如果二维码指向的是一个大容量的 APP 下载包或复杂的跳转链接,扫码后手机会自动触发下载或进入复杂的网页路径。 我其实并不想真的下载并安装测试(那是后续的 QA 环节),我只是想一眼看到二维码里到底写了什么字符,确定那个 URL 是不是我想要的那一个。 实现:借力小程序的原生能力 既然发现了痛点,解决起来就非常顺手了。得益于微信生态对扫码的深度支持,我在“豆子工具”里实现了一个“二维码识别”功能: 核心逻辑:直接调用小程序的 wx.scanCode 接口。 功能表现:不仅支持扫描实物二维码,还支持从手机相册里直接读取生成的二维码图片。 结果反馈:系统不会触发自动跳转,而是将二维码包含的原始文本、URL、一维码内容直接以纯文本的形式展示在屏幕上。 当你碰到陌生的二维码时,忍不住想看,但又担心是病毒时或者有害网站时,不妨先使用该工具扫描二维码。如果二维码内容是网站链接,它不会跳转到网站,只会显示网址,非常安全。 价值:多看一眼,少出一次错 现在,每当我生成一个新的二维码,无论是用于软件下载、文档分享还是活动跳转,我都会习惯性地用自己的工具“扫一下”: 确认 URL 参数是否完整。 确认是否有肉眼难以察觉的拼写错误。 确认二维码的类型(一维码还是二维码)是否符合预期。 总结 这个功能的代码实现极其简单,几乎就是调用一个 API 的事。但它的价值在于改变了工作流——在发布前的最后关头,提供了一个低成本的“人工校验点”。 很多时候,工具的作用不仅仅是自动化,更是为了在我们疏忽大意时,拉我们一把。

2018-01-09 · 1 min · Eagle

实战笔记:当我想查端口却没装 Telnet 时,我决定自己写个工具

我从事于 IT 工作,经常会碰到各种奇葩的问题。其中的一项就是服务无法访问,当碰到这些情况,如何快速的排查问题?如果手边有电脑,那还好办,直接打开电脑找问题即可。如果手边没有电脑,我们怎么快速的定位问题?是服务挂掉了?还是服务器宕机了? 我的基本思路是这样的,先查看服务器是否宕机,如果服务器没有宕机,那么查看服务是否挂掉?如果服务没有挂掉,那么很大可能是数据造成的问题,或者程序 Bug。 某次我急需确认服务器上的一个端口是否正常开启,习惯性地打开 Windows 命令行准备敲下 telnet 命令。结果弹出的却是:“telnet 不是内部或外部命令”。这是让我抓狂的一刻。 由于系统刚重装,这个组件还没勾选。当我从控制面板找到它、安装、甚至可能还要重启系统时,这套复杂的操作让我陷入了反思:为了检测一个端口,至于这么麻烦吗? 更进一步想,如果我手头没有电脑,只有一部手机,我该如何快速判断服务器防火墙是不是忘了开? 痛点:环境依赖与生态限制 在实现这个功能之前,我有过两个思考维度: 环境依赖:无论是 Windows 的 Telnet 还是 Linux 的 nc,都依赖当前操作系统的环境配置。 小程序限制:微信小程序虽然有网络请求能力,但它必须配置服务器域名白名单。如果你想直接用小程序前端去探测一个随机的 IP 或端口,微信的底层安全机制是不允许的。 方案:Go 后端代劳,小程序只做“遥控器” 为了绕过这些限制,我在“豆子工具”里实现了一个远程端口检测功能。它的逻辑非常直接且高效: 前端交互:用户只需在小程序里输入目标服务器的 IP/域名 和 端口号。 后端核心:数据提交到我用 Go 编写的后端服务。 模拟连接:后端服务代替用户执行 TCP 连接探测。Go 语言的 net.DialTimeout 在这里非常实用,可以精准控制探测时间,避免由于网络超时导致的页面死等。 结果反馈:后端将“连接成功”或“连接失败”的结果返回给小程序展示。 那么如何操作呢? 1,访问服务器的 SSH 端口,查看是否通畅?如果程序返回开启,那么进行下一步。 2,访问服务端口,查看是否挂掉?如果程序返回开启,那么进行下一步。 3,查看其他用户是否这样的情况?如果是,大概率是程序 Bug,如果不是,大概率给这个用户的数据相关。 价值:随时随地的“运维眼” 自从这个功能上线后,我解决了很多尴尬的场景: 排查防火墙:在云厂商后台改了安全组策略后,掏出手机点一下,秒知是否生效。 现场交付:在客户现场没有电脑时,快速确认后端服务是否已经拉起。 零部署成本:再也不用担心当前电脑有没有装 Telnet 或 Netcat。 总结 很多时候,工具的意义并不在于它用了多么高深的算法,而在于它是否能在你最需要的时候,以最简单的方式解决那个微小却刺手的痛点。 这个小功能的背后,其实是 Go 语言并发网络模型的一个微小缩影。

2018-01-08 · 1 min · Eagle

实战笔记:从一个按钮到全能生成器,随机数功能的“进化论”

还记得我之前提到的吗?2018 年,“豆子工具”的初版只有一个功能:点一下按钮,生成一个随机数。 那时候的代码逻辑极其简单,甚至算不上一个“工具”。但随着这几年自己在开发、运维过程中不断遇到“需要一个复杂密码”、“需要一个 16 位纯金钥”或者“需要一个全大写 ID”等实际场景,我发现简单的随机数其实并不简单。 痛点:单一随机数的局限 早期的随机数功能非常死板,生成的格式往往不是我想要的。每次生成后,我可能还需要手动去改长度、改大小写,甚至手动补上特殊字符。 作为一个开发者,如果一个工具不能让我“一键到位”,那就是不合格的。 进化:高度自定义的“融合模式” 于是,我把这些年所有关于“随机”的需求全部揉碎、重组,将它升级成了一个全能的生成器。 现在的随机数功能,不再是盲目地随机,而是基于规则的精准生成。我为其设计了一套组合逻辑: 长度自定义:不再局限于几位数字,用户可以根据需求自由输入长度。 字符集自由组合: 纯数字:适用于验证码类场景。 纯字母:适用于临时 ID 或变量命名。 字母+数字:兼顾强度与易读性。 含特殊字符:专门为高强度随机密码设计。 结果格式化: 支持结果一键转大写或转小写。这在配置某些特定系统的 API Key 时非常有用,省去了手动切换输入法的麻烦。 思考:小功能里的“产品观” 虽然随机数在技术实现上只是简单的字符数组随机采样,但从产品角度看,它体现了一种**“减少用户操作”**的原则。 把纯数字、字母、符号和格式化选项融合在一起,本质上是把原本需要用户在脑子里构思、在手里修改的过程,变成了一个简单的“勾选”动作。 以前,我曾把这个功能做的非常复杂,可以生成Excel文件并进行下载,但是当我上线后,我发现这个功能用的人很少,而我自己也没有这样的场景。我用的最多的就是需要一个临时密码,用来分享时会用到。所以就砍掉了这个功能。 当简化之后,它有几个好处:1,增加了稳定性,因为去掉了导出Excel的功能。2,界面更简单,减少了很多输入的操作,方便使用。 总结 现在,每当我需要为一个新数据库设置密码,或者为测试环境生成一批随机标识时,我都会习惯性地打开这个功能。 从 2018 年那个只有一个按钮的“玩具”,到如今能够满足生产环境需求的“工具”,这种一点一滴的打磨,也许正是独立开发者的乐趣所在。

2018-01-07 · 1 min · Eagle

实战笔记:知识真的就是金钱,聊聊我的局域网调试工具

在“豆子工具”的所有功能中,局域网调试工具(TCP/UDP/WebSocket) 并不是受众最广的,但它却是我最引以为傲的一个。 因为它让我真切地体会到了一句话:知识就是力量,知识就是金钱。 缘起:把调试器揣进口袋 做嵌入式开发或者网络协议调试的人都知道,以往测试局域网通信,必须背着电脑,接上串口线或网线,蹲在机柜旁守着。我当时就在想:既然微信小程序已经开放了网络通信的能力,为什么我不能做一个随身携带的调试器呢? 于是,我深度调用了小程序的 wx.createTCPSocket、wx.createUDPSocket 和 WebSocket API,在“豆子工具”里构建了一个完整的网络测试模块。它支持: 十六进制(Hex)与 ASCII 码切换 实时数据日志展示 局域网内稳定的数据收发 变现:从技术分享到“第一桶金” 工具做成后,我并没有藏着掖着,而是把实现原理和核心逻辑整理成文,发布到了微信开发者社区。 没过多久,一位用户通过那篇文章联系到了我。他在工业自动化领域遇到了一个难题:需要一套能够定制化采集设备数据的微信小程序工具,而协议正是基于 Modbus/TCP。 由于我的“豆子工具”已经打好了坚实的底层基础,我对原有的 TCP 调试模块进行了针对性的修改,迅速就适配出了满足他实际业务场景的采集方案。 虽然这笔订单带来的“第一桶金”数额并不算惊人,但它对我的意义非凡。它验证了一个逻辑:当你把一个细分领域的工具做到极致,并愿意分享出去时,价值自然会找上门来。 思考:底层逻辑的价值 很多开发者纠结于学习各种眼花缭乱的新框架,但其实最耐打的永远是底层逻辑。 通过开发这个调试工具,我深度钻研了 TCP 的三次握手、UDP 的无连接特性以及 Modbus 这种工业标准协议。正因为有了这些底层的积淀,当机会来临时,我才能在短短几天内就把“调试工具”变成“生产力工具”。 总结 现在,这个局域网调试模块依然是“豆子工具”里的核心功能。每当我在现场用手机直接调通一台设备时,我都会想起那个联系我的用户。 知识不仅能改变认知,真的能产生价值。

2018-01-06 · 1 min · Eagle

实战笔记:为了省下服务器流量费,我给小程序加上了 Webp 转换

在“流量贵如油”的今天,作为一名自己买服务器、撸代码的站长,如何给服务器“减负”是每天都要思考的必修课。 痛点:博客网站的流量杀手 我有一个运行多年的个人博客。在分析服务器日志时发现,最大的流量开销并不是文字,而是文章里那些高清的图片。 虽然 JPG 和 PNG 已经很普及,但随着屏幕分辨率越来越高,原图动辄几 MB,对于按带宽付费或者流量计费的服务器来说,这都是白花花的银子。 方案:Webp 格式的“降维打击” WebP是一种现代图片格式,由Google开发,主要目的是优化网页加载速度。它在2010年发布,并且可以提供比传统JPEG、PNG和GIF格式更高效的压缩和更好的图像质量。 它的特性如下: 高压缩效率:无损压缩情况下,WebP无损压缩后的图片文件大小通常比PNG小20-30%,同时可以完整地恢复原始图像数据。有损压缩情况下,WebP有损压缩后的图片质量与JPEG相似,但文件大小可以缩减25-34%,从而能在不牺牲太多图像质量的情况下减小文件体积。 支持透明度:WebP格式支持8位透明度通道(Alpha Channel),这允许图片在有损压缩的同时也能够处理透明背景,这是JPEG格式不具备的能力。 动画支持:WebP格式可以存储动画,功能类似于GIF,但是以更小的文件体积和更好的压缩效率。 广泛的颜色表示:WebP支持丰富的颜色表示方式,包括4:2:0和4:4:4色度采样。 兼容性和支持:WebP格式得到了许多现代浏览器如Chrome、Firefox、Edge等的支持。对于不支持WebP的浏览器,需要使用其他格式的图片作为替代。 文件扩展名是.webp。在Internet媒体类型(MIME type)中,WebP的类型是image/webp。 现在主流浏览器(Chrome, Safari, Edge 等)已经全面支持 Webp 格式。相比于传统的 JPG 和 PNG,Webp 可以在保证肉眼看不出画质损失的前提下,将文件体积压缩 30% 到 70%。 这是一个非常惊人的数据。这意味着原本 100GB 的图床流量,换成 Webp 后可能只需要 30GB。 为了方便处理博客素材,我决定把这个需求也集成到“豆子工具”里。 比如我的Hugo网站,在写文章用户图片时,我经常会截屏作为我的图片源,或者拍照作为我的图片源。这个在微信上传时自动转为JPG格式。虽然进行了压缩,但是体积还是有几百KB甚至达到1MB多。 我的网站流量非常精贵,所以此时使用webp的优势就体现出来了。我会把图片发送到我的电脑,然后使用电脑上的小程序打开进行格式转换。比如我的一个660KB的JPG图片,转换成webp格式后,只有115KB。 当然,如果你需要在手机上进行格式转换也可以,但是不要使用微信同步到电脑,因为它会进行格式转换,重新转为JPG。 推荐在电脑上使用电脑版的小程序直接进行图片格式转换,非常方便快捷。 实现:基于 Google 官方工具链 图片转换的实现原理与我之前的“音频转换”方案异曲同工,主打一个稳定与高效: 核心引擎:在服务端安装了 Google 官方出品的 webp 命令行工具链(cwebp)。 后端调度:依然由 Go 语言担任“指挥官”,接收小程序上传的 PNG/JPG 原图,调用外部 cwebp 进程进行压缩。 参数优化:在后端我预设了平衡性最好的质量参数,确保图片在压缩后的清晰度依然能够满足博客展示的需求。 闭环应用:现在我写每一篇博客前,都会先用小程序把配图过一遍,转成 Webp 后再上传。 成果:全站 Webp 化 目前,我的博客已经全面实现了图片 Webp 化。这不仅显著提升了网页的加载速度(SEO 评分都变高了),更重要的是,它帮我省下了实打实的流量费用。 ...

2018-01-05 · 1 min · Eagle

实战笔记:我把 FFmpeg 搬进小程序,搞定了音频格式转换

在“豆子工具”众多的功能里,音频转换(m4a 转 mp3) 是我使用频率最高、也最具有“个人救赎”色彩的一个。 起因:被软件更新“背刺”后的郁闷 这个功能的由来非常接地气:有一段时间,我需要频繁地将苹果手机录音产生的 m4a 格式文件转换成 mp3,因为当时某个必须使用的业务软件只认 mp3。 那时候我找遍了各种转换工具。最后发现某款主流音乐软件自带的转换功能挺好用。然而,好景不长,在一次软件自动更新后,这个功能竟然被砍掉了。我去搜老版本安装包,却发现根本找不到安全的下载路径。 那种“被绑架”的无奈感,相信每个工具控都深有体会。 进阶:大名鼎鼎的 ffmpeg 郁闷之后,我转向了技术人的终极方案——ffmpeg。 命令行虽然硬核,但确实强大到无以复加。一条简单的指令就能解决所有问题: ffmpeg -i input.m4a output.mp3 用了很长一段时间的命令行后,新的问题又来了:我总不能随时随地都带着电脑吧?如果我在外面,急需用手机转一个文件发给客户怎么办? 于是,我动了把 ffmpeg 搬进“豆子工具”的心思。 实现:极简架构下的“随时随地” 在小程序里实现这个功能,原理其实并不复杂,核心在于后端调度: 前端上传:小程序端选择 m4a 文件,上传至服务器。 后端处理:后端使用 Go 语言接收文件,通过 exec 模块调用服务器系统环境中的 ffmpeg 进程进行转换。 实时试听:为了保证体验,我在小程序里集成了一个音频播放器。转换前可以听一下是否选对了文件,转换后也可以即时试听确认效果。 即用即删:转换生成的文件在用户下载后会立即从服务器删除,既保护了隐私,也完全不占用宝贵的服务器存储空间。 感受:工具的本质是“自由” 自从这个功能上线后,我就彻底告别了 ffmpeg 命令行。 最爽的一点是随时随地:无论是在地铁上还是在户外,掏出手机,几秒钟就能完成格式转换。这种把强大工具揣在兜里的感觉,就是开发者最大的浪漫。 如果你也经常被各种音频格式限制折磨,或者对 Go 调用 ffmpeg 的具体代码实现感兴趣,欢迎在评论区交流。

2018-01-04 · 1 min · Eagle