Skip to content

Commit

Permalink
Fixed Appx Video, Added VideoJson Ref to VideoIds (#1600)
Browse files Browse the repository at this point in the history
* Fixed appx video with appx videoJson

* Fixed parsing on api

* Fixed course ref

* Update src/components/admin/AddContent.tsx

---------

Co-authored-by: Sargam <[email protected]>
  • Loading branch information
SujithThirumalaisamy and devsargam authored Dec 1, 2024
1 parent 8c603a9 commit dbc976e
Show file tree
Hide file tree
Showing 15 changed files with 114 additions and 54 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "VideoMetadata" ADD COLUMN "appxVideoJSON" JSONB;
1 change: 1 addition & 0 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ model VideoMetadata {
id Int @id @default(autoincrement())
contentId Int
appxVideoId String?
appxVideoJSON Json?
video_1080p_mp4_1 String? // Link to 1080p mp4 quality video variant 1
video_1080p_mp4_2 String? // Link to 1080p mp4 quality video variant 2
video_1080p_mp4_3 String? // Link to 1080p mp4 quality video variant 3
Expand Down
4 changes: 0 additions & 4 deletions src/actions/user/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,9 @@ export const GetAppxVideoPlayerUrl = async (courseId: string, videoId: string):
'User-Id': appxUserId,
},
};
console.log(config);
console.log(url);

const res = await axios.request(config);
const { video_player_token, video_player_url } = res.data.data;
console.log(video_player_token);
console.log(video_player_url);
const full_video_url = `${video_player_url}${video_player_token}&watermark=${name}%0A${email}`;
return full_video_url;
};
16 changes: 1 addition & 15 deletions src/app/api/admin/content/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,19 +60,6 @@ export const POST = async (req: NextRequest) => {
discordChecked: boolean;
} = await req.json();

console.log({
type,
thumbnail,
title,
courseId,
parentContentId,
metadata,
adminPassword,
courseTitle,
rest,
discordChecked,
});

if (adminPassword !== process.env.ADMIN_SECRET) {
return NextResponse.json({}, { status: 403 });
}
Expand Down Expand Up @@ -113,7 +100,7 @@ export const POST = async (req: NextRequest) => {
} else if (type === 'appx') {
await db.videoMetadata.create({
data: {
appxVideoId: metadata.appxVideoId,
appxVideoJSON: JSON.parse(metadata.appxVideoJSON),
contentId: content.id,
},
});
Expand Down Expand Up @@ -181,7 +168,6 @@ export const POST = async (req: NextRequest) => {
mediaId: content.id,
};

console.log(data);
await sendUpdateToDiscord(data);
}

