这是一个我和 NovaDNG 老师探讨了很久的话题。打过好久嘴炮,有过很多幻想。而就在几个月前,我决定将脑子里那些天马行空的想法化作现实。Rune,一款利用现代技术栈重新实现 Zune 神韵的开发项目就此展开。
事实上我已不止一次尝试开发一款播放器,但限于敝人孱弱的技术水平和极其矫情的技术品味,尝试了仓库开了两三个,最后全都变成了弃案。然而随着 GPT、Claude 这类开发能力很强的模型不断涌现,造一个火箭不再是一个遥不可及的事情。如果你之前读过 Alice Run! 的开发报告,那应当能领教这类大语言模型解决开发问题的能力有多惊人。
借着这股「东风」,我开始了几个月近乎疯狂的开发之旅。
开始这篇文章之前,我想先向你分享 Rune 播放器现在的样子:
Why we do that
赶着科技发展如火箭般跃迁的时代,相信你我都曾对很多产品有过感动。有人第一次上手 iPhone 时,反复开关「飞行模式」,只为了欣赏从屏幕右侧飞进来的那个小飞机;有人对着 iOS 系统更新时齿轮转动的动画看得入神发呆;有人把窗口拖来拖去,看着 Vista 新出现的毛玻璃无比兴奋;也有人看到「量子纸」的概念视频,感叹新的设计时代已经来临。
我曾是首批在 Web 上实现 Material Ripple 的开发者,也是首个在 Web 平台上实现高兼容性、高性能 Fluent Reveal Highlight 的开发者。
在那个黄金年代,总有一群较真的人聚在一起探讨着一些在今天看来非常荒谬的问题。你或许还能记得我们曾经对 iPhone 的注塑天线口诛笔伐,对 Android 将三大金刚键收入屏幕感到诧异,对着一加手机那不到两毫米的摄像头突起惋惜「它看起来有点太凸了」。
这一盛况是从什么时候开始衰败的呢?每个人对这个时间点的定义可能都不同,但在我看来可能是 iOS7 的发布。
iOS7 will probably be really awesome when they do the visual design.
「在设计上胡搞也无所谓,只要你足够大牌,它就会变得合理」,人们似乎从教宗那得到了某种启示,自此对设计的较真劲就越来越少了。
时至今日大多数「科技大厂」只有「美工」而没有「设计」,做得出「炫炮」的视觉并不意味着设计水平有多高,能否以充满秩序的方式承载内容才是一个平台的首要设计价值。可惜没人在乎,不然新版 iOS 那丑陋的图标调色功能也不至于通过了公司内部的设计评审,堂而皇之地出现在用户的面前。
苹果在「设计自由奔放」上向微软看齐,谷歌在「设计文档稀烂」上向微软看齐,微软在「寡淡保守无趣」上向苹果看齐。人们都说「好的设计是趋同的」,而把话反过来说「稀烂的设计也在趋同」。
用着手上那按什么地方都卡一下的 Windows,我不禁发问,微软那些手持优雅 mac、日日赞美苹果的设计师们,究竟是否用过自己设计出来的这坨秽物。而当年粉碎了 Material Design 的始作俑者 Luke Wroblewski 又是否静下心来好好用过 Android。
越是因万物蓬勃发展而感到兴奋的人,在看到软件工程和硬件设计质量集体堕落时,越是感到懊恼。
面对着这场狂欢,我曾彷徨无措甚是挫败,最后一气之下把手机换成了海信 A9 和 Jelly 2 这两款鼓励你「远离手机」的设备。不再爱便不会再受到伤害,自此我找回了内心当中的安宁。
「批评会招致仇恨,抱怨不能解决问题」我还在高三时班主任曾如此劝诫过我,而直到三十岁我才领悟了其中的意涵。
抽象的评价没有意义,我需要做些具体的事情。无论结果是好的还是坏的,我至少要实际地证明自己的想法。而这,就是当下我们交出来的答卷。
How we do that
如果要评选出独立开发者五大白月光项目,GTD 系列(TODO、记账、时间管理、日记、日历)、编辑器系列(笔记软件、写作软件、Markdown 编辑器)、CMS 及 OA 系列(博客、各类管理面板)、音乐播放器一定能挤进前四。
你打开 GitHub 简单搜搜,就会发现大量写了一半没人管的仓库。各大软件博客介绍的新软件里,这类软件也必然是每期必现地常客。似乎「如何更高效地提高自己的效率」变成了更加热门的话题。「告别效率,回归工具」成为了某种潮流。
这类项目的不停涌现是因为两个重要的特征:技术门槛低、需求涵射范围广。前者意味着任何一个人,只要有想法就可以立刻下手做出一个「像模像样」的东西。后者决定了开发者必须花费更多精力来给项目划定明确的边界,即定义清楚它的内涵概念和外延概念究竟是什么,哪些东西要做,哪些东西不要做。否则,这个工程就会变成一个永远做不完的无底黑洞,此等项目必然不得善终。
想清楚这两件事看似困难,其核心只有一个问题:我要做的这个企划究竟在解决什么问题?这又被称作是 Goal of success。
Goal of success 是一个很重要的概念。若是完满地解决了当初提出的问题,我们就可以说这款产品达到了「功能完备」之状态。此时开发者既可以选择设立新的目标,也可以选择暂时停下,将其视作是一款完备的产品,转而追求其他的目标。
我们很少看到有开发者宣称自己的作品达到了「Goal of success」,这确是一件憾事。我曾在《当代学生生存手册》一书中详细讨论过此话题,若各位读者感兴趣,我可择日以免费试读的形式将其开放给你,故在此不再赘述。
我们这次建立新仓库的初衷是,通过现代技术重现 Zune 之神韵,撷取历代微软产品设计的亮眼之处,以合理的方式编织到一个产品当中。这是一个设计实验,我们希望重新梳理微软设计的时序,假定历代设计都以一种不那么跳跃的方式演化,最后它们会以何种方式收束到 Fluent Design 2 之上。
让我进一步澄清一下:这是一次关于产品和用户体验设计的实验。
如上论述已是一个高度可操作的课题,接下来我们将其解构为数个子目标,这既是作为团队奠基者我个人意志的投射,也可以被视作是整个项目的价值体系:
- 回答「2024 年的 Zune 播放器,应该长成什么样子」这一问题;
- 探究现代化的聆听体验的一种可能性;
- 如果精力允许,进一步回答:倘若微软的 Multi-platform Vision 依旧在延续,这个设计在电脑、手机、乃至智能手表和手环上,可能是什么样子。
基于此,我们给项目起名为 Rune,寄托了 Zune Revived 这一隐喻和期望。
What we did
目前,这个企划已经执行到了中期阶段。我们对前两个问题做出了某种程度的解答、而对第三个问题的解答也已初具雏形。
保守的视觉
在做界面设计时,我几乎每天都拽着 NovaDNG 讨论界面设计。我们有一个共识,微软最有辨识度的设计便是 Zune 的视觉要素和 Windows 8 的 Metro Design(磁贴设计)。
我非常能够理解很多人讨厌磁贴,因为它看起来并不精致,且与你曾经所看过的设计差异悬殊。但我对这种设计风格抱有极大的好感,因为它是一次大胆的尝试。Metro Design 以一种合理的方式延续了 Zune 的视觉要素,但没有丧失基本的秩序感,甚至具备极佳的辨识度,这对一个产品和品牌来讲是至关重要的。
基于这样的共识,我们搭建起了一些基本的框架和逻辑:
而在一些细部元素的处理上,我们参考了 Windows 10 Mobile 的视觉风格,多了一点不是很夸张的圆角,以和 Fluent Design 2 的设计标准相匹配。
谈起微软设计历史上最浓墨重彩的一笔,不得不提 Reveal Highlight 光效。为了向其致敬,我们刻意花了一点时间给封面墙界面加入了跟随鼠标运动的光照动画。虽然其中的大部分实现都参考自网上已有的公开代码,但细部的色彩调整还是花了不少时间。就结果而言,这流光溢彩光景让我多熬的那几个大夜显得非常值当。甚至有几日睡前,我打开了自己最喜欢的几首曲子,对着屏幕上如火焰版摆动的频谱,笨拙地站在出租屋内起舞。
我已经有好些日子不曾打内心当中感到快乐了。而那几分钟当中的感受,那种自心底萌生出来的喜悦,甚至让我幻想自己临终前是否也要以此为伴的念头。这想法的确荒谬,但确是我当时的想法。
我们对最终呈现出来的视觉风格是满意的,拿给一些微软开发者社区的朋友看,大家也对此抱有积极的态度。
在开发过程中,一切工作都进展地相当平顺,我们并没有遇到什么特别难缠的工程问题。如果非要说,导航栏上下级切换时的 FLIP 动效和换页动效(根据路由关系决定页面淡出方向)倒是吞掉了数个夜晚。但跟之前与一些以「标新立异寻求优越感」的末流设计师合作经验来看,这完全在可接受的范围之内。毕竟最佳工程实践和概念都已完备,我不必像落入浴缸的猫咪一样疯狂地四处扑腾,一切都有迹可循。
愚钝的功能
在 2024 年,人们似乎更加在乎 AI,无所不用其极地将 AI 塞进每一个产品。若 AI 意味着聪明,不加入 AI 的产品无疑是「愚钝」的。但在我看来这并不是坏事,毕竟 AI 只是一个噱头,而它背后要解决的问题才是核心。
AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI AI
你猜我说了几次 AI?
智能、AI 的产品往往意味着和私有化的云服务(Some computers in other people’s home)强绑定,其对应的商业模型对追求盈利的公司们有利,但不一定对你有利。
我讨厌这个势头,并希望摆出自己的姿态作出对抗。
对于目前版本,甚至没有任何一个功能需要联网,整个程序甚至连遥测都没有加。是的,我对你的个人数据不感兴趣,那是属于你的东西,我没有想要掠夺它。
以此为产品价值取向,我们开始了对功能的规划。
让我们来审视一下当代人音乐消费的习惯发生了什么样的变化。在音乐还有物理载体的年代(像是磁带和 CD),人们以「专辑」为单位欣赏音乐。而「MP3」的出现极大地改变了这种模式,以「播放列表」和「单曲」为单位的消费行为成为了主流。
我知道现在依然有很多人坚持尊重音乐家的创作意图,坚持从头到尾听完一个专辑,并对这种零碎的聆听方式嗤之以鼻。我尊重你高雅的品味,但我也想将更加广泛存在的需求处理好。
推荐算法
提到推荐算法,很多读者能想到的第一件事,可能就是根据大量用户的聆听习惯做聚类,这种根据真实消费行为做出来的推荐一定是最符合心理预期的。但一款离线音乐播放产品,并没有这样的「王之宝库」,我们要怎么做?
古老的技术总有它独特的魅力。我们参考了 Sony 的 SenseMe,以及其背后的 12 Tone Analysis 算法。尽管算法本身并没有开源,但是它的名字昭示了一切,背后的实现一望即知——Chroma Spectrum。
通过分析一首曲子在十二个半音上的能量强度,我们便可以大致了解整首作品的形态特征。加上一些时域、频域和主观听感上的特征,构成了一个包含 61 个维度的数据空间。在这个话语体系下,「推荐一首相似的音乐」变成了「寻找在这个空间内最近的点」。听起来挺酷炫的,但实际上就是调库。
音频特征抽取方面,我们用 Rust 重新实现了一遍 Meyda,推荐算法方面,我们则是使用了 Arroy。不要自己造轮子,有现成的东西就拿来用是高速推进项目的重要原则,我受用至今。
基于这个数据库,我们开发了一个类似「心情电台」的功能,沿着高维空间的对角线,取九个百分位数,以这九个点为核心画一个圈,就组成了风格的九个播放列表。
我得承认,敝人的心理学专业背景并不足以支持更加复杂的算法研发,沿着对角线取点只是一种我能想到的权宜之计,基于此推荐出来的曲目风格可能不够多元。或许会有更好的寻找种子点的方法,但是它完全在我的能力范围之外。若正在阅读此文的你有这方面的知识,还请赐教。
掌控感
我理解,对于很多用户来讲,将一切交给算法,会带来很大的不安全感。但一首一首将音乐加入播放列表又相当麻烦。因此我一直在构想一种更加便利、友好且受控的播放列表构建范式。
我能找到的参考范本只有 iTunes 的 Smart Playlist。现在市面上能找到的「动态播放列表构建器」也都参考自这个设计。但这无疑一种相当糟糕的答案,它就像是一个 SQL 编辑器的 GUI,如果你对「数据结构」不够了解,不能精准地拼出专辑和作曲家的名字,那这个功能根本不是为你准备的。
但我们不能期待用户是一名数据专家和专业乐评人,这样的设计无疑是一种转嫁设计责任的行为,将不必要的复杂度一股脑地塞给了懵懂的用户。就像 iOS 全新推出的图标调色和暗色图标功能一样。
对于这个问题,Rune 给出了不同的答案:Mix。我们将整理播放列表的过程分成了两个步骤,「将想要的条件纳入」和「把不想要的东西滤掉」,就像用榨汁机制作混合果汁一样。你可以一次将所有符合条件的歌曲放进来。不必清晰地记住所有信息细节,每个输入框都配有搜索功能,输入一个大概的信息就会列出所有备选,而右面会实时地告诉你这个播放列表都包含什么样的曲目。
你也可以做到这些看起来很魔法的事情:「进入这个播放列表就自动进入随机播放」、「我喜欢这些专辑和作曲者,请向我推荐和它们相似的曲子」、「按照我听完整首歌的次数排序,我要反复听这些我喜欢的曲子」。
他不像 SQL 编辑器一样全能,我们有意识地裁掉了「逻辑关系编辑」这类令人困惑的概念,希望最后呈现出来的产品样态更加贴近你的直觉和日常使用习惯。
这个功能背后由一组查询语法驱动,表现简洁有力。唯一的遗憾是其背后的工程实现,无论是复杂度还是性能都很不理想。希望我的后端工程能力能够早日提升到能够优雅处理这一问题的水平,但目前为止,这已是我尽力而为的结果。
偏执的管理
接下来,我想和你聊聊开源。
Rune 是一款开源软件,基于相对宽松的 MPL 协议。
MPL允许在其授权下的源代码与其他授权的文件进行混合,包括私有许可证。但在MPL授权下的代码文件必须保持MPL授权,并且保持开源。这样的条款让MPL既不像MIT和BSD那样允许派生作品完全转化为私有,也不像GPL那样要求所有的派生作品,包括新的组件在内,全部必须保持GPL。
Wikipedia
对于个人开发者来讲,将软件开源是一个非常危险的行为,因为你会面临被人 Fork、换牌、贴广告、付费上架的危险。业界甚至还出过这样的人间惨剧:Fork 的人忘记换关于页面的联系信息,导致一大堆抨击广告的负面评论大批大批地灌进了原始仓库。
我充分地理解这件事情,就像我当初出版《当代学生生存手册》时,充分理解被盗版的风险,依然选择上架 Booth 一样。
生物是由目的驱动的有机物集合,人类也不例外。我们做一件事情其背后必然对应着某种动机。我的动机是讨好自己,而非商业利益。若是能有更多金钱灌注进来协助我改善生活,那便是好上加好,但没有好像也没差。我不会因此而感到愤世嫉俗或顾影自怜,我坦然地接受这些行为带来的一切结果。
在这样的动机之下,开源是对我个人和 Rune 最好的决策,我并不会因为这个行为失去什么,但各位读者将有机会更加深入地了解这款风格独特的软件,并有机会将我们共同在乎的价值投射在这款独特的作品上。
在完成基础架构设计后,我便开始为每个开发周期编制版本号,每个周期实现一些小功能,修复一些小臭虫。这种独自掌控整个项目的走向非常美妙,每天晚上填写开发日志的过程带来了源源不断的多巴胺喷发。我似乎构造了一个属于自己的迷你世界,而我就是这个世界的创世神明。
掌控感是很重要的。敝人拙见,一切主观动机背后的根源掌控感。无论是开源项目还是闭源项目,公益项目还是商业项目,其背后的核心目的都是对周遭和内部环境的塑造,其最终产物都是对特定事物的话语权。这种话语权可能是对外部事物的改变,也有可能是稳定内心世界的力量。
而终归,那些做到一半便被抛弃的作品们,其走向末路的原因都是对主导者来讲,决定核心价值的因素已经无法被自己所控制。这既有可能是因为未能满足模糊的预期而感到失望,也有可能是对自身边界的错误评估,被过大的责任和工作量压垮。
在清楚地意识到自身管理能力和项目性质的基础上,我选择了一种温和独裁且偏执的开源社区治理策略:
- 英文是唯一被支持的工作语言: 能够以某种形式(包括大语言模型)使用英语,是一名合格开发者的基本资质。开源世界几乎所有主流产品,其源代码和文档的默认语言都是英语。而无法善用这些资源,或使用这种「事实标准」进行沟通的成员应当被排除在社区之外。
- 不接受草率的功能请求: 对于绝大多数的开源项目而言,发起者都是那个可怜的 CPU 0,这是一件极度消耗热情的事。特别是遇到不成熟的「参与者」以一种不负责任的方式提出不切实际的需求时,以「高度社会化」的方式回应会消耗大量时间。因此我没有打算当那个 CPU 0,只打算做自己关心的功能。当然如果开发者想要自己添加一些新功能,或者通过「完成某些工作量」来和我做一个「和需求有关的交易」,我都乐意接受。
这种治理策略看起来非常自私,但若不能照顾好自己,又何谈维护一个作品和爱用者对它的期待。「我依然爱着这个项目」比一切都重要,因为它是延续项目生命的基础。而一种「在给全世界打工却没有任何回报」的感觉是消耗情感资源的重要杀手。
主事者退场,鸟兽散去,一地鸡毛的场景我们已经见证过无数次。我最不希望在 Rune 身上看到的就是这样的结局,这个项目的句号必须由我自己,在心智状态良好的情况下,完满地画下。
结语
至此,Rune 项目已经完成了一半,作为项目的「期中答辩」我已经坦诚地吐露了内心当中的所有想法。作品的优劣每人都有心证,这份答卷接受诸位公评。
若你阅读至此,可能会发现我是一个非常「挑剔」甚至有些「矫情」的人。或许你已经猜到了,「厌世」二字是对我最妥当的形容——我公平地讨厌这个世界上的一切人事物。
我曾非常讨厌这样的自己。但现在,我选择接受它,并尽可能让内心当中的种种不满变成有意义的结果。
《当代学生生存手册》、《Alice! Run!》和《Rune》都是在这种原则下产出的作品。它们可能不够惊人,但我喜欢它们,甚至希望把这些作品刻入玻璃拿来垫骨灰盒。或许在剩下的岁月中,我依旧会不停地产出类似的作品,并期待这些作品能够帮助我坦然面对最终无可避免的消亡。
温润似雾,自由如风。我给这个项目起了一个中文名:符石聆音,这是我对它的全部想象和期望。愿你带我回到那个微风拂面的午后,让我再看看曾经爱过的人们。
谨以此作品纪念 RealOne、Winamp、豪杰 V8、Zune、AirPlay 还有那段再也回不去的美好时光。
Comments
No comments here,
Why not write something?