全球有數(shù)不清的卡拉OK應用,但每到朋友聚會的夜晚,大家還是會不自覺地打開視頻網(wǎng)站來放伴奏。同一臺設備上,一個人搜索,一個人誤觸播放,再一個人不停地問“下一首是什么”——排隊全靠嗓子喊,控制權像擊鼓傳花。VKara 做的事很簡單:把電視或筆記本變成純粹的播放大屏,每個人的手機則靠一個4位房間碼或二維碼,同時登錄同一個房間,搜索、點歌、暫停、切歌全在各自掌心完成。它沒打算替代視頻平臺,只是補上了多人協(xié)同點歌這個缺口。
這個產(chǎn)品的初版誕生在2025年初。作者坦率地說,自己的需求非常個人:就是想跟朋友在家唱得痛快一點。最開始的方案只是個功能跑通了的原型,驗證了可行性,但完全不敢拿去真實的卡拉OK之夜用。用他自己的話說,叫“危險的能用”。界面在跳動,視頻有時會跳過搜索步驟直接播放,歌曲隊列說亂就亂。而最致命的地方在于,VKara本質上是一個實時同步的應用,前端與后端必須在房間狀態(tài)、隊列數(shù)據(jù)、視頻元信息、播放指令和 WebSocket 消息上保持一套一致的契約。當這些契約分散在不同倉庫里各自演進時,每做一次修改都像在踩地雷。于是項目被擱置了——不是點子不行,是改動成本高到讓人不敢下手。
![]()
今年重新?lián)炱痦椖繒r,他沒有急著加功能,而是先問自己一個問題:怎么才能讓這個項目“可以安全地改動”?答案的第一步,就是把舊的前端倉庫和舊的后端倉庫合并成一個 Bun 工作區(qū)單體倉庫(monorepo)。apps/web 是 Next.js 的前端,apps/api 是基于 Elysia 和 WebSocket 的后端,packages/shared?types 存放共享的 API 與 WebSocket 合約,packages/shared?utils 放公共輔助函數(shù)。這不是一次簡單的文件整理,它直接改變了后續(xù)所有工作的節(jié)奏。
在那個散亂的舊結構里,前端和后端對“一個房間該是什么樣子”的認知很容易出現(xiàn)偏差。現(xiàn)在,只要在 shared?types 里定好一個接口,修改會同時傳導到前后端,類型檢查器會立刻叫停任何不一致。共享工具函數(shù)也把解析房間碼、格式化時間這類反復用到的邏輯收攏在一起,不再需要手動比對兩端是否寫了同一段正則。對實時應用來說,這種契約的集中存放就像把散落各處的樂譜合成了一本總譜——每個部件該在什么時候發(fā)出什么信號,一目了然。正因為改動變得安全了,那些擱置已久的真正產(chǎn)品問題才開始被逐個解決。
原先的版本讓人感覺是在一個視頻播放器外頭硬套了一層點歌流程:界面重心還在視頻本身,移動端的操作路徑又長又容易誤觸。重寫后的移動端流程把“加入房間”“搜索歌曲”“選擇執(zhí)行動作”和“控制播放”變成了四個清晰的步驟,并且頁面只圍繞這幾個核心行為來設計。手機不再是一個投影遙控的小屏,它就是每個參與者的專屬點歌臺。這個產(chǎn)品上的轉向,歸根結底是工程架構轉向后才得以執(zhí)行的——如果每一次調(diào)整播放指令的 WebSocket 消息結構都還要在兩個倉庫間小心翼翼地手動同步,這樣的體驗優(yōu)化可能永遠無法落地。
現(xiàn)在 VKara 的演示環(huán)境跑在非常有限的資源上,作者特意提醒如果加載慢請稍微等一下,因為錢包還停留在學生預算級別。但它的運轉邏輯已經(jīng)非常直白:一臺播放設備負責渲染視頻畫面,其他人的手機通過瀏覽器加入房間,每個人都能獨立搜索、隊列管理、控制播放,而所有狀態(tài)都實時同步在所有人的屏幕上。那個曾經(jīng)讓人在聚會里不得不交出遙控器的場景,現(xiàn)在被拆解成了一個不需要安裝任何應用的純網(wǎng)頁協(xié)作流程。從一套危險的、不敢上場的原型,到一個能安全迭代、能明確產(chǎn)品邊界的工具,變化背后并不是某個單一功能的增添,而是整個工程世界的重構,讓原先卡在理想與現(xiàn)實之間的點子,終于可以穩(wěn)穩(wěn)地走到下一個朋友聚會的客廳里。
特別聲明:以上內(nèi)容(如有圖片或視頻亦包括在內(nèi))為自媒體平臺“網(wǎng)易號”用戶上傳并發(fā)布,本平臺僅提供信息存儲服務。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.