一、場景
筆者參與開發的是一款音樂類的快應用產品,自然就需要用到audio的元件和相關api,之前在H5中已經做過音訊播放的相關功能,這次開發快應用以為可以複用大部分程式碼,結果發現還是有些不同。除此之外,因為是體驗更好的快應用,所以有一些H5做不到或者效果不好的功能希望能在快應用上實現,例如跨頁播放狀態同步、全域性無重新整理小播放器等等。
二、Audio的問題及解決方案
(1)、切歌
在H5中,可以直接使用audio.play()
來切歌,但是在快應用中切歌需要先audio.pause()
,並且不能audio.pause()
後直接播放新歌曲,需要在onpause的監聽中,確保已被暫停後,再開始播放新的歌曲(賦值新的歌曲src)。
(2)、播放狀態和圖示顯示的同步
首先需要全域性儲存 當前播放的歌曲id、播放狀態等資訊,各個頁面或元件可以對比狀態顯示不同的圖示。
當audio元件被賦值一個新的音訊src,流程大概是:
onplay > onloadeddata
:
所以頁面圖示顯示就是:
圖示:預設 > onplay > 圖示:載入中 > onloadeddata > 圖示:播放中
:
但是,筆者發現對於同一首歌,聽了別的歌,又切回來時,實際上音訊檔案已被快取,因此不會再次進入onloaddata
。
所以我做了單獨的處理,快取進入過onloaddata
的歌曲id列表,對於進入onplay
的歌曲id進行篩選,如果已快取過,則直接將圖示設定為 播放中。
(3)、跨頁面音訊播放狀態同步
假設A頁面是榜單,B頁面是分類歌曲,某首歌在兩個頁面都有,並且這兩個頁面可以跳轉。如果對於常規的多頁快應用形式,可以在前頁和後頁的生命週期中獲取當前播放的歌曲資訊,然後重新整理頁面那首歌的狀態顯示。但是筆者上一篇文章《一個一線前端攻城獅的快應用開發之路:2、我與WebView的鬥智鬥勇》juejin.im/post/5c3af8…說到目前快應用已整體修改為單頁形式,部分生命週期已失效,如onShow,那麼音訊播放狀態同步就需要修改一下寫法:
1、各頁面/各元件點選了播放歌曲
↓
2、呼叫全域性封裝的audio函式,audio函式控制audio元件播放
↓
3、this.$dispatch通知Container.ux更新全域性的歌曲播放資訊
↓
4、Container.ux更新全域性的歌曲播放資訊後向子元件傳送通知this.$broadcast
↓
5、子元件收到通知後,獲取最新的播放資訊並更新頁面顯示
除了使用$dispatch
和$broadcast
之外,也可以使用new Broadcast()的寫法,直接通知所有元件(頁面),各個元件再根據引數重新整理當前元件的顯示狀態。
(4)、全域性的底部小播放器
基於之前文章分享的快應用單頁模式,實現全域性的底部小播放器就變得十分容易,因為所有頁面都裝在Container.ux這個容器內,小播放器也可以封裝為一個元件,放在Container.ux中,使用(3)中提到通訊方式,實現跨頁面無重新整理的小播放器,並且在小播放器上進行的操作,也會自動同步到 各個頁面上。
三、總結
總的來說,筆者還是更多地想分享一些開發的思路,而不是直接發一大段程式碼,很多時候方案很重要,不要立馬動手做,想清楚後再開始實施,就不至於蓋樓蓋了一半發現圖紙不對,要重新返工。
另外,關於audio,可能上述折騰這些東西在後續版本中會有更好的方案、又或者存在很多我還沒發現的問題,都希望大家不吝指正~