Skip to content

Commit

Permalink
features, fixes, improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
TheAlan404 committed May 1, 2024
1 parent f190240 commit b0c499a
Show file tree
Hide file tree
Showing 20 changed files with 193 additions and 54 deletions.
7 changes: 5 additions & 2 deletions src/api/context/VideoPlayerProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,14 @@ export const VideoPlayerProvider = ({
let info = await api.getVideoInfo(videoID);
setVideoInfo(info);

console.log("Fetched VideoData", info);

let chapters = parseChapters(info.description);
setActiveChapters({
type: "video",
chapters,
});
console.log("Chapters from description:", chapters);
} catch(e) {
console.log(e);
setError(e);
Expand All @@ -83,7 +86,7 @@ export const VideoPlayerProvider = ({

useEffect(() => {
console.log("Setting URL to", activeFormat?.url);
videoElement.src = activeFormat?.url;
if(videoElement.src != activeFormat?.url) videoElement.src = activeFormat?.url;
}, [activeFormat]);

useVideoEventListener(videoElement, "ended", () => {
Expand All @@ -95,7 +98,7 @@ export const VideoPlayerProvider = ({
});

useVideoEventListener(videoElement, "error", (e) => {
if(!videoElement.src) return;
if(!videoElement.src || videoElement.src.endsWith("/undefined")) return;
setPlayState("error");
console.log(e.error);
console.log(videoElement.error);
Expand Down
34 changes: 33 additions & 1 deletion src/api/platforms/invid/invidious.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,16 @@ export class InvidiousAPIProvider implements APIProvider {
};
}

formatURLProxied(uri: string) {
let url = new URL(uri);
url.host = this.instance.url.split("://")[1];
return url.href;
}

getVideoInfo = async (id: string) => {
let v: InvidiousVideoData = await this.request(`videos/${id}`);

console.log(v);
console.log({ invidiousVideoData: v });

return {
id,
Expand All @@ -74,6 +80,7 @@ export class InvidiousAPIProvider implements APIProvider {
...v.formatStreams.map((f, i) => ({
type: "basic",
id: `basic-${i}`,
isProxied: false,
itag: f.itag,
url: f.url,
mimeType: f.type,
Expand All @@ -85,12 +92,37 @@ export class InvidiousAPIProvider implements APIProvider {
...v.adaptiveFormats.map((f, i) => ({
type: "adaptive",
id: `adaptive-${i}`,
isProxied: false,
itag: f.itag,
url: f.url,
mimeType: f.type,
fps: f.fps,
bitrate: Number(f.bitrate),
} as VideoFormat)),
...(this.instance.supportsProxy ? [
...v.formatStreams.map((f, i) => ({
type: "basic",
id: `basic-${i}-proxy`,
itag: f.itag,
url: this.formatURLProxied(f.url),
isProxied: true,
mimeType: f.type,
fps: f.fps,
width: Number(f.size.split("x")[0]),
height: Number(f.size.split("x")[1]),
bitrate: Number(f.bitrate),
} as VideoFormat)),
...v.adaptiveFormats.map((f, i) => ({
type: "adaptive",
id: `adaptive-${i}-proxy`,
itag: f.itag,
url: this.formatURLProxied(f.url),
isProxied: true,
mimeType: f.type,
fps: f.fps,
bitrate: Number(f.bitrate),
} as VideoFormat)),
] : []),
],
} as VideoData;
};
Expand Down
4 changes: 4 additions & 0 deletions src/api/platforms/lt/lighttube.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,24 +92,28 @@ export class LTAPIProvider implements APIProvider {
...f,
type: "basic",
id: `basic-${i}`,
isProxied: false,
} as VideoFormat)),
...ltPlayer.adaptiveFormats.map((f, i) => ({
...f,
type: "adaptive",
id: `adaptive-${i}`,
isProxied: false,
} as VideoFormat)),

...ltPlayer.formats.map((f, i) => ({
...f,
type: "basic",
id: `proxy-basic-${i}`,
url: `${this.instance.url}/proxy/media/${id}/${f.itag}`,
isProxied: true,
} as VideoFormat)),
...ltPlayer.adaptiveFormats.map((f, i) => ({
...f,
type: "adaptive",
id: `proxy-adaptive-${i}`,
url: `${this.instance.url}/proxy/media/${id}/${f.itag}`,
isProxied: true,
} as VideoFormat)),
],
};
Expand Down
37 changes: 37 additions & 0 deletions src/api/platforms/public.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export const fetchLightTubePublicInstances = async () => {
name: i.host,
url: `${i.scheme}://${i.host}`,
region: i.country,
supportsProxy: i.proxyEnabled == "all",
notes: (i.isCloudflare ? "cloudflare" : ""),
} as Instance));
};
Expand Down Expand Up @@ -55,5 +56,41 @@ export const fetchInvidiousPublicInstances = async () => {
url: i.uri,
name,
region: i.region,
supportsProxy: true,
} as Instance));
};

// --- poketube ---

const POKETUBE_PUBLIC_INSTANCES = "https://poketube.fun/api/instances.json";

interface PublicPoketubeInstanceDetails {
uri: string;
CLOUDFLARE: boolean;
piwik: boolean;
proxy: boolean;
official: boolean;
DEFAULT: boolean;
region: string;
software: {
name: string;
version: string;
branch: string;
},
}

type PublicPoketubeInstance = [string, PublicPoketubeInstanceDetails];

export const fetchPoketubePublicInstances = async () => {
const res = await fetch(POKETUBE_PUBLIC_INSTANCES);
const li: PublicPoketubeInstance[] = await res.json();

return li
.map(([name, i]) => ({
type: "poketube",
url: i.uri,
name,
supportsProxy: i.proxy,
notes: i.CLOUDFLARE ? "cloudflare" : "",
} as Instance));
};
1 change: 1 addition & 0 deletions src/api/types/format.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export type VideoFormatType = "basic" | "adaptive" | "dash" | "hls";
export interface VideoFormat {
type: VideoFormatType;
id: string;
isProxied: boolean;

itag: string;
url: string;
Expand Down
20 changes: 12 additions & 8 deletions src/api/types/instances.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
export interface LTInstance {
type: "lighttube";
export interface BaseInstance {
name: string;
url: string;
notes?: string;
region?: string;
supportsProxy?: boolean;
};

export interface InvidiousInstance {
export interface LTInstance extends BaseInstance {
type: "lighttube";
};

export interface InvidiousInstance extends BaseInstance {
type: "invidious";
name: string;
url: string;
notes?: string;
region?: string;
};

export type Instance = LTInstance | InvidiousInstance;
export interface PoketubeInstance extends BaseInstance {
type: "poketube";
};

export type Instance = LTInstance | InvidiousInstance | PoketubeInstance;
56 changes: 29 additions & 27 deletions src/components/cards/InstanceCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,35 +48,37 @@ export const InstanceCard = ({
<Text c="dimmed" fz="sm">
{instance.url}
</Text>
{withControls && (
<Tooltip
label={fav ? "Remove from favourites" : "Add to favourites"}
position="left"
withArrow
>
<ActionIcon
variant="subtle"
color="gray"
onClick={(e) => {
e.stopPropagation();
if (fav)
removeFavourite(instance);
else
addFavourite(instance);
}}
<Group>
<Text fs="xs" c="dimmed">
{instance.region}
</Text>
{withControls && (
<Tooltip
label={fav ? "Remove from favourites" : "Add to favourites"}
position="left"
withArrow
>
{fav ? (
<IconStarFilled color="var(--mantine-color-yellow-filled)" />
) : (
<IconStar />
)}
</ActionIcon>
</Tooltip>
)}
<ActionIcon
variant="subtle"
color="gray"
onClick={(e) => {
e.stopPropagation();
if (fav)
removeFavourite(instance);
else
addFavourite(instance);
}}
>
{fav ? (
<IconStarFilled color="var(--mantine-color-yellow-filled)" />
) : (
<IconStar />
)}
</ActionIcon>
</Tooltip>
)}
</Group>
</Group>
<Text fs="xs" c="dimmed">
{instance.notes}
</Text>
</Stack>
</Grid.Col>
</Grid>
Expand Down
2 changes: 1 addition & 1 deletion src/components/options/OptionsContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { useSoundEffect } from "../../hooks/useSoundEffect";
import { Drawer, ScrollArea } from "@mantine/core";
import { OptionsRouter } from "./OptionsRouter";

export type OptionsView = "main" | "instanceSelect";
export type OptionsView = "main" | "instanceSelect" | "openWith" | "formatSelect";

export interface OptionsContextAPI {
opened: boolean;
Expand Down
2 changes: 2 additions & 0 deletions src/components/options/OptionsRouter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { useContext } from "react";
import { OptionsContext } from "./OptionsContext";
import { OptionsMainView } from "./views/MainView";
import { OptionsInstanceView } from "./views/InstanceView";
import { OptionsOpenWithView } from "./views/OpenWith";

export const OptionsRouter = () => {
const { view } = useContext(OptionsContext);
Expand All @@ -11,6 +12,7 @@ export const OptionsRouter = () => {
<Stack align="center" w="100%" h="100%">
{view == "main" && <OptionsMainView />}
{view == "instanceSelect" && <OptionsInstanceView />}
{view == "openWith" && <OptionsOpenWithView />}
</Stack>
);
};
13 changes: 7 additions & 6 deletions src/components/options/comps/FormatSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,16 @@ export const FormatSelect = () => {
w="100%"
label={"Format"}
value={activeFormat.itag}
onChange={(v) => setFormat(availableFormats[Number(v)]!)}
data={availableFormats.map((f, i) => i.toString())}
renderOption={({ option: { value: i }, checked }) => (
onChange={(v) => setFormat(v)}
data={availableFormats.map((f, i) => f.id)}
renderOption={({ option: { value }, checked }) => (
<Group justify="space-between">
<Group>
<Stack>
{availableFormats[Number(i)].itag}
{availableFormats[Number(i)].mimeType}
{availableFormats[Number(i)].fps}
{availableFormats.find(x => x.id == value).id}
{availableFormats.find(x => x.id == value).itag}
{availableFormats.find(x => x.id == value).mimeType}
{availableFormats.find(x => x.id == value).fps}
</Stack>
</Group>
<Group>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Button } from "@mantine/core";
import { IconSettings } from "@tabler/icons-react";
import { useContext } from "react";
import { OptionsContext } from "./OptionsContext";
import { OptionsContext } from "../OptionsContext";

export const ChangeInstanceButton = () => {
const { open, setView } = useContext(OptionsContext);
Expand Down
24 changes: 24 additions & 0 deletions src/components/options/links/OpenWithButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Button, ButtonProps } from "@mantine/core";
import { IconExternalLink } from "@tabler/icons-react";
import { useContext } from "react";
import { OptionsContext } from "../OptionsContext";

export const OpenWithButton = (props: ButtonProps) => {
const { open, setView } = useContext(OptionsContext);

return (
<Button
color="violet"
variant="light"
rightSection={<IconExternalLink />}
onClick={() => {
open();
setView("openWith");
}}
size="compact-md"
{...props}
>
Open With
</Button>
);
};
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ActionIcon, Tooltip } from "@mantine/core";
import { IconSettings } from "@tabler/icons-react";
import { useContext } from "react";
import { OptionsContext } from "./OptionsContext";
import { OptionsContext } from "../OptionsContext";

export const OptionsButton = () => {
const { toggle } = useContext(OptionsContext);
Expand Down
6 changes: 4 additions & 2 deletions src/components/options/views/MainView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,20 @@ import { FormatSelect } from "../comps/FormatSelect";
import { PlaybackSpeed } from "../comps/PlaybackSpeed";
import { PreferencesList } from "../comps/PreferencesList";
import { RefetchInfo } from "../comps/RefetchInfo";
import { OpenWithButton } from "../links/OpenWithButton";

export const OptionsMainView = () => {
const { playState } = useContext(VideoPlayerContext);
const { videoInfo } = useContext(VideoPlayerContext);

const loaded = playState !== "error" && playState !== "loading";
const loaded = !!videoInfo;

return (
<Grid w="100%">
<Grid.Col span="auto">
<Stack align="center" w="100%">
<Divider w="100%" label="Instance" labelPosition="left" />
<InstanceSelect />
<OpenWithButton fullWidth />
<Divider w="100%" label="Video" labelPosition="left" />
{!loaded && (
<Text>Video not loaded</Text>
Expand Down
Loading

0 comments on commit b0c499a

Please sign in to comment.