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 airplay and casting

Pas 6f67a7c7 c0029577

+50 -14
+4 -1
src/components/player/atoms/Airplay.tsx
··· 1 1 import { Icons } from "@/components/Icon"; 2 2 import { VideoPlayerButton } from "@/components/player/internals/Button"; 3 3 import { usePlayerStore } from "@/stores/player/store"; 4 + import { isSafari } from "@/utils/detectFeatures"; 4 5 5 6 export function Airplay() { 6 7 const canAirplay = usePlayerStore((s) => s.interface.canAirplay); 7 8 const display = usePlayerStore((s) => s.display); 8 9 9 - if (!canAirplay) return null; 10 + // Show Airplay button on Safari browsers (which support AirPlay natively) 11 + // or when the webkit event has confirmed availability 12 + if (!canAirplay && !isSafari) return null; 10 13 11 14 return ( 12 15 <VideoPlayerButton
+2
src/components/player/atoms/Chromecast.tsx
··· 38 38 const context = castFramework.CastContext.getInstance(); 39 39 const updateVisibility = () => { 40 40 const state = context.getCastState(); 41 + // Hide only if we know for sure there are no devices available 42 + // Show the button for other states (NOT_CONNECTED, CONNECTING, CONNECTED) 41 43 setCastHidden(state === castFramework.CastState.NO_DEVICES_AVAILABLE); 42 44 }; 43 45
+44 -13
src/components/player/display/base.ts
··· 784 784 proxiedUrl = source.url; // Already proxied or no headers needed 785 785 } 786 786 } else if (source?.type === "mp4") { 787 - // TODO: Implement MP4 proxy for protected streams 788 - const hasHeaders = 789 - source.headers && Object.keys(source.headers).length > 0; 790 - if (hasHeaders) { 787 + const allHeaders = { 788 + ...source.preferredHeaders, 789 + ...source.headers, 790 + }; 791 + const hasHeaders = Object.keys(allHeaders).length > 0; 792 + if (!isUrlAlreadyProxied(source.url) && hasHeaders) { 791 793 // Use MP4 proxy for streams with headers 792 - proxiedUrl = createMP4ProxyUrl(source.url, source.headers || {}); 794 + proxiedUrl = createMP4ProxyUrl(source.url, allHeaders); 793 795 } else { 794 796 proxiedUrl = source.url; 795 797 } 796 798 } 797 799 800 + // Function to restore original URL 801 + const restoreOriginalUrl = () => { 802 + if (source?.type === "hls") { 803 + if (hls && originalUrl) { 804 + hls.loadSource(originalUrl); 805 + } 806 + } else if (originalUrl) { 807 + videoPlayer.src = originalUrl; 808 + } 809 + }; 810 + 811 + // Function to check airplay state and restore if needed 812 + const checkAirplayState = () => { 813 + const isWireless = videoPlayer.webkitCurrentPlaybackTargetIsWireless; 814 + if (!isWireless) { 815 + // Airplay didn't start or ended, restore original URL 816 + restoreOriginalUrl(); 817 + } 818 + }; 819 + 798 820 if (proxiedUrl && proxiedUrl !== originalUrl) { 799 - // Temporarily set the proxied URL for Airplay 821 + // Set the proxied URL for Airplay 800 822 if (source?.type === "hls") { 801 823 if (hls) { 802 824 hls.loadSource(proxiedUrl); ··· 809 831 setTimeout(() => { 810 832 videoPlayer.webkitShowPlaybackTargetPicker(); 811 833 812 - // Restore original URL after a short delay 834 + // Check airplay state after user interaction 835 + // Give user time to select device, then check if airplay started 813 836 setTimeout(() => { 814 - if (source?.type === "hls") { 815 - if (hls && originalUrl) { 816 - hls.loadSource(originalUrl); 817 - } 818 - } else if (originalUrl) { 819 - videoPlayer.src = originalUrl; 837 + checkAirplayState(); 838 + }, 2000); 839 + 840 + // Set up periodic check for airplay state changes 841 + const airplayCheckInterval = setInterval(() => { 842 + const isWireless = 843 + videoPlayer.webkitCurrentPlaybackTargetIsWireless; 844 + if (!isWireless) { 845 + // Airplay ended, restore original URL 846 + restoreOriginalUrl(); 847 + clearInterval(airplayCheckInterval); 820 848 } 821 849 }, 1000); 850 + 851 + // Clear interval after 5 minutes as safety measure 852 + setTimeout(() => clearInterval(airplayCheckInterval), 300000); 822 853 }, 100); 823 854 } else { 824 855 // No proxying needed, just trigger Airplay