Qiita初投稿です。
バックエンド寄りのことばっかりやってましたが、何かものを作りたいと思い、Electronが良さげな感じだったので、Youtube Live ROM専用プレーヤーを作ってみました。
アプリ名は「Madoka」です。
ソースコード及びダウンロード
ソースコード: https://github.com/minakawa-daiki/Madoka
ダウンロード: https://github.com/minakawa-daiki/Madoka/releases/tag/v0.1.0
※動作は Mac/Windows で確認しています。
主に使用したもの
- Electron v1.7.9
v1.8.1をはじめ使っていましたが、通信が安定しなかったため、バージョンを下げました。 - React
全てをReactではなく、少し複雑なコンポーネントのみをReactで記述しました。 - Webpack
トランスパイルで使用しました。 -
YouTube Data API (v3)
コメントの取得部分で使用しました。 -
Shuvi-lib
プレーヤー本体に使用しました。(Qiita)
Madoka -まどか-
主な機能としては
- YouTube Liveの映像再生
- コメントの表示
です。すごくシンプルに作ってあります。
使い方としては動画IDを入力して「エンターキー」を押すか「検索マーク」を押すと、映像とコメントが流れます。
Live専用なので、シークバーはあえて用意しませんでした。
プレイヤー操作としては、再生、停止、更新、画質の変更などが可能です。
また、コメントを隠すことで映像のみにすることも可能です。
技術よりのはなし
YouTube Data API (v3)でコメント取得
コメントの取得にはVideoIdではなくliveChatIdが必要と気づくまでに少し時間がかかりました。
それと、今回MadokaではVideoIdからコメント取得まで辿っていますが、ChannelIdから辿っている例もありました。
VideoIdから実際にコメントを取得するコードの例
import googleApi from 'googleapis';
const youtube = googleApi.youtube({version: 'v3'});
youtube.videos.list({part: 'snippet, liveStreamingDetails', id: 'ここにVIDEO_ID', auth: 'ここにAPI_KEY'}, (err, data) => {
if (data && data.items[0] && data.items[0].liveStreamingDetails && data.items[0].liveStreamingDetails.activeLiveChatId) {
youtube.liveChatMessages.list({
part: 'snippet',
liveChatId: data.items[0].liveStreamingDetails.activeLiveChatId,
pageToken: '前回の続きからのコメントを取得する際に指定',
auth: 'API_KEY'
},
(err, data) => {
if (data) {
//次にコメントを取得する際に必要になるトークン
console.log(data.nextPageToken);
//コメントを取得
data.items.map(item => console.log(item.snippet.displayMessage));
//次回コメントを取得可能になるまでの時間(ポーリング待機時間)
console.log(data.pollingIntervalMillis);
}
});
}
});
ここで注意して欲しいのは、ニコニコ生放送のコメントみたいにWebSocketを通じてコメントを取得するのではなく、
こちらからのGETリクエストを通じて毎回コメントを取得するため、ポーリング待機時間があることです。
サーバーの負荷具合や時間帯によって変動するっぽいです。
Webpackを使用した際のdotenv使用方法
もともとWebpackではなく、babel-registerを使用していたのですが、読み込みが毎回結構時間がかかってしまうので、Webpackに変更した際、「.env」に記述した内容を読み込まなくなってしまったため少しつまづきました。
自分の解決方法としては「webpack.config.js」ファイルで「.env」を読み込んでしまうという方式にしました。(それ以外良い方法ある人は教えてください。)
const webpack = require('webpack');
const path = require('path');
require('dotenv').config({ path: __dirname + '/.env' });
module.exports = {
省略,
plugins: [
new webpack.DefinePlugin({
// process.env.NODE_ENVを'production'に置き換える
'process.env.NODE_ENV': JSON.stringify('production'),
//ここで「.env」ファイルの「YOUTUBE_API_KRY」の値を「process.env.YOUTUBE_API_KRY」に格納している
'process.env.YOUTUBE_API_KRY': JSON.stringify(process.env.YOUTUBE_API_KRY)
})
]
};
モーダル等をその要素以外をクリックした際に閉じる動作
地味につまづいたポイントです。
やり方は様々あると思うのですが、一番しっくりきた方法を書いておきます。
//画面のどこをクリックしても呼ばれるリスナ
document.addEventListener('click', (e) => {
//「#setting-wrap」はクリックした時に出現する要素
//クリックした場所が「#setting-wrap」以外の場合分岐に入る
if(e.target.closest('#setting-wrap') === null) {
//あとはdisplay:noneにするだけ
const settingMenuStyle = document.getElementById('setting-menu').style;
if(settingMenuStyle.display === 'flex'){ settingMenuStyle.display = 'none'; }
}
});
未解決
cssで -webkit-app-region: drag
を指定した際、Windows環境でその要素のhoverやクリックが怪しい。
終わりに
初めてElectronを触ってみたのですが、なかなか良かったです。
個人でこういったアプリを作るのがかなり久々だったのでとても楽しかったです。
これからもどんどんアプリつくっていくのでよろしくお願いします!
HP: https://minakawadaiki.com
GitHub: https://github.com/minakawa-daiki
Twitter: https://twitter.com/oliver_diary
FaceBook: https://www.facebook.com/minakawa.daiki