架構圖 === ###### tags: `Jukebox` [toc] # Spotify 使用 Fire base ```graphviz digraph { node[shape=Mrecord] rankdir=LR // subgraph cluster_WebPlayer { // label="網頁" subgraph cluster_user { label="user" beforeLogin [label="<f1>未登入 |輸入 host 帳號進入 room |查看 host 歌單"]; userPlayer [label="登入自己的帳號 |<search>搜尋歌 |<list>查看自己的歌單 |網頁播放器"] user2host [label="編輯 room 歌單(點/插歌)| 投票決定喀歌"] userToken [label="自己的 token"] } subgraph cluster_host { label="host" hostCreate [label="登入 host, 建立 room"] player [label="SDK網頁播放器"] message [label="廣播"] } // } subgraph cluster_firebase { label="Fire base" userSystem [label="會員系統"] room [label="<data>room data |<list>歌單"] hostToken [label="host token"] } subgraph cluster_spotify { label="spotify" server [label="Spotify server"]; oauth2 [label="Spotify Oauth2"]; } message -> Speaker player -> Speaker hostCreate -> oauth2 -> room:data -> hostToken beforeLogin -> room room -> beforeLogin userPlayer -> oauth2 -> userToken -> server -> userPlayer user2host -> hostToken -> server -> player } ``` 好難畫Q_Q總之就是用 firebase 做啦 --- --- ## 前端頁面: 功能: 1. 顯示播放清單(host) 2. 顯示播放清單(user) 3. 網頁播放器(user) 4. 會員登入系統 5. 點歌系統(host) 6. 廣播系統 7. 投票喀歌系統 ## story - 初次造訪網頁先輸入 host 的帳號(room),找到存在於 Fire base 的 room / 在 fire base 建立 room。 - 取得 room 的資料,顯示目前 room 裡面有的歌單, - 登入自己的 spotify account 搜尋歌,也可以先透過網頁播放器用自己的帳號先播歌,選擇是否要語音廣播,排序進去 fire base。 - 需要是登入的狀態才可以參與咖歌投票事件 - **歌曲的播放實際上是透過 fire base 讓網頁帳號是登入 host 的手機撥放音樂,原本要在後端做的"音樂與語音的切換"都由 host 的網頁處理** - user 必須要有 spotify 帳號才可以搜尋音樂 ## 待討論 1. 不使用讓 user 使用 host 的 token: - 讓 user 可以使用自己的帳號事先播放音樂 ## Fire base: 1. 儲存 room data - host account - host token - track list 3. 即時發送 room 歌單, 語音文字 4. 會員資料 --- # spotify 單一帳號固定在後端 ```graphviz digraph { node[shape=Mrecord] // rankdir=LR // subgraph cluster_WebPlayer {} server [label="Spotify server" shape=box]; back [label=" {<f1> 儲存歌單 |<f2> 自訂會員系統 |插入 Ms.Google 語音} |backend "]; font [label=" {<f2>查看現在的歌單 |<s1>編輯 backend 歌單(點/插歌) |<s2>投票決定喀歌} |<f1>搜尋介面 |fontend "]; phone [label="{phone |與 backend 登入同帳號 |SDK網頁播放器}"] back -> phone [label="Spotify connect"]; phone -> speaker; server -> back; back -> server [label="發出下一首歌API"]; back -> font:s1; font:s1 -> back; server -> font:f1 [label="用從 back end 取得的 token 來查詢歌"]; font:f1 -> server; } ``` ## story - 前端: 顯示播放清單+播放器介面+會員登入系統+點歌廣播系統+投票喀歌系統 - 登入會員系統前,可以先經由 spotify oauth 登入自己的 spotify account,使用 WEB API 查詢歌或者先在自己的電腦撥放確定這是想要點的歌,再透過網頁傳要點的歌給後端 server。WEB API 目前查看結果也必須要有 token,有誤請告知。如果不需要則可以不需要登入自己的 spotify account 就可以查詢 - 登入會員系統後,才可以操作後端 server 內的播放清單、投票機制 - 後端: 接收編輯清單+會員資料+投票喀歌系統+發送撥放歌曲 API - 會員系統可以 - 從個人 spotify 獲取基本資料 (但是點歌部分只是傳送 spotify_url 給後端,後端接收到是哪一首歌後加進去暫存的歌單) - 訪客式登入或者簡單註冊暱稱當作帳號登入,主要目的只是紀錄是誰點了歌、投票時需要有的依據 - 必須在前端點歌時接收廣播 message,在當前撥放的歌結束後發暫停撥放API,然後先插入 message 廣播,再送出撥放歌曲的 api - 必須發送即時播放清單的更動 - 手機: 和使用者所見頁面基本上一樣,登入的是 host account,room host(房主) 的概念 - 必須是瀏覽器的撥放器,這樣才可以結合 spotify web SDK 和 Google 語音,如果只是單純的 spotify 原生 app,就沒辦法插入 google 語音(是吧?) --- # ~~單純使用 spotify connect~~ ```graphviz digraph { node[shape=Mrecord] // rankdir=LR user [label="{user |可以使用電腦/手機操作原生 spotify app,連動群組 |自己的電腦/手機必須退出群組才可以撥自己要的音樂 |加入群組期間不小心誤觸手機/電腦的案件會直接影響到整個群組}"]; server [label="Spotify server" shape=box]; back [label="{back end |固定帳號維持登入狀態 |回傳 spotify connent 邀請連結/條碼 |限時將以加入群組播放的 spotify account 踢出,\n因為同時間上限六個帳號 |在對應的歌上發暫停播放 API,並插入廣播給 phone 網頁播放器}"]; font [label="{font end | 渲染條碼 | 渲染目前播放+群組播放清單 | spotify web SDK player}"]; phone [label="{phone |與 backend 登入同帳號 |SDK 網頁播放器}"]; back -> font [label="傳送群組撥放邀請碼"]; font -> back [label="傳送歌單、\n對應廣播"] font -> user [label="oauth 登入\n使用邀請碼\n加入群組"]; user -> font [label="新增歌單\n新增廣播"]; server -> phone [label="->因為 connect 特性,\n user電腦/手機、font end SDK player 操作\n都會透過 spotify server 連帶操控手機"]; user -> server [label="透過 spotify connet 功能\n操控 phone 的 spotify app"]; server -> user; back -> server [label="登入\n"]; server -> back; phone -> speaker; } ``` ## story - spotify 群組播放會讓多個帳號登入後共享同一個播放清單、同時間播放同樣的歌,想像是多個帳號被 spotify server 視為同一個帳號、正在播放同一個清單同一首歌。 - 使用者加入群組後可以操控手機/電腦 spotify app 直接影響整個群組 - 因為釐清流程後立場轉變不推薦不再繼續說明XD好像更麻煩一點都不單純啊啊啊!! - 最重要不推薦的原因: **使用者可以用自己的 app 操控共享歌單** - 我的理解有誤或者想太多,那再繼續討論 --- # 單單使用 youtube ```graphviz digraph { node[shape=Mrecord] // rankdir=LR server [label="youtube server" shape=box]; font [label="{渲染播放清單 |渲染播放器+畫面 |點歌搜尋介面} | font end"]; phone [label="{phone |可能可以跟使用者的同個瀏覽器播放畫面?}"]; back [label="{<f1> 儲存歌單 |<f2> 自訂會員系統 |插入 Ms.Google 語音 |平衡音量} |backend"]; font -> server; server -> font [label="直接搜尋找歌"]; font -> back back -> font [label="確認點歌\n編輯歌單"] phone -> server [label="跟 youtube server 要下首歌音訊"]; server -> phone; back -> phone [label="下達接下來的歌單給網站"] phone -> speaker } ``` - 大概就這樣而已吧~? 感覺簡單多了 - 暫時撇除掉 youbute 可能也可以像 spotify connect 共同編輯歌單這件事情 --- # youtube + spotify ```graphviz digraph { node[shape=Mrecord] // rankdir=LR // subgraph cluster_WebPlayer {} s_server [label="Spotify server" shape=box]; y_server [label="Youtube server" shape=box] back [label=" {<f1> 儲存歌單 |<f2> 自訂會員系統 |插入 Ms.Google 語音 |判別下一首是 youtube / spotify\n暫停另一方} |backend "]; font [label=" {<f2>查看現在的歌單 |<s1>編輯 backend 歌單(點/插歌) |<s2>投票決定喀歌} |<f1>搜尋介面 |fontend "]; phone [label="{phone |與 backend 登入同帳號 |SDK網頁播放器}"] back -> phone [label="next youtube url"] back -> phone [label="Spotify connect"]; phone -> y_server; y_server -> phone; phone -> speaker; s_server -> back; back -> s_server [label="發出下一首歌API"]; back -> font:s1; font:s1 -> back; s_server -> font:f1 [label="用 backend 取得的\ntoken 來查歌"]; font:f1 -> s_server; y_server -> font:f1 [label="用 backend 取得的\ntoken 來查歌"]; font:f1 -> y_server; {rank="same"; y_server s_server} } ``` - 歌單由 backend 管理,順序可能夾雜 spotify / youtube 的歌,如果 下一首是 spotify、youtube 則暫停,反之亦然。 - 需要在網頁中實做出兩個 player 做切換。 # Line Bot ```graphviz digraph { node[shape=Mrecord] spotify [label="Spotify server"]; client [label="{<1>Spotify client |line bot 處理字串變成 api 所需要的樣子 |<2>line bot }"] spotify -> client client -> spotify user -> client:2 client:2 -> user // [label="{Line Bot |用 node 架的 server |spotify id, secret, token}"] } ```