mirror of
https://github.com/linsa-io/linsa.git
synced 2026-01-12 12:20:23 +01:00
Improve HLS live detection and state management in StreamPage component
- Add `hlsLive` state to track if HLS playlist is live - Implement `isHlsPlaylistLive` function to determine playlist status - Reset `hlsLive` before fetching new manifest - Update fetch logic to set `hlsLive` based on playlist analysis - Refine live status checks to consider HLS playlist state - Adjust rendering conditions to use `isActuallyLive` for consistency
This commit is contained in:
@@ -50,6 +50,7 @@ function StreamPage() {
|
|||||||
const [error, setError] = useState<string | null>(null)
|
const [error, setError] = useState<string | null>(null)
|
||||||
const [streamReady, setStreamReady] = useState(false)
|
const [streamReady, setStreamReady] = useState(false)
|
||||||
const [webRtcFailed, setWebRtcFailed] = useState(false)
|
const [webRtcFailed, setWebRtcFailed] = useState(false)
|
||||||
|
const [hlsLive, setHlsLive] = useState<boolean | null>(null)
|
||||||
const [nowPlaying, setNowPlaying] = useState<SpotifyNowPlayingResponse | null>(
|
const [nowPlaying, setNowPlaying] = useState<SpotifyNowPlayingResponse | null>(
|
||||||
null,
|
null,
|
||||||
)
|
)
|
||||||
@@ -127,6 +128,15 @@ function StreamPage() {
|
|||||||
? fallbackPlayback ?? playback
|
? fallbackPlayback ?? playback
|
||||||
: playback
|
: playback
|
||||||
|
|
||||||
|
const isHlsPlaylistLive = (manifest: string) => {
|
||||||
|
const upper = manifest.toUpperCase()
|
||||||
|
const hasEndlist = upper.includes("#EXT-X-ENDLIST")
|
||||||
|
const isVod = upper.includes("#EXT-X-PLAYLIST-TYPE:VOD")
|
||||||
|
const hasSegments =
|
||||||
|
upper.includes("#EXTINF") || upper.includes("#EXT-X-PART")
|
||||||
|
return !hasEndlist && !isVod && hasSegments
|
||||||
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let isActive = true
|
let isActive = true
|
||||||
if (!activePlayback || activePlayback.type !== "hls") {
|
if (!activePlayback || activePlayback.type !== "hls") {
|
||||||
@@ -136,15 +146,26 @@ function StreamPage() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setStreamReady(false)
|
setStreamReady(false)
|
||||||
|
setHlsLive(null)
|
||||||
fetch(activePlayback.url)
|
fetch(activePlayback.url)
|
||||||
.then((res) => {
|
.then(async (res) => {
|
||||||
if (isActive) {
|
if (isActive) {
|
||||||
setStreamReady(res.ok)
|
if (!res.ok) {
|
||||||
|
setStreamReady(false)
|
||||||
|
setHlsLive(false)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const manifest = await res.text()
|
||||||
|
if (!isActive) return
|
||||||
|
const live = isHlsPlaylistLive(manifest)
|
||||||
|
setStreamReady(live)
|
||||||
|
setHlsLive(live)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
if (isActive) {
|
if (isActive) {
|
||||||
setStreamReady(false)
|
setStreamReady(false)
|
||||||
|
setHlsLive(false)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -156,7 +177,41 @@ function StreamPage() {
|
|||||||
activePlayback?.type === "hls" ? activePlayback.url : null,
|
activePlayback?.type === "hls" ? activePlayback.url : null,
|
||||||
])
|
])
|
||||||
|
|
||||||
const shouldFetchSpotify = username === "nikiv" && !stream?.is_live
|
useEffect(() => {
|
||||||
|
let isActive = true
|
||||||
|
if (!stream?.hls_url || activePlayback?.type === "hls") {
|
||||||
|
return () => {
|
||||||
|
isActive = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setHlsLive(null)
|
||||||
|
fetch(stream.hls_url)
|
||||||
|
.then(async (res) => {
|
||||||
|
if (!isActive) return
|
||||||
|
if (!res.ok) {
|
||||||
|
setHlsLive(false)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const manifest = await res.text()
|
||||||
|
if (!isActive) return
|
||||||
|
setHlsLive(isHlsPlaylistLive(manifest))
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
if (isActive) {
|
||||||
|
setHlsLive(false)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
isActive = false
|
||||||
|
}
|
||||||
|
}, [activePlayback?.type, stream?.hls_url])
|
||||||
|
|
||||||
|
const isActuallyLive =
|
||||||
|
Boolean(stream?.is_live) &&
|
||||||
|
(activePlayback?.type !== "hls" || hlsLive !== false)
|
||||||
|
const shouldFetchSpotify = username === "nikiv" && !isActuallyLive
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!shouldFetchSpotify) {
|
if (!shouldFetchSpotify) {
|
||||||
@@ -251,7 +306,7 @@ function StreamPage() {
|
|||||||
<ViewerCount username={username} />
|
<ViewerCount username={username} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{stream?.is_live && activePlayback && showPlayer ? (
|
{isActuallyLive && activePlayback && showPlayer ? (
|
||||||
activePlayback.type === "webrtc" ? (
|
activePlayback.type === "webrtc" ? (
|
||||||
<div className="relative h-full w-full">
|
<div className="relative h-full w-full">
|
||||||
<WebRTCPlayer
|
<WebRTCPlayer
|
||||||
@@ -296,7 +351,7 @@ function StreamPage() {
|
|||||||
) : (
|
) : (
|
||||||
<VideoPlayer src={activePlayback.url} muted={false} />
|
<VideoPlayer src={activePlayback.url} muted={false} />
|
||||||
)
|
)
|
||||||
) : stream?.is_live && activePlayback ? (
|
) : isActuallyLive && activePlayback ? (
|
||||||
<div className="flex h-full w-full items-center justify-center text-white">
|
<div className="flex h-full w-full items-center justify-center text-white">
|
||||||
<div className="text-center">
|
<div className="text-center">
|
||||||
<div className="animate-pulse text-4xl">🔴</div>
|
<div className="animate-pulse text-4xl">🔴</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user