dingdang-robot:一個開源的中文智能音箱項目
歡迎大家前往騰訊雲社區,獲取更多騰訊海量技術實踐乾貨哦~
作者:潘偉洲
免責說明:本文介紹的 dingdang-robot 與公司的叮噹助手沒有任何關係。
這個項目其實來源於我生活中的一個需求:我每天晚上都會去廚房做一個麵包當明天的早餐,當我把用料按順序準備好放進麵包機時,我需要準確預約到明天早上我吃早餐的時間。然而,幾乎每次在這個時候我都沒有帶手機在身邊,而是都放在客廳里充電,這時只能跑去客廳看時間。雖然廚房到客廳只有幾步之遙,但自己又是懶癌患者,每天都要這麼來回奔波就覺得很不方便。要解決這個問題當然有很多種方法,比如直接買個小時鐘放在廚房。不過我更希望「連看都不用看」,直接有人告訴我時間。所以,我需要一個像 Amazon Echo 那樣的智能音箱。
然而,不論是 Amazon Echo 、Google Home 還是微軟 Cortana 音箱,在國內的使用都是個問題。雖然國內也有類似的智能音箱產品,但我沒有用過這些產品,不知道可定製性如何。比如,如果我需要開發個功能讓它告訴我某種麵包的配方是什麼,這些產品就不一定能做到了。考慮再三,我決定自己動手寫一個。整個項目用了差不多三個星期的業餘零碎時間。
先放上項目主頁:http://dingdang.hahack.com
Demo:https://github.com/wzpan/dingdang-robot/wiki/demo
下面分享一下我在開發這個項目過程中的心得。
硬體
首先要解決的是硬體問題。我選擇在 Raspberry Pi 上開發。於是我買了塊 Raspberry Pi 三代主板。麥克風和音響方面,出於美觀的目的,買了個自帶音響的 USB 全向會議麥克風。整套設備看起來就像這樣:
過了不久覺得這個麥克風自帶的音響音質太一般了,所以我又外接了一個小音箱。然後再插了一個攝像頭,用來實現拍照功能,又進化成了這樣:
發布了不到一個星期,respeaker 的商務經理看到了我這個項目,希望能提供硬體上的支持,所以我又玩上了各種 respeaker 的硬體(做為回報,我也零報酬給他們帶去了 100 多個 respeaker-2mics-HAT 的銷量):
因為軟體本身是和硬體解耦的,並不依賴具體的硬體要求,所以很多用戶也自己做了硬體上的定製和嘗試(最後一張圖裡預裝了 dingdang-robot 的是熊,不是妹子 :-p
):
硬體有了,接下來就得開始寫軟體了。主要的框架借鑒了 Jasper 項目,並加入了我自己的定製和想法。這裡說說一些有意思的部分。
指令接收
智能音箱要解決的一個最重要的問題就是如何接收指令。這裡頭主要涉及兩個問題:
- 被動喚醒(Passive Listening),即「什麼時候開始聽」。這個階段只監聽喚醒詞。當聽到喚醒詞時,進入主動聆聽。
- 主動聆聽(Active Listening),即「什麼時候結束聽」。這個階段主動聆聽用戶的任何語音指令,然後對聽到的內容進行分析處理。
被動喚醒階段的基本策略是:每次以 16000 的採樣率錄製 1024 個採樣作為一個採樣集,然後對採樣集進行信號強度估計,當某個採樣集信號強度大於一個閾值時,就認為可能接受到了指令。然後持續錄製多 1 秒時間,再轉交給語音識別模塊。當語音識別模塊認為是喚醒詞時,進入主動聆聽階段。
主動聆聽的策略與被動喚醒基本相似,每次以 16000 的採樣率錄製 1024 個採樣作為一個採樣集,然後對採樣集進行信號強度估計,當某個採樣集信號強度低於一個閾值約 1 秒的時間時,就認為用戶已說完了指令。當然還要考慮環境吵雜,一直處於聆聽的可能。因此可以再加一個超時保護,超過 12 秒就結束聆聽。
語音處理
說說STT(語音識別,說成ASR也是一回事啦)引擎和TTS(語音轉文本)引擎的選擇。由於被動喚醒會試圖識別所有聽到的內容,出於隱私保護的目的,應該使用離線的語音識別引擎,因此我選擇的是 PocketSphinx 。而對於主動聆聽,由於是在喚醒階段才會進行轉換,進入主動聆聽前會有蜂鳴提示,用戶也會清楚此時叮噹正在聽他們說話,相對來說隱私泄露的可能性就比較低,因此我最初選擇的是在線的百度 STT 語音識別服務,也省下了擴展語音識別模型的工夫,有利於更好地實現插件可擴展。TTS 引擎方面同樣也先支持了百度的語音合成。
在實際測試中,PocketSphinx 的識別出乎意料的好。由於我的離線指令集只有幾個候選喚醒詞,PocketSphinx 對這些喚醒詞的識別非常靈敏,甚至有時候其他聲音也可能被誤當成喚醒詞而喚醒叮噹。但即使被意外喚醒了,不去理會叮噹就可以了。
相比之下,百度的語音識別就比較遲鈍了。有時候明明我發音很清晰了,還是會識別成另外的含義。通過在百度的語音識別平台上傳自定義的語音識別詞庫 可以提高識別的準確率。另外,由於我用的是 Restful API,網速比較差的時候響應也比較慢。我在家用的是 10M 帶寬的網路,反應速度還算可以接受。
下面這個視頻是我與叮噹對話的演示。我把喚醒詞設置成了「小梅」:
http://www.miaopai.com/show/-yeEBNJlvrQ-UNZzaglxr2s9JQU8TZNy.htm
一個問題是當回答內容比較長(比如問叮噹當天的新聞)時,合成語音的耗時會變得很長,給人的感受是叮噹的響應很慢。所以我加了個 read_long_content
的選項。當內容過長時,改成發送到用戶的郵箱或者微信。
到了九月份的時候,dingdang-robot 在離線喚醒方面又增加了 snowboy 引擎,在主動聆聽和語音合成方面又增加了阿里、科大訊飛的服務,無論是識別速度和合成音色的豐富程度又有了很大的進步。
技能插件
叮噹最好玩的部分當然就是玩插件了,通過寫插件可以讓叮噹接入各種各樣的服務,完成各種各樣的事情。我在叮噹里也內置了幾個插件。為了方便用戶擴展,我定義了三個技能插件目錄:
$HOME/dingdang/client/plugins
:官方插件,與 wzpan/dingdang-robot 同一倉庫;$HOME/.dingdang/contrib
:用戶貢獻的第三方插件,單獨維護一個 dingdang-robot/dingdang-contrib 倉庫;$HOME/.dingdang/custom
:用戶自定義插件,用於存放用戶自己開發的,暫時不計劃對外發布的插件。
如下是截至本文發布前 dingdang-robot 提供的插件,可以看出,其他用戶貢獻的插件已經達到了叮噹自帶的插件的兩倍:
插件名用途是否用戶貢獻Echo簡單的回聲/傳話功能。否Email檢查郵件功能。否Time時間插件。詢問叮噹時間。否Camera用於調起攝像頭拍照(如果安裝了攝像頭的話)。部分SendQR要求叮噹發送微信登錄二維碼到用戶郵箱(方便遠程微信登錄)。否Chatting用於進入/退出閑聊模式的插件。否Unclear用於機器人聊天兜底。否Hass用於控制接入HomeAssistant的設備是NetEaseMusic網易雲音樂播放插件否Weather天氣查詢插件否SpeakIP播報主機IP地址插件是Reboot重新啟動操作系統(root用戶)是WebServer啟動HTTP伺服器插件是SendMessage向微信好友發消息插件是ControMqtt通過Mqtt協議與其他開發板通訊是WOL通過WOL(Wake On Lan)實現語音開機是EmailMyPC以郵件方式實現語音操控電腦是ToDo簡單的備忘插件是RaspberryPiStatus簡單的樹莓派狀態查詢插件是HeadlineNews新聞頭條播報插件是Direction出行路線規劃插件是BaiduFM百度FM音樂播放插件是
音樂播放
既然是智能音箱,當然少不了播放音樂的功能。所以我額外寫了個播放網易雲音樂的插件 NetEaseMusic 。出於版權考慮,並不集成進官方插件中,而是放進 dingdang-contrib 裡頭。
這個插件的實現比較複雜。普通的插件接受到指令,響應完就退出了。而為了能支持各種指令控制音樂播放,這個插件在接收到播放控制指令後並不退出插件,而是進入一個播放器模式,這個模式主動聆聽得到的指令只會在播放控制指令集中匹配,其他的插件指令都不起作用。只有當用戶要求退出播放時才回到普通模式。NetEaseMusic 的播放控制指令如下:
指令相同指令用途播放音樂-進入音樂播放模式。在音樂播放模式下,其他的插件功能將不可用。下一首切歌, 下一首歌, 下首歌切換到下一首歌。如果沒有下一首歌,就回到列表中第一首歌上一首上一首歌,上首歌切換到上一首歌。如果沒有上一首歌,就跳到列表中最後一首歌大聲點大點聲,大聲調高播放音量小聲點小點聲,小聲降低播放音量隨機播放-隨機播放列表中的音樂順序播放-順序播放列表中的音樂暫停播放-暫停音樂的播放播放繼續繼續音樂的播放榜單-播放推薦榜單歌單-播放用戶的歌單(如果有多張,將只播放第一張)結束播放退出播放,停止播放退出音樂播放模式。搜索查找搜索歌曲/歌手。將自動播放搜索結果。什麼歌-正在播放的是什麼歌
實現這個插件的過程中還參考了 Vellow 的 MusicBox 項目以及 yaphone 的 RasWxNeteaseMusic 。為了方便重用,我把 MusicBox 的核心 API 抽離了出來封成了一個 MusicBoxApi 庫 。比較坑爹的是就在我準備發布叮噹的前幾天,老的獲取音樂地址的方式徹底不能用了,而新的介面批量獲取的地址不知道為什麼是亂序的,於是我只能在播放每首歌前都調用一下新版的獲取地址的 POST 介面,又增加了一點響應時間。
下面這段音頻是使用叮噹控制音樂播放的演示:
http://onmw7y6f4.bkt.clouddn.com/%E6%92%AD%E6%94%BE%E9%9F%B3%E4%B9%90.mp3
完成了音樂播放功能後,叮噹的好玩程度提高了很多。以前要聽歌,至少得把電腦或者手機打開。現在只需要喊一聲叫叮噹播放歌曲就可以了。想換歌、搜索歌曲、調節音量都是說句話就搞定的事情,生活幸福指數大幅提升 ^_^
。
開源心得
dingdang-robot 的正式開源時間是今年的 5 月 20 日(是的,我專門挑了個好日子),截至本文發表時,該項目的相關數據如下:
- Github Stars:418,平均一個月 100 star
- QQ群用戶:340
- pull requests:48
- 項目主頁 PV:12,000+
- 捐贈記錄:https://github.com/wzpan/dingdang-robot/wiki/donate-list
雖然數據並不是特別亮眼,不過對於這樣的小眾項目,我已經比較滿意了。下面談談個人怎麼維護一個開源項目吧。
前期:做好框架
根據二八法則,項目的前期應該要把整個項目期望能達到的 80% 的基本要求完成。一個人的力量畢竟有限,要完成剩餘的 20% 的功能可能要耗費非常多的精力,還不如先推出來,形成社區後再去嘗試完成。
以 dingdang-robot 為例,其實智能音箱最重要的幾個用途:音樂播放、鬧鐘提醒和智能家電控制只有音樂播放是我在首次發布的時候提供的(因為不能播放在線音樂的智能音箱實在不好意思叫智能音箱)。剩下的幾個功能都是我提了 feature issues 大致提供了實現思路,然後由其他的開發者去完成的。
所以,對於一個比較大的項目,更重要的是在這個階段界定好 80% 的目標,設計好項目的框架,確定 License,寫好 README 和 CONTRIBUTION(代碼審核、持續集成測試等)。
中期:推廣 + 社區搭建
項目發布之後,推廣和社區搭建是非常重要的,畢竟直接關係到項目的用戶數量和這個項目的生命力。
推廣方面,這個階段我發布了三篇文章:
- 叮噹:一個開源的中文智能音箱項目:介紹這個項目。
- 手把手教你編寫叮噹機器人插件:介紹如何開發和貢獻技能插件。
- 使用叮噹聲控智米電風扇:介紹如何使用叮噹控制家電。
這三篇文章推到了開發者頭條和樹莓派實驗室上,都取得了不錯的點擊率。
另外,如果你跟微博上一些大 V 關係不錯,也可以嘗試 @ 他們幫忙推廣,當然前提是項目要足夠拿得出手才行。
在這個階段,項目的主頁和文檔也必須儘快搞好,良好的主頁和文檔是吸引用戶付出精力去嘗試你的項目的必要前提。如果像我一樣想省點事,可以直接用 Github Pages 生成簡單的項目主頁,然後直接用 Github Wiki 維護文檔。
社區的搭建也是非常關鍵的一環。可以考慮的渠道比如:
- 即時通訊工具:如果項目主要針對國內用戶,可以使用QQ群;如果針對國際用戶,可以使用 slack 。
- 論壇。即時通訊工具的最大問題就是存在時效性。類似的問題在群里剛回答完,新加入的用戶又問了一遍,非常崩潰。所以搭建一個論壇,引導用戶多去使用論壇交流就可以解決這樣的問題。
以 dingdang-robot 為例,QQ群是很多人決定參與項目之前先加入的社區。剛開始群里才幾個人的時候也是非常冷清尷尬,但後面隨著人越來越多,群里變得非常熱鬧(甚至我不得不選擇上班時間屏蔽該群)。而論壇最初是其中一個用戶用 discuz! 搭建的,但郵箱認證沒搞定,久而久之論壇里一堆的 spam 。趁著國慶我又用 discourse 重新搭了一個,加了嚴格的審核策略,正好用騰訊雲的體驗代金券。
市集模式合作階段:促進合作,保持生命力
一旦用戶數量足夠多,參與貢獻的人就會多了起來。這時候怎麼調動大家參與貢獻的熱情就顯得格為重要了。
為了達到這個目的,項目作者本身首先當然要以身作則,體現出充足碼力。該你承擔的部分積極實現,該 code review 的時候趕緊 review,該發布新版本的時候保證發布。然後在社區裡頭多多拋出可能的 idea 和實現方案,這時候往往就會有人願意參與貢獻。
我比較喜歡的形式是在項目的 Github issue 頁里提出需求,然後過不久就可以看到有人參與貢獻了(比如 #28, #29 和 #39)。對於參與貢獻的用戶,要不吝致謝,讓他們的名字出現在 changelog 中。
除了這種市集模式的合作方式之外,未來我可能會考慮其他新穎的促進合作的方式,比如在線直播寫插件、發布新版本,線下 Hackathon 等。
總結和後續
對於有 Coding 能力的 Hacker 而言,自己動手做一個智能音箱,不僅可以當做業餘練手項目,還可以自由地定製硬體模塊,並實現自己需要的各種功能,這遠比直接購買一個 Amazon Echo 有趣得多。
更重要的,我更希望能有其他有興趣的朋友參與進來,一同開發完善這個智能音箱項目。我相信,這種個性化服務的產品本身就應該是完全可定製的。而您的加入可以使 dingdang-robot 變得更智能!
相關閱讀
CNN 在語音識別中的應用
加權有限狀態機在語音識別中的應用
揭秘騰訊雲Supermind智能網路,百萬級設備的網路高效運維
此文已由作者授權騰訊雲技術社區發布,轉載請註明原文出處
推薦閱讀: