This commit is contained in:
kieran 2024-05-28 15:30:32 +01:00
parent c32c230227
commit 0c07258e58
Signed by: Kieran
GPG Key ID: DE71CEB3925BE941
3 changed files with 77 additions and 1 deletions

View File

@ -14,6 +14,7 @@ import { RelativeTime } from "../relative-time";
import { VideoInfo } from "@/service/video/info";
import { VideoDuration } from "./duration";
import { getName } from "../profile";
import { useDeadLink } from "@/hooks/dead-link";
export function VideoTile({
ev,
@ -34,10 +35,13 @@ export function VideoTile({
const isGrownUp = useContentWarning();
const { proxy } = useImgProxy();
const liveMedia = useDeadLink(ev);
const link = NostrLink.fromEvent(ev);
const poster = video.bestPoster();
const bestVideo = video.bestVideo();
const [hasImg, setHasImage] = useState(true);
if (!liveMedia) return;
console.debug(liveMedia)
return (
<div
className={classNames("flex gap-2", className, {

73
src/hooks/dead-link.ts Normal file
View File

@ -0,0 +1,73 @@
import { SHORTS_KIND, VIDEO_KIND } from "@/const";
import { MediaPayload, VideoInfo } from "@/service/video/info";
import { findTag } from "@/utils";
import { NostrEvent, TaggedNostrEvent } from "@snort/system";
import { useEffect, useState } from "react";
const saveDeadLink = (link: string, val: boolean) => localStorage.setItem(`dead-link:${link}`, String(val));
const getDeadLink = (link: string) => localStorage.getItem(`dead-link:${link}`);
export function useDeadLink(ev: TaggedNostrEvent | NostrEvent) {
const [alive, setAlive] = useState<MediaPayload>();
async function testLink(link: string) {
const u = new URL(link);
link = u.toString(); // normalize link
const existing = getDeadLink(link);
if (existing === null) {
// youtube links cant be played
if (u.hostname.endsWith("youtube.com") || u.hostname.endsWith("youtu.be")) {
saveDeadLink(link, false);
return false;
}
const req = await fetch(link, {
method: "HEAD",
});
saveDeadLink(link, req.ok);
return req.ok;
} else {
return existing === "true";
}
}
async function testPayload(pl: MediaPayload) {
const alive = await testLink(pl.url);
if (pl.url && alive) {
return pl;
}
for (const alt of pl.alternatives) {
const alive = await testLink(alt);
if (alt && alive) {
return {
...pl,
url: alt
};
}
}
}
async function getLiveLink(links: Array<MediaPayload>) {
for (const l of links) {
const live = await testPayload(l);
if (live) {
setAlive(live);
break;
}
}
}
useEffect(() => {
const links = ev.kind === VIDEO_KIND || ev.kind === SHORTS_KIND ?
VideoInfo.parse(ev)?.sources() :
[
{
url: findTag(ev, "streaming") ?? findTag(ev, "recording"),
alternatives: []
} as MediaPayload
];
getLiveLink(links).catch(console.error);
}, [ev]);
return alive;
}

View File

@ -15,7 +15,6 @@ export function VideosPage() {
const videos = useRequestBuilder(rb);
console.debug(login?.state?.muted);
const sorted = videos
.filter(a => {
const host = getHost(a);