pstream is dead; long live pstream taciturnaxolotl.github.io/pstream-ng/
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

update chromecasting logic

Pas 51e30c97 9b02bf79

+36 -2
+17 -1
src/components/player/atoms/Airplay.tsx
··· 6 6 export function Airplay() { 7 7 const canAirplay = usePlayerStore((s) => s.interface.canAirplay); 8 8 const display = usePlayerStore((s) => s.display); 9 + const source = usePlayerStore((s) => s.source); 10 + 11 + // Check if source is supported for casting 12 + // HLS is always supported (proxied if needed) 13 + // MP4/File is only supported if it doesn't need headers (no proxy available) 14 + const isCastable = (() => { 15 + if (!source) return false; 16 + if (source.type === "hls") return true; 17 + if (source.type === "file") { 18 + const hasHeaders = 19 + Object.keys(source.headers || {}).length > 0 || 20 + Object.keys(source.preferredHeaders || {}).length > 0; 21 + return !hasHeaders; 22 + } 23 + return true; // Unknown types assumed castable 24 + })(); 9 25 10 26 // Show Airplay button on Safari browsers (which support AirPlay natively) 11 27 // or when the webkit event has confirmed availability 12 - if (!canAirplay && !isSafari) return null; 28 + if ((!canAirplay && !isSafari) || !isCastable) return null; 13 29 14 30 return ( 15 31 <VideoPlayerButton
+17 -1
src/components/player/atoms/Chromecast.tsx
··· 23 23 export function Chromecast({ className }: ChromecastProps) { 24 24 const [castHidden, setCastHidden] = useState(false); 25 25 const isCasting = usePlayerStore((s) => s.interface.isCasting); 26 + const source = usePlayerStore((s) => s.source); 26 27 const launcherRef = useRef<HTMLDivElement>(null); 28 + 29 + // Check if source is supported for casting 30 + // HLS is always supported (proxied if needed) 31 + // MP4/File is only supported if it doesn't need headers (no proxy available) 32 + const isCastable = (() => { 33 + if (!source) return false; 34 + if (source.type === "hls") return true; 35 + if (source.type === "file") { 36 + const hasHeaders = 37 + Object.keys(source.headers || {}).length > 0 || 38 + Object.keys(source.preferredHeaders || {}).length > 0; 39 + return !hasHeaders; 40 + } 41 + return true; // Unknown types assumed castable 42 + })(); 27 43 28 44 useEffect(() => { 29 45 const w = window as unknown as { cast?: typeof cast }; ··· 72 88 "google-cast-button", 73 89 "cast-button-container", 74 90 isCasting ? "casting" : "", 75 - castHidden ? "hidden" : "", 91 + castHidden || !isCastable ? "hidden" : "", 76 92 ].join(" ")} 77 93 > 78 94 <div ref={launcherRef} />
+2
src/components/player/display/base.ts
··· 834 834 if (source?.type === "hls") { 835 835 if (hls) { 836 836 hls.loadSource(proxiedUrl); 837 + } else { 838 + videoPlayer.src = proxiedUrl; 837 839 } 838 840 } else { 839 841 videoPlayer.src = proxiedUrl;