影片愈來愈重要的這時代,前端會遇到嵌 Youtube 的相關需求
最近做的幾個案子,頁面上很常會要嵌入 Youtube,比方一些形象的宣傳影片、一些看起來很感人但其實是廣告的影片(咦?)。
大部份遇到這需求,都是直接用 Youtube 本來就有提供的 iframe 來解決,但有些時候會需要用到 API,像是當企劃說:「我想要滑到出現影片這塊時,影片就自動播放。」、「當影片播放時,幫我埋個 GA 事件。」…etc。
這時如果只會基本的 iframe,是不夠的。而且為了節省流量,公司又沒有串流功能時,影片很少很少會放自己的主機,大部份都是放 Youtube 上,這些情況就需要用到 Youtube 提供的 iframe API。
本篇要筆記的就是 Youtube iframe API 的一些常用功能,比方嵌入、自動播放、監聽影片狀態、做一個自己的控制器等。
再配合之前寫過的二篇,就可以滿足上面企劃提的例子了:
滑到影片出現時自動播放,可用 IntersectionObserver 配合。
發送 GA 事件,先了解 GA 事件要傳送哪三個值。
基本使用:嵌入影片 + 自動播放
Youtube iframe API 最基本的使用,就是嵌入影片了。API 中嵌入影片有二種方式:
- HTML 中放一個 div,由 JavaScript 去嵌入
- HTML 裡直接放個 iframe
這兩種方式不論哪一種,都可以直接在嵌入完成後,自動播放影片。
要注意的是,瀏覽器的政策是不能干擾使用者的瀏覽,所以如果想要自動播放影片,影片就 必須要是靜音,這樣自動播放時,使用者也不會因為突然出現的聲音而被嚇到。
以下的 HTML,UI 用了 Bootstrap,因此會看見出現 Bootstrap 的 class name。
另外本筆記所有 Demo,會統一整理在一個頁面上,網址連結附在最後一段。
1 HTML 中放一個 div,由 JavaScript 去嵌入
程式碼如下:
可以看到,HTML 就是放一個 <div id="player"></div>
,再由 JavaScript 呼 API 去指定 player 這個 id 的 div 去嵌入影片。
因為 Bootstrap 的 CSS 會讓 iframe 有響應式,因此 iframe 的寬高就寫預設值的 640*390 就行。
videoId
就是要嵌入的 Youtube 影片 id。影片 id 可以從網址上找到,我們一般看到的 Youtube 網址是這樣:
https://www.youtube.com/watch?v=KuhIY-AUG6c
影片 id 就是 v=
後面的那一串,像這個例子就是 KuhIY-AUG6c
。順帶一提,這部影片的泱泱好可愛~
API 中跟一般嵌入 Youtube 最大的不同,就是有一個 callback,可以在影片嵌入完就緒時,執行一個 function,就是程式碼中的這段:
events: { 'onReady': onPlayerReady }
當影片 ready 的時候,就執行 onPlayerReady
這個 function。
onPlayerReady 寫的內容是這樣:
function onPlayerReady(e) { e.target.mute().playVideo(); }
function 會自動帶一個參數,這邊用小寫 e
,實際上你想叫什麼都行,也可以寫成 event
,或是你家小狗的英文名字,一般我們會用 event
或是偷懶用小寫 e
。
e.target
就是這個 Youtube 本身,mute()
是讓它靜音,playVideo()
就是播放影片。
2 HTML 裡直接放個 iframe
直接放個 iframe 的方式,跟我們一般複製貼上 Youtube 給的嵌入碼很像,但還是有小地方不一樣:
在 iframe src 的部份,最後要帶一個參數:enablejsapi=1
origin="嵌入 Youtube 的網域"
這個則是選填,如果有填,那嵌入 Youtube 的網域,就要是你寫在 origin 後面的那個網域。比方如果這邊寫了 origin=https://letswrite.tw
,那這一段程式碼就只能在本站中執行 Youtube iframe API,如果不是在本站,就會報錯。
JavaScript 的部份跟前一種方式是一樣的,但因為寬高可以寫在 iframe上,因此呼 API 這段可以不必寫寬高。
HTML 上,iframe 的 id 還是要有,API 在呼的時候不管是 1、2 哪種方式,都要寫上 id。
自製 Youtube 播放器
這段來筆記自製播放器的部份,最後會完成的樣子如下:
可以看到,泱泱好可愛~~啊不是,是這邊的 Demo 上總共接了 API 提供的幾項功能:
- 播放、暫停、停止
- 後退 10 秒、前進 10 秒(秒數可以自己設定)
- 播放速度,捲軸的值是:0.25 / 0.5 / 0.75 / 1 / 1.25 / 1.5 / 1.75 / 2
- 音量:0 – 100
- 是否靜音
這些 API 文件上都有寫,不過散在各段中,覺得未來總會有遇到以上需求的時候,這邊就把這幾項功能整理在一起,程式碼如下:
每個功能按鈕都給一個 id,這個按鈕就監聽 click 事件,捲軸的話就是監聽 input 事件,聽到事件後的 callback,都是寫在 onPlayerReady
的function中。
需要說明的是後退、前進幾秒這個,這邊 Youtube 並沒有直接給一個往前/往後的功能,但有給了兩個 API:抓目前播放到幾秒、讓影片直接跳到幾秒。
因此所謂的後退、前進功能,其實就是按了按鈕後,先抓目前影片播放的秒數,接著讓影片跳到目前秒數 +10 或 -10 的地方。加多少或減多少可以自行修改。
其它的功能程式碼裡面都有寫上註解了,可以直接看註解說明。
監聽 Youtube 播放狀態
Youtube 的影片我們可以用 API 來知道目前是:準備好的、初次載入的、播放的、暫停的、播完的、緩衝中,這六種狀態。
可以看到,在原本 'onReady': onPlayerReady
下面多加了一個 callback:
'onStateChange': onPlayerStateChange
onPlayerStateChange
這個 function 一樣會帶上一個參數,這邊取名為小寫 e。小寫 e 一樣指的是這個 Youtube 這個影片本身,但會另外多帶另一個 data
出來,console.log 的話會看到以下:
這個 data 就是影片的狀態碼,總共有 -1、0、1、2、3、5 這六個數字,對應的狀態如下:
- -1:unstarted 未啟動,初次載入
- 0:ended 結束
- 1:playing 播放中
- 2:paused 暫停
- 3:buffering 緩衝中
- 5:video cued 準備好可以播放了
當頁面嵌入的 Youtube,這個影片準備就緒時,用 e.target.getPlayerState()
會得到 5 這個狀態。
當你按下播放,這時影片會開始載入,狀態會回傳 -1,這段就是當我們按下播放,會看到 Youtube 一開始出現的轉圈圈那段。
當 Youtube 開始播影片,狀態碼是 1。
按下暫停是 2。
如果網路太慢需要緩衝又在那轉圈圈時是 3。
影片整個播完了是 0。
我們可以針對不同的狀態,發送不同的 GA 事件,就可以大概統計有多少人點了影片播放,又有多少人有看完。
Demo、原始碼
Demo 跟原始碼的部份都有整理在 GitHub 上。
Demo:https://letswritetw.github.io/letswrite-youtube-iframe-api/
原始碼:https://github.com/letswritetw/letswrite-youtube-iframe-api
本篇參考資源主是 Youtube Iframe Player API 的文件:
YouTube Player API Reference for iframe Embeds