mirror of
https://github.com/ragestudio/comty.git
synced 2025-06-11 03:24:16 +00:00
use new loadStream method
This commit is contained in:
parent
924195c107
commit
dba6e0f222
@ -23,14 +23,12 @@ export default class StreamViewer extends React.Component {
|
|||||||
loading: true,
|
loading: true,
|
||||||
cinemaMode: false,
|
cinemaMode: false,
|
||||||
|
|
||||||
streamSources: null,
|
stream: null,
|
||||||
streamInfo: null,
|
|
||||||
spectators: 0,
|
spectators: 0,
|
||||||
|
|
||||||
player: null,
|
player: null,
|
||||||
decoderInstance: null,
|
decoderInstance: null,
|
||||||
|
|
||||||
plyrOptions: {},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
videoPlayerRef = React.createRef()
|
videoPlayerRef = React.createRef()
|
||||||
@ -60,9 +58,12 @@ export default class StreamViewer extends React.Component {
|
|||||||
decoderInstance.on(mpegts.Events.ERROR, this.onSourceEnd)
|
decoderInstance.on(mpegts.Events.ERROR, this.onSourceEnd)
|
||||||
|
|
||||||
decoderInstance.attachMediaElement(this.videoPlayerRef.current)
|
decoderInstance.attachMediaElement(this.videoPlayerRef.current)
|
||||||
|
|
||||||
decoderInstance.load()
|
decoderInstance.load()
|
||||||
|
|
||||||
await decoderInstance.play()
|
await decoderInstance.play().catch((error) => {
|
||||||
|
console.error(error)
|
||||||
|
})
|
||||||
|
|
||||||
this.toggleLoading(false)
|
this.toggleLoading(false)
|
||||||
|
|
||||||
@ -125,54 +126,42 @@ export default class StreamViewer extends React.Component {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
loadStreamInfo = async (username) => {
|
loadStream = async (payload) => {
|
||||||
const streamInfo = await Livestream.getStreamInfo({ username }).catch((error) => {
|
const stream = await Livestream.getLivestream({
|
||||||
|
username: payload.username,
|
||||||
|
profile_id: payload.profile,
|
||||||
|
}).catch((error) => {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
|
|
||||||
return null
|
return null
|
||||||
})
|
})
|
||||||
|
|
||||||
if (!streamInfo) {
|
if (!stream) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("Stream info", streamInfo)
|
console.log("Stream data >", stream)
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
streamInfo: streamInfo,
|
stream: stream,
|
||||||
})
|
spectators: stream.connectedClients,
|
||||||
}
|
|
||||||
|
|
||||||
loadStreamSources = async (username) => {
|
|
||||||
const streamSources = await Livestream.getLivestream({ username }).catch((error) => {
|
|
||||||
console.error(error)
|
|
||||||
|
|
||||||
this.onSourceEnd(error)
|
|
||||||
|
|
||||||
return null
|
|
||||||
})
|
})
|
||||||
|
|
||||||
if (!streamSources) {
|
return stream
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log("Stream sources", streamSources)
|
|
||||||
|
|
||||||
this.setState({
|
|
||||||
streamSources: streamSources,
|
|
||||||
spectators: streamSources.connectedClients,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
attachPlayer = () => {
|
attachPlayer = () => {
|
||||||
|
// check if user has interacted with the page
|
||||||
const player = new Plyr("#player", {
|
const player = new Plyr("#player", {
|
||||||
clickToPlay: false,
|
clickToPlay: false,
|
||||||
autoplay: true,
|
autoplay: true,
|
||||||
|
muted: true,
|
||||||
controls: ["mute", "volume", "fullscreen", "airplay", "options", "settings",],
|
controls: ["mute", "volume", "fullscreen", "airplay", "options", "settings",],
|
||||||
settings: ["quality"],
|
settings: ["quality"],
|
||||||
...this.state.plyrOptions,
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
player.muted = true
|
||||||
|
|
||||||
// insert a button to enter to cinema mode
|
// insert a button to enter to cinema mode
|
||||||
player.elements.buttons.fullscreen.insertAdjacentHTML("beforeBegin", `
|
player.elements.buttons.fullscreen.insertAdjacentHTML("beforeBegin", `
|
||||||
<button class="plyr__controls__item plyr__control" type="button" data-plyr="cinema">
|
<button class="plyr__controls__item plyr__control" type="button" data-plyr="cinema">
|
||||||
@ -202,6 +191,7 @@ export default class StreamViewer extends React.Component {
|
|||||||
this.enterPlayerAnimation()
|
this.enterPlayerAnimation()
|
||||||
|
|
||||||
const requestedUsername = this.props.params.key
|
const requestedUsername = this.props.params.key
|
||||||
|
const profile = this.props.query.profile
|
||||||
|
|
||||||
await this.setState({
|
await this.setState({
|
||||||
requestedUsername,
|
requestedUsername,
|
||||||
@ -210,28 +200,45 @@ export default class StreamViewer extends React.Component {
|
|||||||
this.attachPlayer()
|
this.attachPlayer()
|
||||||
|
|
||||||
// get stream info
|
// get stream info
|
||||||
this.loadStreamInfo(requestedUsername)
|
const stream = await this.loadStream({
|
||||||
await this.loadStreamSources(requestedUsername)
|
username: requestedUsername,
|
||||||
|
profile: profile,
|
||||||
|
})
|
||||||
|
|
||||||
if (this.state.streamSources) {
|
if (!stream) {
|
||||||
if (!this.state.streamSources.sources) {
|
return this.onSourceEnd()
|
||||||
console.error("Stream sources is not defined")
|
}
|
||||||
|
|
||||||
return false
|
// load the flv decoder (by default)
|
||||||
|
if (this.state.stream) {
|
||||||
|
if (!this.state.stream.sources) {
|
||||||
|
console.error("Stream sources not found")
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.loadDecoder("flv", this.state.streamSources.sources.flv)
|
await this.loadDecoder("flv", this.state.stream.sources.flv)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Watch ws to get livestream:started event and load the decoder if it's not loaded
|
// TODO: Watch ws to get livestream:started event and load the decoder if it's not loaded
|
||||||
|
|
||||||
// set a interval to update the stream info
|
// set a interval to update the stream info
|
||||||
this.streamInfoInterval = setInterval(() => {
|
this.streamInfoInterval = setInterval(() => {
|
||||||
this.loadStreamSources(requestedUsername)
|
this.loadStream({
|
||||||
|
username: this.state.requestedUsername,
|
||||||
|
profile: profile,
|
||||||
|
})
|
||||||
}, 1000 * 60)
|
}, 1000 * 60)
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount = () => {
|
componentWillUnmount = () => {
|
||||||
|
if (this.state.player) {
|
||||||
|
this.state.player.destroy()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof this.state.decoderInstance?.unload === "function") {
|
||||||
|
this.state.decoderInstance.unload()
|
||||||
|
}
|
||||||
|
|
||||||
this.exitPlayerAnimation()
|
this.exitPlayerAnimation()
|
||||||
|
|
||||||
if (this.streamInfoInterval) {
|
if (this.streamInfoInterval) {
|
||||||
@ -312,14 +319,14 @@ export default class StreamViewer extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (to) {
|
if (to) {
|
||||||
app.cores.player.start({
|
app.cores.player.start({
|
||||||
src: this.state.streamSources.sources.aac,
|
src: this.state.stream?.sources.aac,
|
||||||
title: this.state.streamInfo.title,
|
title: this.state.stream?.info.title,
|
||||||
artist: this.state.streamInfo.username,
|
artist: this.state.stream?.info.username,
|
||||||
})
|
})
|
||||||
|
|
||||||
// setLocation to main page
|
// setLocation to main page
|
||||||
app.navigation.goMain()
|
app.navigation.goMain()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -335,32 +342,34 @@ export default class StreamViewer extends React.Component {
|
|||||||
<div className="livestream_player">
|
<div className="livestream_player">
|
||||||
<div className="livestream_player_header">
|
<div className="livestream_player_header">
|
||||||
{
|
{
|
||||||
this.state.streamInfo
|
this.state.stream
|
||||||
? <>
|
? <>
|
||||||
<div className="livestream_player_header_user">
|
<div className="livestream_player_header_user">
|
||||||
<UserPreview username={this.state.requestedUsername} />
|
<UserPreview user={this.state.stream.user} />
|
||||||
|
|
||||||
{
|
<div className="livestream_player_indicators">
|
||||||
!this.state.isEnded && <div className="livestream_player_header_user_spectators">
|
{
|
||||||
<antd.Tag
|
!this.state.isEnded && <div className="livestream_player_header_user_spectators">
|
||||||
icon={<Icons.Eye />}
|
<antd.Tag
|
||||||
>
|
icon={<Icons.Eye />}
|
||||||
{this.state.spectators}
|
>
|
||||||
</antd.Tag>
|
{this.state.spectators}
|
||||||
</div>
|
</antd.Tag>
|
||||||
}
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="livestream_player_header_info">
|
<div className="livestream_player_header_info">
|
||||||
<div className="livestream_player_header_info_title">
|
<div className="livestream_player_header_info_title">
|
||||||
<h1>{this.state.streamInfo?.title}</h1>
|
<h1>{this.state.stream.info.title}</h1>
|
||||||
</div>
|
</div>
|
||||||
<div className="livestream_player_header_info_description">
|
<div className="livestream_player_header_info_description">
|
||||||
<Ticker
|
<Ticker
|
||||||
mode="smooth"
|
mode="smooth"
|
||||||
>
|
>
|
||||||
{({ index }) => {
|
{({ index }) => {
|
||||||
return <h4>{this.state.streamInfo?.description}</h4>
|
return <h4>{this.state.stream.info.description}</h4>
|
||||||
}}
|
}}
|
||||||
</Ticker>
|
</Ticker>
|
||||||
</div>
|
</div>
|
||||||
@ -406,7 +415,7 @@ export default class StreamViewer extends React.Component {
|
|||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
<LiveChat
|
<LiveChat
|
||||||
roomId={`livestream:${this.state.requestedUsername}`}
|
roomId={`livestream:${this.state.requestedUsername}:${this.props.query.profile ?? "default"}`}
|
||||||
floatingMode={this.state.cinemaMode}
|
floatingMode={this.state.cinemaMode}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -169,14 +169,36 @@
|
|||||||
|
|
||||||
margin-right: 20px;
|
margin-right: 20px;
|
||||||
|
|
||||||
.livestream_player_header_user_spectators {
|
.livestream_player_indicators {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
|
||||||
|
gap: 10px;
|
||||||
|
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
|
|
||||||
.ant-tag {
|
.livestream_player_header_user_spectators {
|
||||||
background-color: #eb0400;
|
height: fit-content;
|
||||||
border-color: #eb0400;
|
|
||||||
color: var(--background-color-contrast);
|
.ant-tag {
|
||||||
font-size: 1rem;
|
background-color: #eb0400;
|
||||||
|
border-color: #eb0400;
|
||||||
|
color: var(--background-color-contrast);
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.livestream_player_header_user_quality {
|
||||||
|
font-size: 1.8rem;
|
||||||
|
height: fit-content;
|
||||||
|
|
||||||
|
svg {
|
||||||
|
color: var(--text-color);
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user