Expand Down
8 changes: 5 additions & 3 deletions src/components/AppxVideoPlayer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ export const AppxVideoPlayer = ({
if (!url.length) {
return <p>Loading...</p>;
}

return <iframe src={url} className="h-[80vh] w-[80vw] rounded-lg"></iframe>;
return <iframe
src={url}
className="h-[80vh] w-[80vw] rounded-lg"
allowFullScreen
></iframe >;
};

1 change: 1 addition & 0 deletions src/components/CourseView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ export const CourseView = ({
markAsCompleted:
courseContent?.value?.videoProgress?.markAsCompleted || false,
bookmark: courseContent?.value.bookmark || null,
courseId: course.id,
}}
/>
) : null}
Expand Down
4 changes: 2 additions & 2 deletions src/components/FolderView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ export const FolderView = ({
{courseContent.map((content) => {
const videoProgressPercent =
content.type === 'video' &&
content.videoFullDuration &&
content.duration
content.videoFullDuration &&
content.duration
? (content.duration / content.videoFullDuration) * 100
: 0;
return (
Expand Down
12 changes: 4 additions & 8 deletions src/components/VideoPlayer2.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ interface VideoPlayerProps {
subtitles?: string;
contentId: number;
appxVideoId?: string;
appxCourseId?: string;
onVideoEnd: () => void;
}

Expand All @@ -40,18 +41,13 @@ export const VideoPlayer: FunctionComponent<VideoPlayerProps> = ({
subtitles,
onVideoEnd,
appxVideoId,
appxCourseId
}) => {
const videoRef = useRef<HTMLDivElement>(null);
const playerRef = useRef<Player | null>(null);
const [player, setPlayer] = useState<any>(null);
const searchParams = useSearchParams();
const vidUrl = options.sources[0].src;
let href: string | null = null;
let courseId: string | null = null;
if (typeof window !== 'undefined') {
href = window.location.href;
courseId = href.split('/')[4];
}

const togglePictureInPicture = async () => {
try {
Expand Down Expand Up @@ -482,8 +478,8 @@ export const VideoPlayer: FunctionComponent<VideoPlayerProps> = ({

if (isYoutubeUrl(vidUrl)) return <YoutubeRenderer url={vidUrl} />;

if (appxVideoId && typeof window !== 'undefined' && courseId)
return <AppxVideoPlayer courseId={courseId} videoId={appxVideoId} />;
if (appxVideoId && typeof window !== 'undefined' && appxCourseId)
return <AppxVideoPlayer courseId={appxCourseId} videoId={appxVideoId} />;

return (
<div
Expand Down
5 changes: 4 additions & 1 deletion src/components/VideoPlayerSegment.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ interface VideoProps {
videoJsOptions: any;
contentId: number;
appxVideoId?: string;
appxCourseId?: string;
onVideoEnd: () => void;
}

Expand All @@ -36,6 +37,7 @@ export const VideoPlayerSegment: FunctionComponent<VideoProps> = ({
videoJsOptions,
onVideoEnd,
appxVideoId,
appxCourseId
}) => {
const playerRef = useRef<Player | null>(null);

Expand All @@ -52,7 +54,7 @@ export const VideoPlayerSegment: FunctionComponent<VideoProps> = ({
if (mouseTimeDisplay) {
const timeTooltip: any = mouseTimeDisplay.getChild('timeTooltip');
if (timeTooltip) {
timeTooltip.update = function (
timeTooltip.update = function(
seekBarRect: any,
seekBarPoint: any,
time: string,
Expand Down Expand Up @@ -104,6 +106,7 @@ export const VideoPlayerSegment: FunctionComponent<VideoProps> = ({
subtitles={subtitles}
options={videoJsOptions}
appxVideoId={appxVideoId}
appxCourseId={appxCourseId}
onVideoEnd={onVideoEnd}
onReady={handlePlayerReady}
/>
Expand Down
40 changes: 32 additions & 8 deletions src/components/admin/AddContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,39 @@ export const AddContent = ({
const [loading, setLoading] = useState<boolean>(false);

const getLabelClassName = (value: string) => {
return `flex gap-1 p-4 rounded-lg items-center space-x-2 ${
type === value ? 'border-[3px] border-blue-500' : 'border-[3px]'
}`;
return `flex gap-1 p-4 rounded-lg items-center space-x-2 ${type === value ? 'border-[3px] border-blue-500' : 'border-[3px]'
}`;
};

const formatInputJSON = (value: string) => {
const valWithout = value.replaceAll("\\", "").slice(1, -1);
if (valWithout[0] === "{") {
return valWithout;
}
return valWithout.slice(1, -1);
};

const validateJSON = (value: string) => {
try {
JSON.parse(value);
return true;
} catch (error) {
return false;
}
};

const handleContentSubmit = async () => {
setLoading(true);
console.log(courseTitle);
if (type === "appx") {
//@ts-ignore
metadata.appxVideoJSON = formatInputJSON(metadata.appxVideoJSON);
//@ts-ignore
if (!validateJSON(metadata.appxVideoJSON)) {
toast.error("Invalid JSON");
setLoading(false);
return;
}
}
const response = await fetch('/api/admin/content', {
body: JSON.stringify({
type,
Expand All @@ -74,13 +99,12 @@ export const AddContent = ({
},
});
setLoading(false);
console.log(response);
const responseData = await response.json();
console.log(responseData);

if (response.status === 200) {
// handle success if needed
toast.success(responseData.message);
setMetadata({});
} else {
// handle error if needed
toast.error(responseData.message || 'Something went wrong');
Expand Down Expand Up @@ -215,8 +239,8 @@ function AddAppxVideoMetadata({
<div>
<Input
type="text"
placeholder="Appx Video Id"
onChange={(e) => onChange({ appxVideoId: e.target.value })}
placeholder="Appx Video JSON"
onChange={(e) => onChange({ appxVideoJSON: JSON.stringify(e.target.value) })}
className="h-14"
/>
</div>
Expand Down
15 changes: 12 additions & 3 deletions src/components/admin/ContentRenderer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { getServerSession } from 'next-auth';
import { authOptions } from '@/lib/auth';
import { ContentRendererClient } from './ContentRendererClient';
import { Bookmark } from '@prisma/client';
import { getAppxCourseId } from '@/utiles/appx';

function bunnyUrl(url?: string) {
if (!url) return '';
Expand Down Expand Up @@ -86,7 +87,7 @@ export const getMetadata = async (contentId: number) => {
slides: metadata['slides'],
segments: metadata['segments'],
thumbnails: metadata['thumbnail_mosiac_url'],
appxVideoId: metadata['appxVideoId'],
appxVideoJSON: metadata['appxVideoJSON'],
};

if (user?.bunnyProxyEnabled) {
Expand All @@ -104,7 +105,7 @@ export const getMetadata = async (contentId: number) => {
slides: metadata['slides'],
segments: metadata['segments'],
thumbnails: metadata['thumbnail_mosiac_url'],
appxVideoId: metadata['appxVideoId'],
appxVideoJSON: metadata['appxVideoJSON'],
};

const isHighestQualityUrlAccessible = await isUrlAccessible(mainUrls['1080']);
Expand Down Expand Up @@ -144,15 +145,23 @@ export const ContentRenderer = async ({
slides?: string;
markAsCompleted: boolean;
bookmark: Bookmark | null;
courseId: string;
};
}) => {
const metadata = await getMetadata(content.id);
const appxCourseId = await getAppxCourseId(content.courseId);
if (!appxCourseId) {
return <div>Loading...</div>;
}
//@ts-ignore
const appxVideoId: string = metadata?.appxVideoJSON[appxCourseId];

return (
<div>
<ContentRendererClient
nextContent={nextContent}
metadata={metadata}
content={content}
content={{ ...content, appxVideoId, appxCourseId }}
/>
</div>
);
Expand Down
7 changes: 5 additions & 2 deletions src/components/admin/ContentRendererClient.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ export const ContentRendererClient = ({
thumbnail: string;
description: string;
markAsCompleted: boolean;
appxVideoId?: string;
appxCourseId?: string;
};
}) => {
const [showChapters, setShowChapters] = useState(
Expand Down Expand Up @@ -79,7 +81,8 @@ export const ContentRendererClient = ({
contentId={content.id}
subtitles={metadata.subtitles}
thumbnails={[]}
appxVideoId={metadata.appxVideoId}
appxVideoId={content.appxVideoId}
appxCourseId={content.appxCourseId}
segments={metadata?.segments || []}
videoJsOptions={{
playbackrates: [0.5, 1, 1.25, 1.5, 1.75, 2],
Expand All @@ -99,7 +102,7 @@ export const ContentRendererClient = ({
responsive: true,
sources: [source],
}}
onVideoEnd={() => {}}
onVideoEnd={() => { }}
/>
<div className="flex flex-col gap-4 rounded-xl bg-primary/5 p-4">
<div className="flex w-full flex-col justify-between gap-2 md:flex-row">
Expand Down
14 changes: 7 additions & 7 deletions src/db/course.ts
Original file line number Diff line number Diff line change
Expand Up @@ -296,13 +296,13 @@ export const getFullCourseContent = async (
videoProgress:
content.type === 'video'
? {
duration: videoProgress.find((x) => x.contentId === content.id)
?.currentTimestamp,
markAsCompleted: videoProgress.find(
(x) => x.contentId === content.id,
)?.markAsCompleted,
videoFullDuration: content.VideoMetadata?.duration,
}
duration: videoProgress.find((x) => x.contentId === content.id)
?.currentTimestamp,
markAsCompleted: videoProgress.find(
(x) => x.contentId === content.id,
)?.markAsCompleted,
videoFullDuration: content.VideoMetadata?.duration,
}
: null,
},
]),
Expand Down
2 changes: 1 addition & 1 deletion src/lib/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ async function validateUser(
}
return { data: null };
}
const url = 'https://harkiratapi.classx.co.in/post/userLogin';
const url = `${process.env.APPX_BASE_API}/post/userLogin`;
const headers = {
'Client-Service': process.env.APPX_CLIENT_SERVICE || '',
'Auth-Key': process.env.APPX_AUTH_KEY || '',
Expand Down
37 changes: 37 additions & 0 deletions src/utiles/appx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ import { refreshDbInternal } from '@/actions/refresh-db';

const LOCAL_CMS_PROVIDER = process.env.LOCAL_CMS_PROVIDER;
const COHORT_3_PARENT_COURSES = [8, 9, 10, 11, 12];
// 8 -> Web + Devops + Web3
// 9 -> Web + Devops
// 10 -> Web3
// 11 -> Web
// 12 -> Devops

export const APPX_COURSE_IDS = [1, 2, 3, 8, 9, 10, 11, 12];

Expand Down Expand Up @@ -212,3 +217,35 @@ export async function getPurchases(email: string): Promise<CoursesResponse> {
};
}
}

export async function getAppxCourseId(courseId: string) {
const session = await getServerSession(authOptions);
const parentCourses = await prisma.userPurchases.findMany({
where: {
courseId: {
in: COHORT_3_PARENT_COURSES,
},
userId: session?.user?.id,
},
include: {
course: true,
},
orderBy: {
courseId: 'asc'
}
});

const CMS_APPX_COURSE_MAP: Record<string, string[]> = {
13: ["8", "10"],
14: ["8", "9", "11"],
15: ["8", "9", "12"]
};

let appxCourseId: string | null = null;
parentCourses.forEach((pc => {
if (CMS_APPX_COURSE_MAP[courseId].includes(pc.courseId.toString())) {
appxCourseId = pc.course.appxCourseId;
}
}));
return appxCourseId;
}

0 comments on commit dbc976e

Please sign in to comment.