This repository has been archived by the owner on Nov 19, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
302 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import { | ||
Router, | ||
} from "../../../../helpers/route"; | ||
import { | ||
getSetting, | ||
} from "../../../../helpers/settings"; | ||
import YoutubeService from "../../../../services/external/google/youtube-service"; | ||
|
||
const router = new Router(); | ||
|
||
router.get("/video-id", async (): Promise<string | null> => { | ||
const channelId: string = await getSetting("YouTube channel id"); | ||
|
||
if (!channelId) { | ||
return null; | ||
} | ||
|
||
return await YoutubeService.getChannelLiveVideoId(channelId); | ||
}); | ||
|
||
router.get("/is-live", async (): Promise<boolean> => { | ||
const channelId: string = await getSetting("YouTube channel id"); | ||
|
||
if (!channelId) { | ||
return false; | ||
} | ||
|
||
return await YoutubeService.isChannelLive(channelId); | ||
}); | ||
|
||
export default router; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import xml2js from "xml2js"; | ||
import { | ||
get, | ||
} from "../../../helpers/axios"; | ||
import { | ||
cachedFetcher, | ||
CacheKey, | ||
} from "../../../helpers/fetchCache"; | ||
|
||
const fetchChannelLiveInfo = cachedFetcher<null | string>( | ||
"youtube-live", | ||
15 * 1000, | ||
async (channelId: string) => { | ||
const page = await get<string>( | ||
`https://www.youtube.com/channel/${ channelId }/live`, | ||
{ | ||
validateStatus: (status) => 404 === status || 200 === status, | ||
}, | ||
); | ||
|
||
if (!page.includes("<meta name=\"title\"")) { | ||
return null; | ||
} | ||
|
||
const xml = await get<string>( | ||
`https://www.youtube.com/feeds/videos.xml?channel_id=${ channelId }`, | ||
); | ||
|
||
const data = await xml2js.parseStringPromise( | ||
xml, | ||
{ | ||
trim: true, | ||
normalize: true, | ||
normalizeTags: true, | ||
}, | ||
); | ||
|
||
return data?.feed?.entry?.shift()?.id?.pop()?.split(":")?.pop() || null; | ||
}, | ||
(channelId: string) => channelId as CacheKey, | ||
); | ||
|
||
export default class YoutubeService { | ||
public static async isChannelLive(channelId: string): Promise<boolean> { | ||
const videoId = await this.getChannelLiveVideoId(channelId); | ||
|
||
return null !== videoId; | ||
} | ||
|
||
public static async getChannelLiveVideoId(channelId: string): Promise<string | null> { | ||
try { | ||
return await fetchChannelLiveInfo(channelId); | ||
} catch { | ||
return null; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
<template> | ||
<div style="display: none;" /> | ||
</template> | ||
|
||
<script> | ||
export default { | ||
data: () => ({ | ||
timers: {}, | ||
}), | ||
beforeDestroy() { | ||
this.removeTimers(); | ||
}, | ||
mounted() { | ||
this.addTimer( | ||
"youtubeLiveCheck", | ||
() => this.$store.dispatch("external/live/fetchYoutubeLiveVideoId"), | ||
14000 + 2000 * Math.random(), | ||
); | ||
}, | ||
methods: { | ||
addTimer(key, fn, timeout = 10000) { | ||
this.$set( | ||
this.timers, | ||
key, | ||
{ | ||
timeout, | ||
fn, | ||
timer: setInterval(() => fn(), timeout), | ||
}, | ||
); | ||
}, | ||
removeTimers() { | ||
for (const { timer } of Object.values(this.timers)) { | ||
clearInterval(timer); | ||
} | ||
}, | ||
}, | ||
}; | ||
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
<template> | ||
<app-max-width-container> | ||
<v-row> | ||
<v-col cols="12"> | ||
<h1 | ||
:class="$style.header" | ||
class="text-center my-12" | ||
> | ||
<translated-text trans-key="live.header" /> | ||
</h1> | ||
</v-col> | ||
</v-row> | ||
|
||
<v-row> | ||
<v-col cols="12"> | ||
<div :class="$style.wrapper"> | ||
<iframe | ||
:class="$style.iframe" | ||
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" | ||
allowfullscreen | ||
frameborder="0" | ||
height="100%" | ||
:src="`https://www.youtube.com/embed/${youtubeId}`" | ||
title="YouTube video player" | ||
width="100%" | ||
/> | ||
</div> | ||
</v-col> | ||
</v-row> | ||
</app-max-width-container> | ||
</template> | ||
|
||
<router> | ||
name: PageLive | ||
</router> | ||
|
||
<script> | ||
import { | ||
mapGetters, | ||
} from "vuex"; | ||
import AppMaxWidthContainer from "../components/AppMaxWidthContainer"; | ||
import TranslatedText from "../components/TranslatedText"; | ||
export default { | ||
components: { | ||
TranslatedText, | ||
AppMaxWidthContainer, | ||
}, | ||
async validate({ store, redirect }) { | ||
const isLive = await store.getters["external/live/isLive"]; | ||
if (isLive) { | ||
return true; | ||
} | ||
return redirect({ name: "Index" }); | ||
}, | ||
computed: { | ||
...mapGetters("external/live", [ | ||
"youtubeId", | ||
]), | ||
}, | ||
}; | ||
</script> | ||
|
||
<style lang="scss" module> | ||
@import "assets/styles/include/all"; | ||
.header { | ||
font-size: 250%; | ||
font-weight: bold; | ||
text-align: center; | ||
text-transform: uppercase; | ||
color: $fer-dark-blue; | ||
} | ||
.wrapper { | ||
position: relative; | ||
padding-top: 56.25%; | ||
.iframe { | ||
position: absolute; | ||
top: 0; | ||
left: 0; | ||
width: 100%; | ||
height: 100%; | ||
} | ||
} | ||
</style> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import Vue from "vue"; | ||
|
||
export const state = () => ({ | ||
youtubeLiveVideoId: null, | ||
}); | ||
|
||
export const getters = { | ||
youtubeId(state) { | ||
return state.youtubeLiveVideoId; | ||
}, | ||
|
||
isLive(state, getters) { | ||
return Boolean(getters.youtubeId); | ||
}, | ||
}; | ||
|
||
export const mutations = { | ||
SET_YOUTUBE_ID(state, id) { | ||
Vue.set(state, "youtubeLiveVideoId", id); | ||
}, | ||
}; | ||
|
||
export const actions = { | ||
async fetchYoutubeLiveVideoId({ commit }) { | ||
const { data } = await this.$api.$get( | ||
"/external/info/youtube/live/video-id", | ||
{ | ||
progress: false, | ||
}, | ||
); | ||
|
||
commit("SET_YOUTUBE_ID", data); | ||
|
||
return data; | ||
}, | ||
|
||
async nuxtServerInit({ dispatch }) { | ||
await dispatch("fetchYoutubeLiveVideoId"); | ||
}, | ||
}; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1941,6 +1941,13 @@ | |
"@types/webpack-sources" "*" | ||
source-map "^0.6.0" | ||
|
||
"@types/xml2js@^0.4.8": | ||
version "0.4.8" | ||
resolved "https://registry.yarnpkg.com/@types/xml2js/-/xml2js-0.4.8.tgz#84c120c864a5976d0b5cf2f930a75d850fc2b03a" | ||
integrity sha512-EyvT83ezOdec7BhDaEcsklWy7RSIdi6CNe95tmOAK0yx/Lm30C9K75snT3fYayK59ApC2oyW+rcHErdG05FHJA== | ||
dependencies: | ||
"@types/node" "*" | ||
|
||
"@typescript-eslint/eslint-plugin@^4.21.0": | ||
version "4.21.0" | ||
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.21.0.tgz#3fce2bfa76d95c00ac4f33dff369cb593aab8878" | ||
|
@@ -10305,7 +10312,7 @@ sass@^1.26.5: | |
dependencies: | ||
chokidar ">=2.0.0 <4.0.0" | ||
|
||
sax@>=0.6, sax@~1.2.4: | ||
sax@>=0.6, sax@>=0.6.0, sax@~1.2.4: | ||
version "1.2.4" | ||
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" | ||
integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== | ||
|
@@ -12463,6 +12470,19 @@ xml-crypto@^2.0.0: | |
xmldom "0.1.27" | ||
xpath "0.0.27" | ||
|
||
xml2js@^0.4.23: | ||
version "0.4.23" | ||
resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.23.tgz#a0c69516752421eb2ac758ee4d4ccf58843eac66" | ||
integrity sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug== | ||
dependencies: | ||
sax ">=0.6.0" | ||
xmlbuilder "~11.0.0" | ||
|
||
xmlbuilder@~11.0.0: | ||
version "11.0.1" | ||
resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3" | ||
integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA== | ||
|
||
[email protected]: | ||
version "0.1.27" | ||
resolved "https://registry.yarnpkg.com/xmldom/-/xmldom-0.1.27.tgz#d501f97b3bdb403af8ef9ecc20573187aadac0e9" | ||
|