aethex.live/docs/PHASE_3_CREATOR_TOOLS.md

20 KiB

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:

// 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:

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:

// 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:

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:

// 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:

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:

// 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:

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):

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:

model VOD { /* ... */ }
model Clip { /* ... */ }
model StreamAnalytics { /* ... */ }
model ViewCountSnapshot { /* ... */ }
model WatchProgress { /* ... */ }

Updated Models:

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 for Phase 4 details.