Skip to content

Commit

Permalink
feat: creating live stream page
Browse files Browse the repository at this point in the history
  • Loading branch information
dager-mohamed committed Aug 1, 2024
1 parent 73bbc44 commit 9858df5
Show file tree
Hide file tree
Showing 8 changed files with 205 additions and 36 deletions.
24 changes: 24 additions & 0 deletions apps/web/src/app/live/[id]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import '@vidstack/react/player/styles/default/theme.css';
import '@vidstack/react/player/styles/default/layouts/audio.css';
import '@vidstack/react/player/styles/default/layouts/video.css';

import Chat from '../../../components/Chat';
import LiveVideoPlayer from '../../../components/LiveVideoPlayer';

export default function LiveStreamPage() {
return (
<>
<div className="flex w-full h-screen">
<LiveVideoPlayer
src={
'https://stream.mux.com/v69RSHhFelSm4701snP22dYz2jICy4E4FUyk02rW4gxRM.m3u8'
}
poster={
'https://image.mux.com/v69RSHhFelSm4701snP22dYz2jICy4E4FUyk02rW4gxRM/thumbnail.webp?time=30'
}
/>
<Chat />
</div>
</>
);
}
8 changes: 0 additions & 8 deletions apps/web/src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,11 @@
import Navbar from '../components/Navbar';
import VideosList from '../components/VideosList';
import getUsers from '../../utils/API/getUsers';
import { User } from '@clerk/nextjs/server';

export default async function Page() {
const users = await getUsers();
return (
<>
<Navbar />
<VideosList />
<ol>
{users.data && users.data.map((user: User) => (
<li key={user.id}>{user?.username}</li>
))}
</ol>
</>
);
}
72 changes: 72 additions & 0 deletions apps/web/src/components/Chat.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { Button } from '@org/shared';
import { Textarea } from '@org/shared';
import { SendIcon } from 'lucide-react';

export default function Chat() {
return(
<div className="bg-background border-l flex flex-col w-[400px]">
<div className="border-b px-4 py-3 text-lg font-medium">Live Chat</div>
<div className="flex-1 overflow-auto p-4 space-y-4">
<div className="flex items-start gap-3">
<div className="rounded-full bg-primary text-primary-foreground w-8 h-8 flex items-center justify-center text-sm font-medium">
JD
</div>
<div>
<div className="font-medium">John Doe</div>
<div className="text-muted-foreground text-sm">
Hey, this is looking great!
</div>
</div>
</div>
<div className="flex items-start gap-3">
<div className="rounded-full bg-secondary text-secondary-foreground w-8 h-8 flex items-center justify-center text-sm font-medium">
SA
</div>
<div>
<div className="font-medium">Sarah Adams</div>
<div className="text-muted-foreground text-sm">
Wow, the video quality is amazing!
</div>
</div>
</div>
<div className="flex items-start gap-3">
<div className="rounded-full bg-accent text-accent-foreground w-8 h-8 flex items-center justify-center text-sm font-medium">
MJ
</div>
<div>
<div className="font-medium">Michael Johnson</div>
<div className="text-muted-foreground text-sm">
Can not wait to see more of this!
</div>
</div>
</div>
<div className="flex items-start gap-3">
<div className="rounded-full bg-muted text-muted-foreground w-8 h-8 flex items-center justify-center text-sm font-medium">
EM
</div>
<div>
<div className="font-medium">Emily Miller</div>
<div className="text-muted-foreground text-sm">
This is so cool, I am loving it!
</div>
</div>
</div>
</div>
<div className="border-t p-4">
<div className="relative">
<Textarea
placeholder="Type your message..."
className="pr-12 rounded-md"
/>
<Button
type="submit"
size="icon"
className="absolute top-1/2 right-2 -translate-y-1/2"
>
<SendIcon className="w-5 h-5" />
</Button>
</div>
</div>
</div>
)
}
32 changes: 32 additions & 0 deletions apps/web/src/components/LiveVideoPlayer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { MediaPlayer, MediaProvider, PlayerSrc, Poster } from '@vidstack/react';
import {
DefaultVideoLayout,
defaultLayoutIcons,
} from '@vidstack/react/player/layouts/default';

interface VideoPlayerProps {
src: PlayerSrc;
poster: string;
}

export default function LiveVideoPlayer({ src, poster }: VideoPlayerProps) {
return (
<div className="w-full h-full" style={{ maxWidth: '80%' }}>
<MediaPlayer
src="https://stream.mux.com/v69RSHhFelSm4701snP22dYz2jICy4E4FUyk02rW4gxRM.m3u8"
poster="https://image.mux.com/v69RSHhFelSm4701snP22dYz2jICy4E4FUyk02rW4gxRM/thumbnail.webp?time=30"
viewType="video"
streamType="live"
className="h-full"
logLevel="warn"
crossOrigin
playsInline
>
<MediaProvider>
<Poster className="vds-poster" />
</MediaProvider>
<DefaultVideoLayout icons={defaultLayoutIcons} />
</MediaPlayer>
</div>
);
}
75 changes: 49 additions & 26 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"@nestjs/platform-express": "^10.0.2",
"@radix-ui/react-avatar": "^1.1.0",
"@radix-ui/react-slot": "^1.1.0",
"@vidstack/react": "^1.11.30",
"axios": "^1.6.0",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
Expand Down Expand Up @@ -48,6 +49,7 @@
"@swc/cli": "~0.3.12",
"@swc/core": "~1.5.7",
"@swc/helpers": "~0.5.11",
"@types/cookie-parser": "^1.4.7",
"@types/jest": "^29.4.0",
"@types/node": "18.16.9",
"@types/react": "18.3.1",
Expand All @@ -73,7 +75,6 @@
"ts-jest": "^29.1.0",
"ts-node": "10.9.1",
"typescript": "~5.5.2",
"@types/cookie-parser": "^1.4.7",
"webpack-cli": "^5.1.4"
}
}
24 changes: 24 additions & 0 deletions shared/src/components/ui/textarea.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import * as React from "react"

import { cn } from "@org/shared/lib/utils"

export interface TextareaProps
extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {}

const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
({ className, ...props }, ref) => {
return (
<textarea
className={cn(
"flex min-h-[60px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50",
className
)}
ref={ref}
{...props}
/>
)
}
)
Textarea.displayName = "Textarea"

export { Textarea }
3 changes: 2 additions & 1 deletion shared/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// Use this file to export React client components (e.g. those with 'use client' directive) or other non-server utilities

export * from './components/ui/button';
export * from './components/ui/avatar'
export * from './components/ui/avatar';
export * from './components/ui/textarea';

0 comments on commit 9858df5

Please sign in to comment.