canaria's blog

響け! この歌に乗せ 愛を送るよ

0%

專案雜記|百鬼開台了嗎 計時器

intro

想想還是寫一下好了,畢竟這算是我第一次摸Youtube Data API。寫下來留個紀錄。
月初某天在Discord群組內閒聊的時候,有人提到了百鬼不知道幾天不開台了。由於Youtube超過一段時間後,在影片頁面上只會顯示該影片是在幾週或幾個月前上傳。除非點進最新的影片內,不然看不到確切的上傳日期。
這也給我一個想法,是不是可以用Youtube API直接抓到最新的影片上傳日期呢?因此在那幾天打APEX的零碎時間下完成了這個小專案(?)

demo

懶得看code的人可以直接點網址,順便訂閱一下我家百鬼あやめ,按讚分享開啟小鈴鐺

Youtube Data API

由於Google App Script內建Youtube Data API,只要在頁籤內新增服務即可直接使用,因此我這邊採用Google App Script作為我的後端資料操作。
Google開放每個專案每天約100次的搜尋請求,在小範圍內使用應該是沒問題的。
詳細的說明可以參考官方文件以及Google App Script的example code,這邊只做簡單的介紹。

youtube頻道網址後面那一串就是channelId。首先依照channelId搜尋該頻道依照上傳順序排列的最新一部影片。
回傳的東西雖然很多,但這次我們只需要三個部分,分別為:︁直播狀態、公開時間、影片ID。

  • 直播狀態(liveBroadcastContent):共有三種可能的值,分別是預定開始直播(upcoming)、直播中(live)、毫無反應就是個影片(none)。
  • 公開時間(publishedAt):回傳的時間格式會長這樣 2022-03-11T15:33:11Z ,後續可以交由Day.js處理。這邊要注意的是,假如頻道主在17:30發送直播預告,18:00開始直播,這邊回傳的值依然會是17:30。
  • 影片ID(videoId):就是youtube的影片ID,這邊回傳時幫他補上了/embed/,方便接下來直接嵌入網頁。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function doGet(e) {

var cid ='UC7fk0CB07ly8oSl0aqKkqFg';
var results = YouTube.Search.list('snippet', {channelId: cid, type: 'video', order: 'date', maxResults: 1});

if (results.items[0]){

var livestatus = results.items[0].snippet.liveBroadcastContent;
var publishtime = results.items[0].snippet.publishedAt;
var videoid = results.items[0].id.videoId;

var ans = {
'live': livestatus,
'pubt': publishtime,
'vidi': 'https://www.youtube.com/embed/' + videoid
};

return ContentService.createTextOutput(JSON.stringify(ans)).setMimeType(ContentService.MimeType.JSON);
}
else {
return 0;
}
}

Day.js

首先我們要判斷頻道的狀態是即將直播直播中沒開台。如果是前兩者的話便將計時器隱藏,並嵌入直播影片。
再來透過Day.js,就算時間格式不同,我們也可以很簡單的算出現在和影片發布時間的間隔,在經過數值處理後就能得出:上次開台至今過了幾天幾時幾分幾秒了。
Day.js的功能還有很多,其他功能可以參考官方文件

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
$.get('https://script.google.com/macros/s/nakiri-api/exec' , function(e) {

if (e.live == "none"){

/*顯示計時器*/

const startDate = dayjs(e.pubt);
setDate();
setInterval(() => setDate(), 1000);

/*每1000毫秒刷新一次*/

function setDate() {
let secs = dayjs().diff(startDate, 'second');
let mins = Math.floor(secs / 60);
let hours = Math.floor(mins / 60);
let days = Math.floor(hours / 24);
secs = secs - (mins * 60)
mins = mins - (hours * 60);
hours = hours - (days * 24);

let secs2 = secs.toString().padStart(2, '0');
let mins2 = mins.toString().padStart(2, '0');
let hours2 = hours.toString().padStart(2, '0');

$('#day').text(days);
$('#hour').text(hours2);
$('#min').text(mins2);
$('#sec').text(secs2);
}

}
if (e.live == "upcoming" || e.live == "live"){

/*隱藏計時器*/

$('<iframe>', {
src: e.vidi,
id: 'ytplayere',
frameborder: 0,
scrolling: 'no'
}).appendTo('#ytplayer');

}
else {
...
}
});

分享按鈕

這也算是我第一次做三個社群的分享按鈕,搭配了Font Awesome Icon和簡單的onclick事件來完成。
三個台灣常見的社群平台分享連結如下:

1
2
3
4
5
6
7
8
// twitter
http://twitter.com/share?text={TEXT_MESSAGE}&url={URL_MESSAGE}&hashtags={TAG_MESSAGE}

// facebook
https://www.facebook.com/sharer/sharer.php?kid_directed_site=0&sdk=joey&u={URL_MESSAGE}&display=popup&ref=plugin&src=share_button&quote={TEXT_MESSAGE}

// line
https://line.me/R/msg/text/?{TEXT_MESSAGE}

outro

透過這次的小專案,我稍微認識了Youtube Data API和Day.js。
希望未來能有更多點子讓我可以練手,也希望我家百鬼あやめ可以多多開台。

以上。