'use client'; import { useEffect, useState, forwardRef, useContext, Ref } from 'react'; import { IVod } from '@/lib/vods'; import { useAuth } from '@/components/auth'; import { getVodTitle } from './vod-page'; import { VideoSourceSelector } from '@/components/video-source-selector' import { buildIpfsUrl } from '@/lib/ipfs'; import { strapiUrl } from '@/lib/constants'; import MuxPlayer from '@mux/mux-player-react/lazy'; import { VideoContext } from './video-context'; import MuxPlayerElement from '@mux/mux-player'; import VideoApiElement from "@mux/mux-player/dist/types/video-api"; interface IPlayerProps { vod: IVod; setIsPlayerReady: Function; } interface ITokens { playbackToken: string; storyboardToken: string; thumbnailToken: string; } async function getMuxPlaybackTokens(playbackId: string, jwt: string): Promise { const res = await fetch(`${strapiUrl}/api/mux-asset/secure?id=${playbackId}`, { headers: { 'Authorization': `Bearer ${jwt}` } }) const json = await res.json() return { playbackToken: json.playbackToken, storyboardToken: json.storyboardToken, thumbnailToken: json.thumbnailToken } } function hexToRgba(hex: string, alpha: number) { const r = parseInt(hex.slice(1, 3), 16); const g = parseInt(hex.slice(3, 5), 16); const b = parseInt(hex.slice(5, 7), 16); return `rgba(${r}, ${g}, ${b}, ${alpha})`; } export const VideoPlayer = forwardRef(function VideoPlayer( props: IPlayerProps, ref: Ref ): React.JSX.Element { const { vod, setIsPlayerReady } = props const title: string = getVodTitle(vod); const { authData } = useAuth(); const [selectedVideoSource, setSelectedVideoSource] = useState(''); const [isEntitledToCDN, setIsEntitledToCDN] = useState(false); const [hlsSource, setHlsSource] = useState(''); const [isClient, setIsClient] = useState(false); const [playbackId, setPlaybackId] = useState(''); const [src, setSrc] = useState(''); const [tokens, setTokens] = useState({}); const { setTimeStamp } = useContext(VideoContext); useEffect(() => { setIsClient(true); const token = authData?.accessToken; const playbackId = vod?.attributes.muxAsset?.data?.attributes?.playbackId; if (token) setIsEntitledToCDN(true); if (selectedVideoSource === 'Mux') { if (!!token && !!playbackId) { try { getMuxPlaybackTokens(vod.attributes.muxAsset.data.attributes.playbackId, token) .then((tokens) => { setTokens({ playback: tokens.playbackToken, storyboard: tokens.storyboardToken, thumbnail: tokens.thumbnailToken }) setHlsSource(vod.attributes.muxAsset.data.attributes.playbackId) setPlaybackId(vod.attributes.muxAsset.data.attributes.playbackId) }); } catch (e) { console.error(e) } } } else if (selectedVideoSource === 'B2') { if (!vod.attributes.videoSrcB2) return; // This shouldn't happen because videoSourceSelector won't choose B2 if there is no b2. This return is only for satisfying TS setHlsSource(vod.attributes.videoSrcB2.data.attributes.cdnUrl); setPlaybackId(''); setSrc(vod.attributes.videoSrcB2.data.attributes.cdnUrl); } else if (selectedVideoSource === 'IPFSSource') { setHlsSource(''); setPlaybackId(''); setSrc(buildIpfsUrl(vod.attributes.videoSrcHash)) } else if (selectedVideoSource === 'IPFS240') { setHlsSource(''); setPlaybackId(''); setSrc(buildIpfsUrl(vod.attributes.video240Hash)) } }, [selectedVideoSource, authData, vod, setHlsSource]); if (!isClient) return <> return ( <> { setIsPlayerReady(true)} } ref={ref} preload="auto" crossOrigin="*" loading="viewport" playbackId={playbackId} src={src} tokens={tokens} primaryColor="#FFFFFF" metadata={{ video_title: getVodTitle(vod) }} streamType="on-demand" onTimeUpdate={(evt) => { const muxPlayer = evt.target as VideoApiElement const { currentTime } = muxPlayer; setTimeStamp(currentTime) }} muted > {/* {vod?.attributes?.videoSrcB2?.data?.attributes?.cdnUrl && (<>

CDN2

)} */} ) })