mirror of
https://github.com/ragestudio/comty.git
synced 2025-06-11 03:24:16 +00:00
improve live player
This commit is contained in:
parent
1571aa09b9
commit
96f30d454a
@ -8,6 +8,7 @@ import { Icons } from "components/Icons"
|
|||||||
|
|
||||||
import Plyr from "plyr"
|
import Plyr from "plyr"
|
||||||
import Hls from "hls.js"
|
import Hls from "hls.js"
|
||||||
|
import mpegts from "mpegts.js"
|
||||||
|
|
||||||
import "plyr/dist/plyr.css"
|
import "plyr/dist/plyr.css"
|
||||||
import "./index.less"
|
import "./index.less"
|
||||||
@ -21,8 +22,8 @@ export default class StreamViewer extends React.Component {
|
|||||||
spectators: 0,
|
spectators: 0,
|
||||||
|
|
||||||
player: null,
|
player: null,
|
||||||
loadedDecoder: "hls",
|
|
||||||
decoderInstance: null,
|
decoderInstance: null,
|
||||||
|
|
||||||
plyrOptions: {},
|
plyrOptions: {},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,13 +36,29 @@ export default class StreamViewer extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
attachDecoder = {
|
attachDecoder = {
|
||||||
hls: (source) => {
|
flv: (source) => {
|
||||||
if (!source) {
|
if (!source) {
|
||||||
console.error("Stream source is not defined")
|
console.error("Stream source is not defined")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
this.toogleSourceLoading(true)
|
const decoderInstance = mpegts.createPlayer({
|
||||||
|
type: "flv",
|
||||||
|
isLive: true,
|
||||||
|
url: source
|
||||||
|
})
|
||||||
|
|
||||||
|
decoderInstance.attachMediaElement(this.videoPlayerRef.current)
|
||||||
|
decoderInstance.load()
|
||||||
|
decoderInstance.play()
|
||||||
|
|
||||||
|
return decoderInstance
|
||||||
|
},
|
||||||
|
hls: (source) => {
|
||||||
|
if (!source) {
|
||||||
|
console.error("Stream source is not defined")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
const hlsInstance = new Hls({
|
const hlsInstance = new Hls({
|
||||||
autoStartLoad: true,
|
autoStartLoad: true,
|
||||||
@ -54,15 +71,10 @@ export default class StreamViewer extends React.Component {
|
|||||||
|
|
||||||
hlsInstance.on(Hls.Events.MANIFEST_PARSED, (event, data) => {
|
hlsInstance.on(Hls.Events.MANIFEST_PARSED, (event, data) => {
|
||||||
console.log(`${data.levels.length} quality levels found`)
|
console.log(`${data.levels.length} quality levels found`)
|
||||||
|
|
||||||
this.toogleSourceLoading(false)
|
|
||||||
|
|
||||||
// try auto play
|
|
||||||
this.videoPlayerRef.current.play()
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
hlsInstance.on(Hls.Events.ERROR, function (event, data) {
|
hlsInstance.on(Hls.Events.ERROR, (event, data) => {
|
||||||
console.error(event, data)
|
console.error(event, data)
|
||||||
|
|
||||||
switch (data.details) {
|
switch (data.details) {
|
||||||
@ -81,7 +93,7 @@ export default class StreamViewer extends React.Component {
|
|||||||
hlsInstance.on(event, this.playerDecoderEvents[event])
|
hlsInstance.on(event, this.playerDecoderEvents[event])
|
||||||
})
|
})
|
||||||
|
|
||||||
this.setState({ decoderInstance: hlsInstance, loadedDecoder: "hls" })
|
return hlsInstance
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,6 +104,8 @@ export default class StreamViewer extends React.Component {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log("Stream info", streamInfo)
|
||||||
|
|
||||||
this.setState({ streamInfo: streamInfo })
|
this.setState({ streamInfo: streamInfo })
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,18 +115,20 @@ export default class StreamViewer extends React.Component {
|
|||||||
// get stream info
|
// get stream info
|
||||||
await this.loadStreamInfo(requestedUsername)
|
await this.loadStreamInfo(requestedUsername)
|
||||||
|
|
||||||
console.log("Stream info", this.state.streamInfo)
|
|
||||||
|
|
||||||
if (this.state.streamInfo) {
|
if (this.state.streamInfo) {
|
||||||
if (!this.state.streamInfo.sources) {
|
if (!this.state.streamInfo.sources) {
|
||||||
|
console.error("Stream sources is not defined")
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
this.enterPlayerAnimation()
|
this.enterPlayerAnimation()
|
||||||
|
|
||||||
const player = new Plyr("#player", {
|
const player = new Plyr("#player", {
|
||||||
|
clickToPlay: false,
|
||||||
autoplay: true,
|
autoplay: true,
|
||||||
controls: ["play", "mute", "volume", "fullscreen", "options", "settings"],
|
controls: ["mute", "volume", "fullscreen", "airplay", "options", "settings",],
|
||||||
|
settings: ["quality"],
|
||||||
...this.state.plyrOptions,
|
...this.state.plyrOptions,
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -120,7 +136,7 @@ export default class StreamViewer extends React.Component {
|
|||||||
player,
|
player,
|
||||||
})
|
})
|
||||||
|
|
||||||
await this.loadDecoder("hls", this.state.streamInfo.sources.hls)
|
await this.loadDecoder("flv", this.state.streamInfo.sources.flv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,30 +149,26 @@ export default class StreamViewer extends React.Component {
|
|||||||
app.style.applyVariant("dark")
|
app.style.applyVariant("dark")
|
||||||
|
|
||||||
app.eventBus.emit("style.compactMode", true)
|
app.eventBus.emit("style.compactMode", true)
|
||||||
|
|
||||||
app.SidebarController.toggleVisibility(false)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
exitPlayerAnimation = () => {
|
exitPlayerAnimation = () => {
|
||||||
app.style.applyVariant(app.settings.get("themeVariant"))
|
app.style.applyVariant(app.settings.get("themeVariant"))
|
||||||
|
|
||||||
app.eventBus.emit("style.compactMode", false)
|
app.eventBus.emit("style.compactMode", false)
|
||||||
|
|
||||||
app.SidebarController.toggleVisibility(true)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
updateQuality = (newQuality) => {
|
updateQuality = (newQuality) => {
|
||||||
if (loadedProtocol === "hls") {
|
if (this.state.loadedProtocol !== "hls") {
|
||||||
this.state.protocolInstance.levels.forEach((level, levelIndex) => {
|
|
||||||
if (level.height === newQuality) {
|
|
||||||
console.log("Found quality match with " + newQuality)
|
|
||||||
this.state.protocolInstance.currentLevel = levelIndex
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
console.error("Unsupported protocol")
|
console.error("Unsupported protocol")
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.state.protocolInstance.levels.forEach((level, levelIndex) => {
|
||||||
|
if (level.height === newQuality) {
|
||||||
|
console.log("Found quality match with " + newQuality)
|
||||||
|
this.state.protocolInstance.currentLevel = levelIndex
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
loadDecoder = async (decoder, ...args) => {
|
loadDecoder = async (decoder, ...args) => {
|
||||||
@ -174,9 +186,19 @@ export default class StreamViewer extends React.Component {
|
|||||||
this.setState({ decoderInstance: null })
|
this.setState({ decoderInstance: null })
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("Switching to " + decoder)
|
this.toogleSourceLoading(true)
|
||||||
|
|
||||||
return await this.attachDecoder[decoder](...args)
|
console.log(`Switching decoder to: ${decoder}`)
|
||||||
|
|
||||||
|
const decoderInstance = await this.attachDecoder[decoder](...args)
|
||||||
|
|
||||||
|
await this.setState({
|
||||||
|
decoderInstance: decoderInstance
|
||||||
|
})
|
||||||
|
|
||||||
|
this.toogleSourceLoading(false)
|
||||||
|
|
||||||
|
return decoderInstance
|
||||||
}
|
}
|
||||||
|
|
||||||
toogleSourceLoading = (to) => {
|
toogleSourceLoading = (to) => {
|
||||||
|
@ -42,7 +42,10 @@
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
width: 20vw;
|
|
||||||
|
width: 100%;
|
||||||
|
min-width: 400px;
|
||||||
|
max-width: 500px;
|
||||||
|
|
||||||
.info {
|
.info {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user