Skip to content

Commit

Permalink
Integrated Youtube Renderer with video player
Browse files Browse the repository at this point in the history
  • Loading branch information
vijaysingh2219 committed Apr 16, 2024
1 parent 4f1310f commit 8a4b86e
Show file tree
Hide file tree
Showing 3 changed files with 172 additions and 115 deletions.
72 changes: 48 additions & 24 deletions prisma/seed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,30 +147,54 @@ async function main() {
data: {
id: 1,
contentId: 3,
video_1080p_mp4_1: 'https://www.w3schools.com/html/mov_bbb.mp4',
video_1080p_mp4_2: 'https://www.w3schools.com/html/mov_bbb.mp4',
video_1080p_mp4_3: 'https://www.w3schools.com/html/mov_bbb.mp4',
video_1080p_mp4_4: 'https://www.w3schools.com/html/mov_bbb.mp4',
video_1080p_1: 'https://www.w3schools.com/html/mov_bbb.mp4',
video_1080p_2: 'https://www.w3schools.com/html/mov_bbb.mp4',
video_1080p_3: 'https://www.w3schools.com/html/mov_bbb.mp4',
video_1080p_4: 'https://www.w3schools.com/html/mov_bbb.mp4',
video_720p_mp4_1: 'https://www.w3schools.com/html/mov_bbb.mp4',
video_720p_mp4_2: 'https://www.w3schools.com/html/mov_bbb.mp4',
video_720p_mp4_3: 'https://www.w3schools.com/html/mov_bbb.mp4',
video_720p_mp4_4: 'https://www.w3schools.com/html/mov_bbb.mp4',
video_720p_1: 'https://www.w3schools.com/html/mov_bbb.mp4',
video_720p_2: 'https://www.w3schools.com/html/mov_bbb.mp4',
video_720p_3: 'https://www.w3schools.com/html/mov_bbb.mp4',
video_720p_4: 'https://www.w3schools.com/html/mov_bbb.mp4',
video_360p_mp4_1: 'https://www.w3schools.com/html/mov_bbb.mp4',
video_360p_mp4_2: 'https://www.w3schools.com/html/mov_bbb.mp4',
video_360p_mp4_3: 'https://www.w3schools.com/html/mov_bbb.mp4',
video_360p_mp4_4: 'https://www.w3schools.com/html/mov_bbb.mp4',
video_360p_1: 'https://www.w3schools.com/html/mov_bbb.mp4',
video_360p_2: 'https://www.w3schools.com/html/mov_bbb.mp4',
video_360p_3: 'https://www.w3schools.com/html/mov_bbb.mp4',
video_360p_4: 'https://www.w3schools.com/html/mov_bbb.mp4',
// video_1080p_mp4_1: 'https://www.w3schools.com/html/mov_bbb.mp4',
// video_1080p_mp4_2: 'https://www.w3schools.com/html/mov_bbb.mp4',
// video_1080p_mp4_3: 'https://www.w3schools.com/html/mov_bbb.mp4',
// video_1080p_mp4_4: 'https://www.w3schools.com/html/mov_bbb.mp4',
// video_1080p_1: 'https://www.w3schools.com/html/mov_bbb.mp4',
// video_1080p_2: 'https://www.w3schools.com/html/mov_bbb.mp4',
// video_1080p_3: 'https://www.w3schools.com/html/mov_bbb.mp4',
// video_1080p_4: 'https://www.w3schools.com/html/mov_bbb.mp4',
// video_720p_mp4_1: 'https://www.w3schools.com/html/mov_bbb.mp4',
// video_720p_mp4_2: 'https://www.w3schools.com/html/mov_bbb.mp4',
// video_720p_mp4_3: 'https://www.w3schools.com/html/mov_bbb.mp4',
// video_720p_mp4_4: 'https://www.w3schools.com/html/mov_bbb.mp4',
// video_720p_1: 'https://www.w3schools.com/html/mov_bbb.mp4',
// video_720p_2: 'https://www.w3schools.com/html/mov_bbb.mp4',
// video_720p_3: 'https://www.w3schools.com/html/mov_bbb.mp4',
// video_720p_4: 'https://www.w3schools.com/html/mov_bbb.mp4',
// video_360p_mp4_1: 'https://www.w3schools.com/html/mov_bbb.mp4',
// video_360p_mp4_2: 'https://www.w3schools.com/html/mov_bbb.mp4',
// video_360p_mp4_3: 'https://www.w3schools.com/html/mov_bbb.mp4',
// video_360p_mp4_4: 'https://www.w3schools.com/html/mov_bbb.mp4',
// video_360p_1: 'https://www.w3schools.com/html/mov_bbb.mp4',
// video_360p_2: 'https://www.w3schools.com/html/mov_bbb.mp4',
// video_360p_3: 'https://www.w3schools.com/html/mov_bbb.mp4',
// video_360p_4: 'https://www.w3schools.com/html/mov_bbb.mp4',
video_1080p_mp4_1: 'https://www.youtube.com/watch?v=IJkYipYNEtI',
video_1080p_mp4_2: 'https://www.youtube.com/watch?v=IJkYipYNEtI',
video_1080p_mp4_3: 'https://www.youtube.com/watch?v=IJkYipYNEtI',
video_1080p_mp4_4: 'https://www.youtube.com/watch?v=IJkYipYNEtI',
video_1080p_1: 'https://www.youtube.com/watch?v=IJkYipYNEtI',
video_1080p_2: 'https://www.youtube.com/watch?v=IJkYipYNEtI',
video_1080p_3: 'https://www.youtube.com/watch?v=IJkYipYNEtI',
video_1080p_4: 'https://www.youtube.com/watch?v=IJkYipYNEtI',
video_720p_mp4_1: 'https://www.youtube.com/watch?v=IJkYipYNEtI',
video_720p_mp4_2: 'https://www.youtube.com/watch?v=IJkYipYNEtI',
video_720p_mp4_3: 'https://www.youtube.com/watch?v=IJkYipYNEtI',
video_720p_mp4_4: 'https://www.youtube.com/watch?v=IJkYipYNEtI',
video_720p_1: 'https://www.youtube.com/watch?v=IJkYipYNEtI',
video_720p_2: 'https://www.youtube.com/watch?v=IJkYipYNEtI',
video_720p_3: 'https://www.youtube.com/watch?v=IJkYipYNEtI',
video_720p_4: 'https://www.youtube.com/watch?v=IJkYipYNEtI',
video_360p_mp4_1: 'https://www.youtube.com/watch?v=IJkYipYNEtI',
video_360p_mp4_2: 'https://www.youtube.com/watch?v=IJkYipYNEtI',
video_360p_mp4_3: 'https://www.youtube.com/watch?v=IJkYipYNEtI',
video_360p_mp4_4: 'https://www.youtube.com/watch?v=IJkYipYNEtI',
video_360p_1: 'https://www.youtube.com/watch?v=IJkYipYNEtI',
video_360p_2: 'https://www.youtube.com/watch?v=IJkYipYNEtI',
video_360p_3: 'https://www.youtube.com/watch?v=IJkYipYNEtI',
video_360p_4: 'https://www.youtube.com/watch?v=IJkYipYNEtI',
slides:
'https://appx-recordings.s3.ap-south-1.amazonaws.com/drm/100x/slides/Loops%2C+callbacks.pdf',
},
Expand Down
18 changes: 13 additions & 5 deletions src/components/YoutubeRenderer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,33 @@ import React from 'react';

interface Props {
videoURL: string;
width: string;
height: string;
width?: string;
height?: string;
style?: React.CSSProperties;
className?: string;
}

export const YoutubeRenderer = ({ width, height, videoURL, style }: Props) => {
export const YoutubeRenderer = ({
width,
height,
videoURL,
style,
className,
}: Props) => {
if (!videoURL) {
return null;
}
return (
<iframe
width={width}
height={height}
width={width || 1280}
height={height || 720}
src={videoURL}
title="YouTube video player"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
referrerPolicy="strict-origin-when-cross-origin"
allowFullScreen
style={style}
className={className || ''}
></iframe>
);
};
Expand Down
197 changes: 111 additions & 86 deletions src/components/admin/ContentRendererClient.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,20 @@ import { VideoPlayerSegment } from '@/components/VideoPlayerSegment';
import VideoContentChapters from '../VideoContentChapters';
import { useMemo, useState } from 'react';
import { handleMarkAsCompleted } from '@/lib/utils';
import YoutubeRenderer from '../YoutubeRenderer';

const isYouTubeUrl = (url: string): boolean => {
const youtubePattern: RegExp =
/(?:youtu|youtube)(?:\.com|\.be)\/(?:watch\?v=)?([\w-]+)/;
return youtubePattern.test(url);
};

const extractYouTubeIdFromUrl = (url: string): string | null => {
const match: RegExpMatchArray | null = url.match(
/(?:youtu\.be\/|(?:youtube\.com\/(?:v\/|u\/\w\/|embed\/|watch\?v=)))([\w-]+)/,
);
return match ? match[1] : null;
};

export const ContentRendererClient = ({
metadata,
Expand Down Expand Up @@ -63,6 +77,11 @@ export const ContentRendererClient = ({
src: mpdUrl,
type: 'application/x-mpegURL',
};
} else if (isYouTubeUrl(mpdUrl)) {
return {
src: mpdUrl,
type: 'video/youtube',
};
}
return {
src: mpdUrl,
Expand All @@ -89,101 +108,107 @@ export const ContentRendererClient = ({

return (
<div className="flex gap-2 items-start flex-col lg:flex-row">
<div className="flex-1 w-full">
<VideoPlayerSegment
setQuality={setQuality}
contentId={content.id}
subtitles={metadata.subtitles}
thumbnails={[]}
segments={metadata?.segments || []}
videoJsOptions={{
playbackrates: [0.5, 1, 1.25, 1.5, 1.75, 2],
controls: true,
fluid: true,
html5: {
vhs: {
overridenative: true,
},
},
thumbnail: metadata.thumbnail || false, // data.isComposite ? data.thumbnails[0] : null,
isComposite: true,
height: 720,
width: 1080,
delta: 30,
autoplay: true,
responsive: true,
sources: [source],
}}
onVideoEnd={() => {
setContentCompleted(true);
}}
{source.type === 'video/youtube' ? (
<YoutubeRenderer
width="1200"
videoURL={`https://www.youtube.com/embed/${extractYouTubeIdFromUrl(source.src)}`}
/>
<br />
<div className="flex justify-between mb-2">
<div>
<div className="text-gray-900 dark:text-white font-bold text-2xl">
{content.title}
) : (
<div className="flex-1 w-full">
<VideoPlayerSegment
setQuality={setQuality}
contentId={content.id}
subtitles={metadata.subtitles}
thumbnails={[]}
segments={metadata?.segments || []}
videoJsOptions={{
playbackrates: [0.5, 1, 1.25, 1.5, 1.75, 2],
controls: true,
fluid: true,
html5: {
vhs: {
overridenative: true,
},
},
thumbnail: metadata.thumbnail || false, // data.isComposite ? data.thumbnails[0] : null,
isComposite: true,
height: 720,
width: 1080,
delta: 30,
autoplay: true,
responsive: true,
sources: [source],
}}
onVideoEnd={() => {
setContentCompleted(true);
}}
/>
<br />
<div className="flex justify-between mb-2">
<div>
<div className="text-gray-900 dark:text-white font-bold text-2xl">
{content.title}
</div>

<button
className="bg-blue-500 hover:bg-blue-700 text-white font-bold rounded p-2 my-4"
disabled={loadingMarkAs}
onClick={handleMarkCompleted}
>
{contentCompleted ? 'Mark as Incomplete' : 'Mark as completed'}
</button>
</div>

<button
className="bg-blue-500 hover:bg-blue-700 text-white font-bold rounded p-2 my-4"
disabled={loadingMarkAs}
onClick={handleMarkCompleted}
>
{contentCompleted ? 'Mark as Incomplete' : 'Mark as completed'}
</button>
<div>
{/* <QualitySelector /> */}
<br />
{metadata.slides ? (
<div
style={{
display: 'flex',
flexDirection: 'row-reverse',
gap: '10px',
}}
>
<a href={metadata.slides} target="_blank">
<button className="bg-blue-500 hover:bg-blue-700 text-white font-bold rounded p-2">
Slides
</button>
</a>
</div>
) : null}
{!showChapters && metadata.segments?.length > 0 && (
<button
className="bg-blue-500 hover:bg-blue-700 text-white font-bold rounded p-2"
onClick={() => {
scrollTo({ top: 0, behavior: 'smooth' });
toggleShowChapters();
}}
>
View All Chapters
</button>
)}
</div>
</div>

<div>
{/* <QualitySelector /> */}
<br />
{metadata.slides ? (
<div
style={{
display: 'flex',
flexDirection: 'row-reverse',
gap: '10px',
}}
>
<a href={metadata.slides} target="_blank">
<button className="bg-blue-500 hover:bg-blue-700 text-white font-bold rounded p-2">
Slides
</button>
</a>
</div>
) : null}
{!showChapters && metadata.segments?.length > 0 && (
{nextContent ? (
<div className="flex flex-row-reverse">
<button
className="bg-blue-500 hover:bg-blue-700 text-white font-bold rounded p-2"
className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded ml-4"
onClick={() => {
scrollTo({ top: 0, behavior: 'smooth' });
toggleShowChapters();
const originalPath = window.location.pathname;
const parts = originalPath.split('/');
parts.pop();
parts.push(nextContent.id.toString());
const newPath = parts.join('/');
router.push(newPath);
}}
>
View All Chapters
</button>
)}
</div>
{nextContent.title}
</button>{' '}
</div>
) : null}
</div>
{nextContent ? (
<div className="flex flex-row-reverse">
<button
className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded ml-4"
onClick={() => {
const originalPath = window.location.pathname;
const parts = originalPath.split('/');
parts.pop();
parts.push(nextContent.id.toString());
const newPath = parts.join('/');
router.push(newPath);
}}
>
{nextContent.title}
</button>{' '}
</div>
) : null}
</div>

)}
{showChapters && (
<VideoContentChapters
segments={metadata?.segments}
Expand Down

0 comments on commit 8a4b86e

Please sign in to comment.