diff --git a/packages/app/src/pages/streams/viewer/index.jsx b/packages/app/src/pages/streams/viewer/index.jsx index 815b3c27..56020326 100644 --- a/packages/app/src/pages/streams/viewer/index.jsx +++ b/packages/app/src/pages/streams/viewer/index.jsx @@ -1,15 +1,25 @@ -import React from 'react' +import React from "react" +import config from "config" import * as antd from "antd" -import Plyr from 'plyr' -import Hls from 'hls.js' -import mpegts from 'mpegts.js' +import { Icons } from "components/Icons" +import moment from "moment" + +import Plyr from "plyr" +import Hls from "hls.js" +import mpegts from "mpegts.js" import "plyr/dist/plyr.css" +import "./index.less" -const streamsSource = "http://media.ragestudio.net/live" +const streamsSource = config.remotes.streamingApi export default class StreamViewer extends React.Component { state = { + userData: null, + streamInfo: null, + spectators: 0, + timeFromNow: "00:00:00", + player: null, streamKey: null, streamSource: null, @@ -22,18 +32,98 @@ export default class StreamViewer extends React.Component { componentDidMount = async () => { const query = new URLSearchParams(window.location.search) - const requested = query.get("key") + const requestedUsername = query.get("key") - const source = `${streamsSource}/${requested}` - const player = new Plyr('#player') + const source = `${streamsSource}/${requestedUsername}` + const player = new Plyr("#player", { + autoplay: true, + controls: ["play", "mute", "volume", "fullscreen", "options", "settings"], + }) await this.setState({ player, - streamKey: requested, + streamKey: requestedUsername, streamSource: source, }) await this.loadWithProtocol[this.state.loadedProtocol]() + + // make the interface a bit confortable for a video player + app.ThemeController.applyVariant("dark") + app.eventBus.emit("toogleCompactMode", true) + app.SidebarController.toogleVisible(false) + app.HeaderController.toogleVisible(false) + + // fetch user info in the background + this.gatherUserInfo() + + // fetch stream info in the background + // await for it + await this.gatherStreamInfo() + + // create timer + if (this.state.streamInfo.connectCreated) { + this.createTimerCounter() + } + } + + componentWillUnmount = () => { + app.ThemeController.applyVariant(app.settings.get("themeVariant")) + app.eventBus.emit("toogleCompactMode", false) + app.SidebarController.toogleVisible(true) + app.HeaderController.toogleVisible(true) + app.HeaderController.toogleVisible(true) + + if (this.timerCounterInterval) { + this.timerCounterInterval = clearInterval(this.timerCounterInterval) + } + } + + gatherStreamInfo = async () => { + const result = await app.request.get.streamInfoFromUsername(undefined, { + username: this.state.streamKey, + }).catch((error) => { + console.error(error) + antd.message.error(error.message) + return false + }) + + if (result) { + this.setState({ + streamInfo: result, + }) + } + } + + gatherUserInfo = async () => { + const result = await app.request.get.user(undefined, { + username: this.state.streamKey, + }).catch((error) => { + console.error(error) + antd.message.error(error.message) + return false + }) + + if (result) { + this.setState({ + userData: result, + }) + } + } + + createTimerCounter = () => { + this.timerCounterInterval = setInterval(() => { + const secondsFromNow = moment().diff(moment(this.state.streamInfo.connectCreated), "seconds") + + // calculate hours minutes and seconds + const hours = Math.floor(secondsFromNow / 3600) + const minutes = Math.floor((secondsFromNow - hours * 3600) / 60) + const seconds = secondsFromNow - hours * 3600 - minutes * 60 + + this.setState({ + timeFromNow: `${hours}:${minutes}:${seconds}`, + }) + }, 1000) } updateQuality = (newQuality) => { @@ -60,10 +150,10 @@ export default class StreamViewer extends React.Component { console.log("Switching to " + protocol) this.loadWithProtocol[protocol]() } - + loadWithProtocol = { hls: () => { - const source = `${this.state.streamSource}.m3u8` + const source = `${streamsSource}/stream/hls/${this.state.streamKey}` const hls = new Hls() hls.loadSource(source) @@ -72,9 +162,13 @@ export default class StreamViewer extends React.Component { this.setState({ protocolInstance: hls, loadedProtocol: "hls" }) }, flv: () => { - const source = `${this.state.streamSource}.flv` + const source = `${streamsSource}/stream/flv/${this.state.streamKey}` - const instance = mpegts.createPlayer({ type: 'flv', url: source, isLive: true }) + const instance = mpegts.createPlayer({ + type: "flv", + url: source, + isLive: true + }) instance.attachMediaElement(this.videoPlayerRef.current) instance.load() @@ -85,15 +179,39 @@ export default class StreamViewer extends React.Component { } render() { - return