848 lines
20 KiB
Markdown
848 lines
20 KiB
Markdown
# Phase 3: Creator Tools & VOD - Complete Implementation Guide
|
|
|
|
**Duration**: Weeks 9-13 | **Complexity**: High | **Team Size**: 3 devs
|
|
|
|
## Executive Summary
|
|
|
|
Phase 3 empowers creators with professional tools for content management. VOD archival enables creators to build libraries of content. Clip creation allows viral moments to be shared. Advanced analytics help creators understand their audience.
|
|
|
|
---
|
|
|
|
## Phase 3 Goals
|
|
|
|
### Primary Goals
|
|
1. Automatic VOD archival from live streams
|
|
2. Clip creation and sharing system
|
|
3. Advanced creator analytics dashboard
|
|
4. Stream health monitoring
|
|
5. VOD library management and playback
|
|
|
|
### Success Criteria
|
|
- 📹 100+ VODs archived
|
|
- 🎬 50+ clips created and shared
|
|
- 📊 Analytics dashboard with 10+ metrics
|
|
- 📈 95% stream uptime with health metrics
|
|
- 🎥 <2 minute clip generation time
|
|
|
|
---
|
|
|
|
## Sprint Breakdown
|
|
|
|
### Sprint 3.1: VOD Archives
|
|
**Duration**: Days 1-5 | **Team**: 2 devs
|
|
|
|
#### User Story 3.1.1: Automatic Stream Recording
|
|
```
|
|
AS A creator
|
|
I WANT my streams automatically archived
|
|
SO THAT I don't lose content and can build a VOD library
|
|
```
|
|
|
|
**Tasks**:
|
|
- [ ] Enable stream recording on Cloudflare/Mux
|
|
- [ ] Store recordings in R2 storage
|
|
- [ ] Index VODs in database
|
|
- [ ] Create VOD metadata storage
|
|
- [ ] Auto-cleanup old test recordings
|
|
|
|
**Recording Configuration**:
|
|
```typescript
|
|
// config/streaming.ts
|
|
export const recordingConfig = {
|
|
enabled: true,
|
|
minDurationMinutes: 1, // Only record streams >1 min
|
|
deleteAfterDays: 365, // Keep for 1 year
|
|
allowUserDelete: true,
|
|
storage: {
|
|
provider: 'r2', // Cloudflare R2
|
|
bucket: 'aethex-vods',
|
|
prefix: '{channelId}/{streamId}/',
|
|
},
|
|
formats: ['hls', 'mp4'], // HLS for streaming, MP4 for download
|
|
}
|
|
```
|
|
|
|
**Database Schema**:
|
|
```prisma
|
|
model VOD {
|
|
id String @id @default(cuid())
|
|
streamId String @unique
|
|
stream Stream @relation(fields: [streamId], references: [id], onDelete: Cascade)
|
|
|
|
channelId String
|
|
channel Channel @relation(fields: [channelId], references: [id], onDelete: Cascade)
|
|
|
|
title String // From stream
|
|
description String?
|
|
thumbnail String?
|
|
|
|
// Storage paths
|
|
hlsUrl String // HLS stream URL
|
|
mp4Url String? // MP4 download link
|
|
|
|
// Duration & stats
|
|
duration Int // Minutes
|
|
fileSize Int // Bytes
|
|
resolution String @default("1080p") // Max resolution
|
|
|
|
// Metadata
|
|
viewCount Int @default(0)
|
|
likeCount Int @default(0)
|
|
clipCount Int @default(0)
|
|
|
|
// Visibility
|
|
isPublic Boolean @default(true)
|
|
isDeleted Boolean @default(false)
|
|
deletedAt DateTime?
|
|
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
clips Clip[]
|
|
}
|
|
|
|
model Clip {
|
|
id String @id @default(cuid())
|
|
vodId String
|
|
vod VOD @relation(fields: [vodId], references: [id], onDelete: Cascade)
|
|
|
|
creatorId String
|
|
creator User @relation(fields: [creatorId], references: [id], onDelete: Cascade)
|
|
|
|
title String
|
|
description String?
|
|
|
|
// Trim points (in seconds from start of VOD)
|
|
startTime Int
|
|
endTime Int
|
|
duration Int // endTime - startTime
|
|
|
|
// Clip URL and metadata
|
|
clipUrl String
|
|
thumbnail String?
|
|
|
|
// Engagement
|
|
viewCount Int @default(0)
|
|
likeCount Int @default(0)
|
|
shareCount Int @default(0)
|
|
|
|
// Status
|
|
status ClipStatus @default(PROCESSING) // PROCESSING, READY, FAILED
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
}
|
|
|
|
enum ClipStatus {
|
|
PROCESSING
|
|
READY
|
|
FAILED
|
|
DELETED
|
|
}
|
|
```
|
|
|
|
**API Routes**:
|
|
- `GET /api/channels/:id/vods` - List creator's VODs
|
|
- `GET /api/vods/:id` - Get VOD details
|
|
- `PUT /api/vods/:id` - Update VOD (title, description, visibility)
|
|
- `DELETE /api/vods/:id` - Delete VOD
|
|
- `GET /api/vods/:id/comments` - VOD comments (Phase 5)
|
|
|
|
**Background Jobs**:
|
|
- Record stream when LIVE status set
|
|
- Stop recording when stream ENDED
|
|
- Generate thumbnail at 25% mark
|
|
- Index VOD metadata
|
|
|
|
**Webhook from Cloudflare/Mux**:
|
|
```typescript
|
|
// pages/api/webhooks/recording-ready.ts
|
|
export async function POST(req) {
|
|
const event = req.body
|
|
|
|
if (event.type === 'video.ready') {
|
|
// Update VOD status to READY
|
|
await db.vod.update({
|
|
where: { streamId: event.streamId },
|
|
data: {
|
|
hlsUrl: event.hlsUrl,
|
|
mp4Url: event.downloadUrl,
|
|
duration: event.duration,
|
|
}
|
|
})
|
|
}
|
|
}
|
|
```
|
|
|
|
**Deliverables**:
|
|
- [ ] Recording enabled on all streams
|
|
- [ ] VODs indexed in database
|
|
- [ ] VOD list page functional
|
|
- [ ] Webhook processing
|
|
|
|
---
|
|
|
|
#### User Story 3.1.2: VOD Playback & Library
|
|
```
|
|
AS A viewer
|
|
I WANT to watch VODs
|
|
SO THAT I can catch up on streams I missed
|
|
```
|
|
|
|
**Tasks**:
|
|
- [ ] VOD library page (`/channel/{username}/vods`)
|
|
- [ ] VOD playback player (reuse HLS player)
|
|
- [ ] VOD comments (Phase 5)
|
|
- [ ] VOD download link (optional)
|
|
- [ ] Progress tracking (watch time)
|
|
|
|
**Page Structure**:
|
|
```
|
|
/channel/[username]/vods
|
|
├── VOD List
|
|
│ ├── Grid/List toggle
|
|
│ ├── Sort: newest, trending, watched
|
|
│ ├── Filter: date range
|
|
│ └── Search VODs
|
|
├── VOD Cards
|
|
│ ├── Thumbnail
|
|
│ ├── Title
|
|
│ ├── Duration
|
|
│ ├── View count
|
|
│ ├── Upload date
|
|
│ └── Like button
|
|
└── Pagination (12 per page)
|
|
```
|
|
|
|
**VOD Playback Page**:
|
|
```
|
|
/vods/[vodId]
|
|
├── Player (full width, sticky controls)
|
|
├── Sidebar:
|
|
│ ├── VOD Info (title, date, views)
|
|
│ ├── Creator Card + Follow
|
|
│ ├── Like/Share buttons
|
|
│ └── Comments (Phase 5)
|
|
└── Related VODs (same channel)
|
|
```
|
|
|
|
**Watch Progress Tracking**:
|
|
```prisma
|
|
model WatchProgress {
|
|
id String @id @default(cuid())
|
|
userId String
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
vodId String
|
|
vod VOD @relation(fields: [vodId], references: [id], onDelete: Cascade)
|
|
|
|
lastPosition Int // Seconds watched
|
|
percentage Float // 0-100
|
|
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
@@unique([userId, vodId])
|
|
}
|
|
```
|
|
|
|
**API Routes**:
|
|
- `GET /api/channels/:id/vods` - List VODs
|
|
- `GET /api/vods/:id` - Get VOD details
|
|
- `POST /api/watch-progress` - Save watch progress
|
|
- `GET /api/watch-progress` - Get user's watch history
|
|
|
|
**Components**:
|
|
```
|
|
components/vod/
|
|
├── VODLibrary.tsx
|
|
├── VODGrid.tsx
|
|
├── VODCard.tsx
|
|
├── VODPlayer.tsx
|
|
├── VODInfo.tsx
|
|
├── WatchProgressBar.tsx
|
|
└── RelatedVODs.tsx
|
|
```
|
|
|
|
**Deliverables**:
|
|
- [ ] VOD library page
|
|
- [ ] VOD playback working
|
|
- [ ] Watch progress tracking
|
|
- [ ] Search/filter working
|
|
|
|
---
|
|
|
|
#### User Story 3.1.3: Watch History & Recommendations
|
|
```
|
|
AS A viewer
|
|
I WANT to access my watch history
|
|
SO THAT I can resume videos and get recommendations
|
|
```
|
|
|
|
**Tasks**:
|
|
- [ ] Watch history page
|
|
- [ ] Resume button (jump to last position)
|
|
- [ ] Clear history option
|
|
- [ ] Recommended VODs from followed creators
|
|
- [ ] "Continue Watching" section
|
|
|
|
**Routes**:
|
|
- `GET /api/watch-history` - User's watch history
|
|
- `DELETE /api/watch-history/:vodId` - Remove from history
|
|
- `POST /api/watch-history/clear` - Clear all
|
|
|
|
**Deliverables**:
|
|
- [ ] Watch history page
|
|
- [ ] Resume functionality
|
|
- [ ] Continue watching section
|
|
|
|
---
|
|
|
|
### Sprint 3.2: Clip Creation
|
|
**Duration**: Days 6-10 | **Team**: 2 devs
|
|
|
|
#### User Story 3.2.1: In-Stream Clip Button
|
|
```
|
|
AS A viewer
|
|
I WANT to create clips while watching
|
|
SO THAT I can share viral moments with others
|
|
```
|
|
|
|
**Tasks**:
|
|
- [ ] Add clip button to stream player
|
|
- [ ] Auto-capture last 30 seconds (configurable)
|
|
- [ ] Show clip creation feedback
|
|
- [ ] Redirect to clip editor after creation
|
|
- [ ] Display creation status
|
|
|
|
**Clip Capture Logic**:
|
|
```typescript
|
|
// When user clicks clip button
|
|
const clipStream = async (streamId: string) => {
|
|
const now = Date.now()
|
|
|
|
// Clip last 30 seconds of HLS stream
|
|
const clipData = {
|
|
vodId: streamId, // Use stream as VOD
|
|
startTime: Math.max(0, currentPlaybackPosition - 30),
|
|
endTime: currentPlaybackPosition,
|
|
title: `Clip from ${creatorName}'s stream`,
|
|
}
|
|
|
|
// Queue clip generation job
|
|
await fetch('/api/clips', {
|
|
method: 'POST',
|
|
body: JSON.stringify(clipData)
|
|
})
|
|
}
|
|
```
|
|
|
|
**Deliverables**:
|
|
- [ ] Clip button visible on stream player
|
|
- [ ] Clip auto-capture working
|
|
- [ ] User feedback on clip creation
|
|
|
|
---
|
|
|
|
#### User Story 3.2.2: Clip Editor
|
|
```
|
|
AS A creator
|
|
I WANT to edit and publish clips
|
|
SO THAT I can curate my best moments
|
|
```
|
|
|
|
**Tasks**:
|
|
- [ ] Build clip editor page (`/clips/[clipId]/edit`)
|
|
- [ ] Timeline with trim handles
|
|
- [ ] Preview scrubber
|
|
- [ ] Title/description editor
|
|
- [ ] Thumbnail editor (select frame)
|
|
- [ ] One-click publish to Twitter/TikTok (Phase 3B)
|
|
|
|
**Page Structure**:
|
|
```
|
|
/clips/[clipId]/edit
|
|
├── Video Preview
|
|
│ ├── Timeline (full VOD)
|
|
│ ├── Clip section highlighted
|
|
│ ├── Trim handles (drag to adjust)
|
|
│ └── Play button
|
|
├── Edit Panel
|
|
│ ├── Title input
|
|
│ ├── Description textarea
|
|
│ ├── Thumbnail selector (frame picker)
|
|
│ ├── Tags input (Phase 2B)
|
|
│ └── Visibility toggle
|
|
└── Publish Action
|
|
├── Preview button
|
|
├── Save draft button
|
|
└── Publish button
|
|
```
|
|
|
|
**Components**:
|
|
```
|
|
components/clips/
|
|
├── ClipEditor.tsx
|
|
├── ClipTimeline.tsx
|
|
├── TrimHandles.tsx
|
|
├── FrameSelector.tsx
|
|
├── PreviewPlayer.tsx
|
|
└── PublishPanel.tsx
|
|
```
|
|
|
|
**API Routes**:
|
|
- `PUT /api/clips/:id` - Update clip metadata
|
|
- `POST /api/clips/:id/generate` - Generate clip video
|
|
- `POST /api/clips/:id/publish` - Publish clip
|
|
- `POST /api/clips/:id/thumbnail` - Update thumbnail
|
|
|
|
**Background Job**:
|
|
- FFmpeg or Cloudflare Stream API to cut video segment
|
|
- Generate MP4 and thumbnail
|
|
- Upload to R2
|
|
- Update clip status to READY
|
|
|
|
**Deliverables**:
|
|
- [ ] Clip editor page
|
|
- [ ] Trim functionality
|
|
- [ ] Preview working
|
|
- [ ] Publish button functional
|
|
|
|
---
|
|
|
|
#### User Story 3.2.3: Clip Sharing & Discovery
|
|
```
|
|
AS A creator
|
|
I WANT my clips shared widely
|
|
SO THAT I grow my audience
|
|
```
|
|
|
|
**Tasks**:
|
|
- [ ] Clip sharing page (`/clips/:id`)
|
|
- [ ] Social media share buttons
|
|
- [ ] Embed code for websites
|
|
- [ ] Clip analytics
|
|
- [ ] Trending clips section
|
|
|
|
**Clip Page Structure**:
|
|
```
|
|
/clips/[clipId]
|
|
├── Header: Clip title + creator
|
|
├── Video Player
|
|
├── Share Buttons (Twitter, TikTok, Discord, etc)
|
|
├── Embed Code (iframe)
|
|
├── Stats (views, likes, shares, datetime)
|
|
├── Creator Card + Channel Link
|
|
├── Comments (Phase 5)
|
|
└── Related Clips (trending from channel)
|
|
```
|
|
|
|
**Routes**:
|
|
- `GET /api/clips/trending` - Trending clips
|
|
- `GET /api/clips/:id/stats` - Clip analytics
|
|
- `GET /api/channels/:id/clips` - Creator's clips
|
|
- `POST /api/clips/:id/like` - Like clip (Phase 5)
|
|
|
|
**Deliverables**:
|
|
- [ ] Clip sharing page
|
|
- [ ] Share buttons working
|
|
- [ ] Trending clips showing
|
|
- [ ] Embed working
|
|
|
|
---
|
|
|
|
### Sprint 3.3: Advanced Analytics
|
|
**Duration**: Days 11-15 | **Team**: 2 devs
|
|
|
|
#### User Story 3.3.1: Analytics Dashboard
|
|
```
|
|
AS A creator
|
|
I WANT detailed analytics
|
|
SO THAT I can understand and grow my audience
|
|
```
|
|
|
|
**Tasks**:
|
|
- [ ] Build analytics dashboard (`/dashboard/analytics`)
|
|
- [ ] Implement data collection
|
|
- [ ] Graphs and charts
|
|
- [ ] Filter by date range
|
|
- [ ] Export analytics (CSV)
|
|
|
|
**Analytics Metrics**:
|
|
|
|
*Stream-level*:
|
|
- Stream duration
|
|
- Peak concurrent viewers
|
|
- Average viewers
|
|
- Total views
|
|
- Chat messages
|
|
- Follow gains
|
|
- Conversion rate (viewers → followers)
|
|
|
|
*Channel-level*:
|
|
- Total hours streamed
|
|
- Total views (all time)
|
|
- Average peak viewers
|
|
- Growth (weekly/monthly)
|
|
- Most watched category
|
|
- Best performing streams
|
|
- Top clips
|
|
|
|
**Database Schema**:
|
|
```prisma
|
|
model StreamAnalytics {
|
|
id String @id @default(cuid())
|
|
streamId String @unique
|
|
stream Stream @relation(fields: [streamId], references: [id], onDelete: Cascade)
|
|
|
|
// Viewers
|
|
peakConcurrent Int
|
|
avgConcurrent Int
|
|
uniqueViewers Int
|
|
totalWatchMinutes Int
|
|
|
|
// Engagement
|
|
chatMessages Int
|
|
newFollowers Int
|
|
conversionRate Float // followers gained / unique viewers
|
|
|
|
// VOD
|
|
vodViews Int @default(0)
|
|
vodEngagement Float @default(0)
|
|
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
}
|
|
|
|
model ViewCountSnapshot {
|
|
id String @id @default(cuid())
|
|
streamId String
|
|
stream Stream @relation(fields: [streamId], references: [id], onDelete: Cascade)
|
|
|
|
viewCount Int
|
|
timestamp DateTime
|
|
|
|
@@index([streamId, timestamp])
|
|
}
|
|
```
|
|
|
|
**Chart Components** (using Recharts or Chart.js):
|
|
```
|
|
components/analytics/
|
|
├── AnalyticsDashboard.tsx
|
|
├── ViewersOverTime.tsx
|
|
├── PeakViewersChart.tsx
|
|
├── EngagementChart.tsx
|
|
├── TopStreamsTable.tsx
|
|
├── ChannelGrowthChart.tsx
|
|
└── ConversionRateMetric.tsx
|
|
```
|
|
|
|
**API Routes**:
|
|
- `GET /api/analytics/streams/:id` - Stream analytics
|
|
- `GET /api/analytics/channels/:id` - Channel analytics
|
|
- `GET /api/analytics/charts/viewers` - Viewer count time series
|
|
- `POST /api/analytics/export` - CSV export
|
|
|
|
**Data Collection**:
|
|
```typescript
|
|
// Collect viewer count every minute
|
|
setInterval(async () => {
|
|
const activeStreams = await db.stream.findMany({
|
|
where: { status: 'LIVE' }
|
|
})
|
|
|
|
for (let stream of activeStreams) {
|
|
await db.viewCountSnapshot.create({
|
|
data: {
|
|
streamId: stream.id,
|
|
viewCount: stream.viewerCount,
|
|
timestamp: new Date(),
|
|
}
|
|
})
|
|
}
|
|
}, 60000)
|
|
```
|
|
|
|
**Deliverables**:
|
|
- [ ] Analytics dashboard built
|
|
- [ ] Charts displaying correctly
|
|
- [ ] Data collection working
|
|
- [ ] Date range filtering
|
|
|
|
---
|
|
|
|
#### User Story 3.3.2: Stream Health Monitoring
|
|
```
|
|
AS A creator
|
|
I WANT to see stream health metrics
|
|
SO THAT I can fix quality issues during live streaming
|
|
```
|
|
|
|
**Tasks**:
|
|
- [ ] Display bitrate, FPS, resolution
|
|
- [ ] Connection quality indicator
|
|
- [ ] Bitrate graph
|
|
- [ ] Issue alerts (bitrate drop, connection loss)
|
|
- [ ] Guide to fix issues
|
|
|
|
**Metrics**:
|
|
```typescript
|
|
interface StreamHealth {
|
|
uptime: number // % uptime
|
|
bitrate: number // Kbps
|
|
fps: number // Frames per second
|
|
resolution: string // 1920x1080
|
|
latency: number // ms from ingest to edge
|
|
packetLoss: number // % packets lost
|
|
bufferingEvents: number // Number of times player buffered
|
|
}
|
|
```
|
|
|
|
**Dashboard Widget**:
|
|
```
|
|
Stream Health Status
|
|
├── Connection: Excellent (green indicator)
|
|
├── Bitrate: 5000 kbps (target 5500) [graph]
|
|
├── FPS: 60 [icon good]
|
|
├── Resolution: 1920x1080
|
|
├── Latency: 1.2s (acceptable range)
|
|
└── Alerts: None
|
|
```
|
|
|
|
**Real-time Updates** (via WebSocket):
|
|
```typescript
|
|
socket.on('stream:health-update', (health) => {
|
|
updateHealthMetrics(health)
|
|
})
|
|
```
|
|
|
|
**Deliverables**:
|
|
- [ ] Health metrics displayed correctly
|
|
- [ ] Real-time updates working
|
|
- [ ] Alerts triggering
|
|
- [ ] Helpful tooltips
|
|
|
|
---
|
|
|
|
#### User Story 3.3.3: VOD & Clip Analytics
|
|
```
|
|
AS A creator
|
|
I WANT to see how my VODs and clips perform
|
|
SO THAT I can create more of the best content
|
|
```
|
|
|
|
**Tasks**:
|
|
- [ ] VOD view count tracking
|
|
- [ ] Clip performance metrics
|
|
- [ ] Trending clips dashboard
|
|
- [ ] Best performing content
|
|
|
|
**Metrics**:
|
|
- VOD views, engagement, average watch time
|
|
- Clip views, likes, shares, embeds
|
|
- Which streams generate most clips
|
|
- Which clips drive most traffic back to channel
|
|
|
|
**API Routes**:
|
|
- `GET /api/vods/:id/analytics`
|
|
- `GET /api/clips/:id/analytics`
|
|
- `GET /api/channels/:id/top-vods`
|
|
- `GET /api/channels/:id/top-clips`
|
|
|
|
**Deliverables**:
|
|
- [ ] VOD analytics working
|
|
- [ ] Clip analytics showing
|
|
- [ ] Top content identified
|
|
|
|
---
|
|
|
|
### Sprint 3.4: Polish & Optimization
|
|
**Duration**: Days 16-20 | **Team**: 2 devs
|
|
|
|
#### Performance Optimization
|
|
- [ ] Optimize analytics queries (database indexes)
|
|
- [ ] Cache analytics data (Redis)
|
|
- [ ] Lazy load charts
|
|
- [ ] Implement pagination on clip lists
|
|
|
|
#### Mobile Responsiveness
|
|
- [ ] Mobile VOD player
|
|
- [ ] Mobile analytics dashboard
|
|
- [ ] Mobile clip editor
|
|
- [ ] Touch-friendly controls
|
|
|
|
#### Testing
|
|
- [ ] Unit tests for analytics calculations
|
|
- [ ] E2E tests: record stream → VOD created → viewable
|
|
- [ ] Clip creation and playback tests
|
|
- [ ] Analytics accuracy validation
|
|
|
|
---
|
|
|
|
## Database Schema - Phase 3 Updates
|
|
|
|
**New Models**:
|
|
```prisma
|
|
model VOD { /* ... */ }
|
|
model Clip { /* ... */ }
|
|
model StreamAnalytics { /* ... */ }
|
|
model ViewCountSnapshot { /* ... */ }
|
|
model WatchProgress { /* ... */ }
|
|
```
|
|
|
|
**Updated Models**:
|
|
```prisma
|
|
model Stream {
|
|
// Add VOD relation
|
|
vod VOD?
|
|
}
|
|
|
|
model Channel {
|
|
// Add VOD and clip relations
|
|
vods VOD[]
|
|
}
|
|
|
|
model User {
|
|
// Add clip relation
|
|
clips Clip[]
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## API Routes - Phase 3 Additions
|
|
|
|
### VODs
|
|
- `GET /api/channels/:id/vods`
|
|
- `GET /api/vods/:id`
|
|
- `PUT /api/vods/:id`
|
|
- `DELETE /api/vods/:id`
|
|
- `POST /api/watch-progress`
|
|
- `GET /api/watch-progress`
|
|
|
|
### Clips
|
|
- `POST /api/clips` (create from stream/VOD)
|
|
- `GET /api/clips/:id`
|
|
- `PUT /api/clips/:id`
|
|
- `DELETE /api/clips/:id`
|
|
- `POST /api/clips/:id/generate`
|
|
- `GET /api/clips/trending`
|
|
- `GET /api/channels/:id/clips`
|
|
|
|
### Analytics
|
|
- `GET /api/analytics/streams/:id`
|
|
- `GET /api/analytics/channels/:id`
|
|
- `GET /api/analytics/charts/viewers`
|
|
- `POST /api/analytics/export`
|
|
|
|
---
|
|
|
|
## Components - Phase 3 Additions
|
|
|
|
### VOD
|
|
```
|
|
components/vod/
|
|
├── VODLibrary.tsx
|
|
├── VODCard.tsx
|
|
├── VODPlayer.tsx
|
|
└── WatchProgressBar.tsx
|
|
```
|
|
|
|
### Clips
|
|
```
|
|
components/clips/
|
|
├── ClipEditor.tsx
|
|
├── ClipTimeline.tsx
|
|
├── TrimHandles.tsx
|
|
├── ClipCard.tsx
|
|
└── TrendingClips.tsx
|
|
```
|
|
|
|
### Analytics
|
|
```
|
|
components/analytics/
|
|
├── AnalyticsDashboard.tsx
|
|
├── ViewersChart.tsx
|
|
├── EngagementChart.tsx
|
|
├── StreamHealth.tsx
|
|
└── TopContentTable.tsx
|
|
```
|
|
|
|
---
|
|
|
|
## Third-Party Services
|
|
|
|
### Video Processing
|
|
- **Cloudflare Stream or Mux**: Recording/clipping
|
|
- **FFmpeg** (self-hosted): Optional for additional processing
|
|
|
|
### Charts
|
|
- **Recharts** or **Chart.js**: Graphing library
|
|
|
|
### Storage
|
|
- **Cloudflare R2**: VOD and clip storage (already in Phase 1)
|
|
|
|
---
|
|
|
|
## Success Metrics
|
|
|
|
### VOD Metrics
|
|
- [ ] 100+ VODs created
|
|
- [ ] 50k+ total VOD views
|
|
- [ ] 10+ min average VOD watch time
|
|
- [ ] 30% VOD engagement rate
|
|
|
|
### Clip Metrics
|
|
- [ ] 50+ clips created
|
|
- [ ] 10k+ total clip views
|
|
- [ ] 5% of viewers create clips
|
|
- [ ] 100+ clips shared to social media
|
|
|
|
### Analytics Metrics
|
|
- [ ] 90%+ creators use analytics dashboard
|
|
- [ ] Charts load in <2s
|
|
- [ ] 0 analytics data loss
|
|
- [ ] Trending clips updated hourly
|
|
|
|
### Performance Metrics
|
|
- [ ] VOD playback <2s latency
|
|
- [ ] Clip generation <2 minutes
|
|
- [ ] Analytics queries <1s
|
|
- [ ] Database stays <100GB
|
|
|
|
---
|
|
|
|
---
|
|
|
|
## Phase 3 Timeline
|
|
|
|
| Week | Sprint | Focus |
|
|
|------|--------|-------|
|
|
| 9 | 3.1 | VOD archival & playback |
|
|
| 10 | 3.2 | Clip creation & editing |
|
|
| 11 | 3.3 | Advanced analytics |
|
|
| 12-13 | 3.4 | Polish & optimization |
|
|
|
|
---
|
|
|
|
## Phase 3 Completion Checklist
|
|
|
|
- [ ] VOD archival working automatically
|
|
- [ ] VOD playback page functional
|
|
- [ ] Clip creation from stream working
|
|
- [ ] Clip editor with trim working
|
|
- [ ] Clip sharing page built
|
|
- [ ] Analytics dashboard showing data
|
|
- [ ] Stream health metrics displaying
|
|
- [ ] Mobile responsive
|
|
- [ ] Performance optimized
|
|
- [ ] Tests passing
|
|
- [ ] Deployed to production
|
|
- [ ] 100+ VODs archived
|
|
- [ ] 50+ clips created
|
|
|
|
---
|
|
|
|
**Phase 3 Estimated Completion**: Week 13 (by April 18, 2025)
|
|
**Next Phase**: Phase 4 - Monetization (April 21, 2025)
|
|
|
|
See [PHASE_4_MONETIZATION.md](PHASE_4_MONETIZATION.md) for Phase 4 details.
|