成品
Youtube Search Engine
介紹
串接 Youtube Data API 將搜尋結果列出來,並引入 fancybox 點擊播放時彈出視窗顯示在頁面最上層,如下圖。
功能
- 列出搜尋結果
- 上一頁 / 下一頁 功能
- Fancybox
列出搜尋結果
申請 Youtube Data API
在開始使用 API 前我們需要申請一組金鑰 key 作為授權碼,先到 Developer Console’s 啟用 API 和服務。
找到並點選「Youtube Data APIv3」
啟用 API
啟用後進入到 Youtube Data API v3 的管理頁面建立憑證,把產生的金鑰 key 記下來
Request
申請好憑證就可以開始使用 API 了,官方文件 Search list 中說明了可使用的參數,這邊說明幾個待會會使用到的參數:
part
:每個搜尋結果中所包含的資訊,頻道名稱、影片敘述、縮圖等,根據手冊將值設為 snippet
maxResults
:設定每次回傳的數量,範圍 0~50,預設值為 5
order
:將搜尋結果排序的方法,分別是
date
:根據創建日期排序
rating
:根據評價排序
relevance
:根據與搜尋的關鍵字相關性排序
title
:根據標題字母順序排序
videoCount
:根據頻道上傳的影片數量排序
viewCount
:根據觀看數排序
q
:要搜尋的關鍵字
pageToken
:辨認要回傳的結果頁面,nextPageToken
、prevPageToken
可以用來回傳下一頁 / 上一頁的搜尋結果
對搜尋按鈕監聽獲取搜尋的關鍵字,再來將我們需要的參數設定和申請好的金鑰 key 加入 url
中並發出請求。
成功之後將回傳的pageToken
傳給函式 generateButtons
用來產生 下一頁 / 上一頁的按鈕。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| let q;
$('#search-btn').click(function(e) { e.preventDefault();
$('#results').html(''); $('#buttons').html('');
q = $('#search-field').val(); getVideos(q); });
function getVideos(q) { $.ajax({ url: `https://youtube.googleapis.com/youtube/v3/search?part=snippet&maxResults=5&order=relevance&q=${q}&key=API_KEY`, method: 'GET', dataType: 'json', success: function(res) { const nextPageToken = res.nextPageToken; const prevPageToken = res.prevPageToken; $.each(res.items, function(i, item) { showViedos(item); }); generateButtons(prevPageToken, nextPageToken); } }); }
|
Response 為
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| { "kind": "youtube#searchListResponse", "etag": etag, "nextPageToken": string, "prevPageToken": string, "regionCode": string, "pageInfo": { "totalResults": integer, "resultsPerPage": integer }, "items": [ search Resource ] }
|
其中的 items
中為我們所需要的資訊
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| { "kind": "youtube#searchResult", "etag": etag, "id": { "kind": string, "videoId": string, "channelId": string, "playlistId": string }, "snippet": { "publishedAt": datetime, "channelId": string, "title": string, "description": string, "thumbnails": { (key): { "url": string, "width": unsigned integer, "height": unsigned integer } }, "channelTitle": string, "liveBroadcastContent": string } }
|
顯示搜尋結果
呼叫函式,將回傳的每一筆搜尋結果整理然後顯示在頁面上。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| function showViedos(item) {
const videoID = item.id.videoId; const title = item.snippet.title; const description = item.snippet.description; const thumbnail = item.snippet.thumbnails.high.url; const channelTitle = item.snippet.channelTitle; const videoDate = item.snippet.publishedAt;
const result = $('<li></li>'); result.html(` <div class="thumbnail"> <img src="${thumbnail}" alt=""> </div> <div class="info"> <h3><a data-fancybox href="http://www.youtube.com/embed/${videoID}">${title}</a></h3> <small>By <span class="cTitle">${channelTitle}</span> on ${videoDate.substr(0,10)}</small> <p>${description}</p> </div> `);
$('#results').append(result); }
|
上一頁 / 下一頁 功能
將得到的 pageToken
產生相對應的按鈕,並把值賦予屬性儲存起來,點擊按鈕時執行對應的函式。
第一頁的搜尋結果回傳的只有 nextPageToken
,而沒有 prevPageToken
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| function generateButtons(prevPageToken, nextPageToken) { if (!prevPageToken) { const button = $(` <div class="button-container"> <button id="next-button" class="next-button" data-token="${nextPageToken}" onclick="nextPage()"></button> </div> `); $('#buttons').append(button); } else { const button = $(` <div class="button-container"> <button id="prev-button" class="prev-button" data-token="${prevPageToken}" onclick="prevPage()"></button> <button id="next-button" class="next-button" data-token="${nextPageToken}" onclick="nextPage()"></button> </div> `); $('#buttons').append(button); } }
|
從按鈕中的屬性獲取 pageToken
的值,把 pageToken
的值加入 url
中再次發出請求,重新渲染至頁面,這邊用 next page 說明,prev page 也是相同的概念。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| function nextPage() { const token = $('#next-button').data('token');
$('#results').html(''); $('#buttons').html('');
$.ajax({ url: `https://youtube.googleapis.com/youtube/v3/search?part=snippet&maxResults=5&order=relevance&q=${q}&pageToken=${token}&key=API_KEY`, method: 'GET', dataType: 'json', success: function(res) {
const nextPageToken = res.nextPageToken; const prevPageToken = res.prevPageToken;
$.each(res.items, function(i, item) { showViedos(item); });
generateButtons(prevPageToken, nextPageToken); } }); }
|
Fancybox
每一筆搜尋結果使用 fancybox 播放影片,參考文件中 fancybox Iframe 在連結中加入 data-fancybox
、data-type="iframe"
的屬性。
HTML
1 2 3 4 5 6
| <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/fancyapps/fancybox@3.5.7/dist/jquery.fancybox.min.css" /> <script src="https://cdn.jsdelivr.net/gh/fancyapps/fancybox@3.5.7/dist/jquery.fancybox.min.js"></script>
<h3><a data-fancybox data-type="iframe" href="http://www.youtube.com/embed/${videoID}">${title}</a></h3>
|
JavaScript
1 2 3 4 5 6 7
| $('[data-fancybox]').fancybox({ toolbar : false, smallBtn : true, iframe : { preload : false } })
|
參考資料