記一次實現音訊(Audio)自動播放,視訊同理
技術標籤:JavaScriptjavascripthtml5
近期接到一個新需求,要在PC端和小程式端實現新訂單語音提醒,其實許多需求前端的實現難度並不高,難的是各瀏覽器的限制、相容不一等,此次也不例外。
常規做法
我們都知道HTML5
中audio
及video
有這樣的基礎屬性autoplay
,例如:
<!-- audio -->
<audio controls autoplay>
<source src="audio.mp3" type="audio/mp3">
</audio>
<!-- video -->
<video controls autoplay>
<source src="video.mp4" type="video/mp4">
</video>
又或者使用JavaScript
更精確地控制音訊、視訊的播放。
// audio
const audio = new Audio('audio.mp3');
audio.play();
// video
const video = document.createElement('video')
video.src = 'video.mp4';
video.play()
咋一看沒什麼錯,官方文件也明確寫著支援,然而還是“太年輕了”,當開始開啟頁面,且使用者還沒有產生什麼互動時,谷歌、火狐瀏覽器赫然報錯了。
報錯如下:
谷歌瀏覽器
火狐瀏覽器
谷歌瀏覽器的提示比較明瞭,原因是使用者還沒有跟document
產生互動,這主要是考慮到使用者體驗問題,那麼回到正題,互動具體是什麼呢?實測移動端的touchstart
和PC端的mousedown
觸發後都會產生使用者互動,前提這是使用者自己觸發的,而不是用JS
模擬的。
解決辦法
那麼既然瀏覽器的規則是確定的(詳見谷歌的Autoplay描述文件),我們應該如何解決需求,搞定產品經理呢?
在作者看來應該要具體需求具體分析,比如說是否允許使用者產生互動後,才做播放?這樣只要監聽document
的touchstart
或mousedown
事件,再做播放就是了;又或者一般我們都是做單頁網站,恰好又需要登入,那麼互動都會提前產生,也就沒有這個問題了。
回到篇首所說的需求,基本是上面說的第二種情況,需要自動播放,而檢視訂單是需要登入的,咋一看似乎有沒啥問題了,然而又有一個其他的問題。使用者登入會有個登入過期的規則,時間一般會設定在30分鐘左右,如果使用者剛好在這個頁面登入超時,超時後登入會直接跳轉到訂單列表頁,此時使用者又剛好晾著不管,沒有做任何操作,那麼我們所做的音訊提醒是不靠譜的。
這個時候有兩種解決辦法
- 登入後攔截特定的URL並重定向到臨近該URL的頁面;
- 使用上面 Autoplay文件裡介紹的方法,給予使用者友善的提示;
第二種方式如下
const promise = audio.play();
if (promise !== undefined) {
promise.then(res => {
// 播放成功
}).catch(error => {
// 提醒使用者點選啟用播放,並檢視新訂單
});
}
由於play()
方法返回的是一個Promise
例項,那麼監聽其成功失敗,就能知道結果並做相應的操作了,至於“點選啟用”,點選哪裡都是一樣的。
以上是一些“曲線救國”的方案,儘管都不完美,但相信產品經理能夠理解,畢竟瀏覽器規則不是我們前端開發能輕易改變的