Browse Source

airplay button

Co-authored-by: Jip Frijlink <JipFr@users.noreply.github.com>
pull/497/head
mrjvs 2 years ago
parent
commit
f6bbec8907
  1. 17
      src/components/player/atoms/Airplay.tsx
  2. 1
      src/components/player/atoms/index.ts
  3. 14
      src/components/player/display/base.ts
  4. 2
      src/components/player/display/displayInterface.ts
  5. 1
      src/pages/parts/player/PlayerPart.tsx
  6. 5
      src/stores/player/slices/display.ts
  7. 2
      src/stores/player/slices/interface.ts

17
src/components/player/atoms/Airplay.tsx

@ -0,0 +1,17 @@ @@ -0,0 +1,17 @@
import { Icons } from "@/components/Icon";
import { VideoPlayerButton } from "@/components/player/internals/Button";
import { usePlayerStore } from "@/stores/player/store";
export function Airplay() {
const canAirplay = usePlayerStore((s) => s.interface.canAirplay);
const display = usePlayerStore((s) => s.display);
if (!canAirplay) return null;
return (
<VideoPlayerButton
onClick={() => display?.startAirplay()}
icon={Icons.AIRPLAY}
/>
);
}

1
src/components/player/atoms/index.ts

@ -10,3 +10,4 @@ export * from "./Title"; @@ -10,3 +10,4 @@ export * from "./Title";
export * from "./EpisodeTitle";
export * from "./Settings";
export * from "./Episodes";
export * from "./Airplay";

14
src/components/player/display/base.ts

@ -85,6 +85,14 @@ export function makeVideoElementDisplayInterface(): DisplayInterface { @@ -85,6 +85,14 @@ export function makeVideoElementDisplayInterface(): DisplayInterface {
emit("fullscreen", isFullscreen);
if (!isFullscreen) emit("needstrack", false);
});
videoElement.addEventListener(
"webkitplaybacktargetavailabilitychanged",
(e: any) => {
if (e.availability === "available") {
emit("canairplay", true);
}
}
);
}
function unloadSource() {
@ -206,5 +214,11 @@ export function makeVideoElementDisplayInterface(): DisplayInterface { @@ -206,5 +214,11 @@ export function makeVideoElementDisplayInterface(): DisplayInterface {
}
}
},
startAirplay() {
const videoPlayer = videoElement as any;
if (videoPlayer && videoPlayer.webkitShowPlaybackTargetPicker) {
videoPlayer.webkitShowPlaybackTargetPicker();
}
},
};
}

2
src/components/player/display/displayInterface.ts

@ -13,6 +13,7 @@ export type DisplayInterfaceEvents = { @@ -13,6 +13,7 @@ export type DisplayInterfaceEvents = {
qualities: SourceQuality[];
changedquality: SourceQuality | null;
needstrack: boolean;
canairplay: boolean;
};
export interface DisplayInterface extends Listener<DisplayInterfaceEvents> {
@ -26,4 +27,5 @@ export interface DisplayInterface extends Listener<DisplayInterfaceEvents> { @@ -26,4 +27,5 @@ export interface DisplayInterface extends Listener<DisplayInterfaceEvents> {
setVolume(vol: number): void;
setTime(t: number): void;
destroy(): void;
startAirplay(): void;
}

1
src/pages/parts/player/PlayerPart.tsx

@ -72,6 +72,7 @@ export function PlayerPart(props: PlayerPartProps) { @@ -72,6 +72,7 @@ export function PlayerPart(props: PlayerPartProps) {
</Player.LeftSideControls>
<div className="flex items-center space-x-3">
<Player.Episodes onChange={props.onMetaChange} />
<Player.Airplay />
<Player.Settings />
<Player.Fullscreen />
</div>

5
src/stores/player/slices/display.ts

@ -80,6 +80,11 @@ export const createDisplaySlice: MakeSlice<DisplaySlice> = (set, get) => ({ @@ -80,6 +80,11 @@ export const createDisplaySlice: MakeSlice<DisplaySlice> = (set, get) => ({
s.caption.asTrack = needsTrack;
});
});
newDisplay.on("canairplay", (canAirplay) => {
set((s) => {
s.interface.canAirplay = canAirplay;
});
});
set((s) => {
s.display = newDisplay;

2
src/stores/player/slices/interface.ts

@ -19,6 +19,7 @@ export interface InterfaceSlice { @@ -19,6 +19,7 @@ export interface InterfaceSlice {
hasOpenOverlay: boolean;
hovering: PlayerHoverState;
lastHoveringState: PlayerHoverState;
canAirplay: boolean;
volumeChangedWithKeybind: boolean; // has the volume recently been adjusted with the up/down arrows recently?
volumeChangedWithKeybindDebounce: NodeJS.Timeout | null; // debounce for the duration of the "volume changed thingamajig"
@ -46,6 +47,7 @@ export const createInterfaceSlice: MakeSlice<InterfaceSlice> = (set, get) => ({ @@ -46,6 +47,7 @@ export const createInterfaceSlice: MakeSlice<InterfaceSlice> = (set, get) => ({
volumeChangedWithKeybind: false,
volumeChangedWithKeybindDebounce: null,
timeFormat: VideoPlayerTimeFormat.REGULAR,
canAirplay: false,
},
setLastVolume(state) {

Loading…
Cancel
Save