import * as React from 'react'; import Head from 'next/head'; import Link from 'next/link'; import { useRouter } from 'next/router'; import { Breadcrumb, Button, ButtonGroup, Col, Row, } from 'react-bootstrap'; import { useIntl } from 'react-intl'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { GetServerSideProps, InferGetServerSidePropsType } from 'next'; import { VideoEntry } from 'util/datatypes/VideoList'; import DownloadButton from 'components/DownloadButton'; import { basename } from 'path'; import { getHLSMasterURL } from '../../util'; import VideoPlayer from '../../components/VideoPlayer'; import CopyField from '../../components/CopyField'; import { FormattedMessage } from '../../components/localization'; import sanitizeFileName from '../../util/sanitizeFileName'; import sanitizeTitle from '../../util/sanitizeTitle'; import { notFound } from '../../util/status'; import { getIndex, getVideos } from '../../util/api'; export const getServerSideProps: GetServerSideProps = async (context) => { const { req }: { req: IncomingMessage } = context; const { id, vslug } = context.params || {}; if (typeof id !== 'string') { throw new Error('only expected a single id'); } if (typeof vslug !== 'string') { throw new Error('only expected a single vslug'); } // Fetch URL to thumbnails server const { ids, servers: { hls: hlsServerURL, dash: dashServerURL }, } = await getIndex(); const vodMeta = ids.find(({ id: thisID, }: { id: string }) => id === thisID); if (!vodMeta) { return { props: {} }; } // Fetch list of videos for this VOD ID const vodInfo = await getVideos(id); let videos; if (Array.isArray(vodInfo)) { videos = vodInfo; } else { videos = vodInfo.videos; } // Check if vslug is actually an index number (old app style) /* NOTE - parseInt will accept strings CONTAINING numbers. This is supposed to reject strings that are not JUST numbers. */ const vindexNum = +vslug; if (!Number.isNaN(vindexNum)) { // Check if video exists if (vindexNum < 0 || vindexNum >= videos.length) { return { props: {} }; } const video = videos[vindexNum]; return { props: { redirect: true, id, video, vslug: sanitizeTitle(video.title), }, }; } // Check if vslug is actually point to a file name const sanitizedFileName = `${sanitizeFileName(basename(vslug, '.mp4'))}.mp4`; const realVIndex = videos.findIndex( (video: VideoEntry) => video.fileName === sanitizedFileName, ); if (realVIndex >= 0) { const video = videos[realVIndex]; return { props: { redirect: true, id, video: realVIndex, vslug: sanitizeTitle(video.title), }, }; } // Check if we can find any video with matching vslug const video = videos.find(({ title }: { title: string }) => sanitizeTitle(title) === vslug); if (!video) { return { props: {} }; } // At this point we found the right video, just get more information at this point const { title } = vodMeta; // let basePath = null; // basePath = `${JSON.stringify(req.toString())}`; const basePath = `https://${req.headers.host}`; // Pass data to the page via props return { props: { id, vslug, video, title, hlsServerURL, dashServerURL, basePath, }, }; }; export default function VideoPlayerPage({ id, vslug, video, redirect, title, hlsServerURL, // dashServerURL, basePath, }: InferGetServerSidePropsType) { if (redirect) { const router = useRouter(); React.useEffect(() => { router.push(`/${id}/${vslug}`); }); return (

You will be redirected {' '} here

); } if (!video) { return notFound(); } const intl = useIntl(); const { fileName, title: videoTitle, sourceVideoURL, sourceVideoStart, } = video; return (
{videoTitle} {' '} – {' '} {title} {' '} – {' '} {intl.formatMessage({ id: 'App.title', description: 'The full title of the website', defaultMessage: 'Games Done Quick Instant Archive', })} {title} {videoTitle}

{title} : {' '} {videoTitle}

{sourceVideoURL ? ( ) : ( '' )} {[basePath, id, vslug].join('/')}
); }