An entry for the streamplace vod showcase
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Streamhut Frontend#

Nuxt 4 web application for browsing and watching videos on Streamhut.

Features#

  • Video Playback - HLS streaming with hls.js
  • Hover Previews - YouTube-style sprite sheet previews
  • Creator Profiles - Browse videos by creator
  • Watch History - Local storage tracking of watched videos
  • Search - Filter videos by title
  • Social Sharing - Share videos and creator profiles with rich link previews
  • Responsive Design - Works on desktop and mobile

Pages#

Route Description
/ Home page with featured video, latest, and recommended sections
/watch?v={uri} Video player with related videos sidebar
/profile/{did} Creator profile with their videos
/search?q={query} Search results
/docs Documentation

Development#

# Install dependencies
bun install

# Start dev server
bun run dev

# Build for production
bun run build

# Generate static site
bun run generate

Configuration#

Create .env in the frontend directory:

# Required: at-run runner URL
NUXT_PUBLIC_RUNNER_URL=https://at-run.example.com

# Required: Bundle path for VOD API
NUXT_PUBLIC_BUNDLE_PATH=/bundle/did:plc:xxx/atmosphereconf-vod/latest

Architecture#

apps/frontend/
├── app/
│   ├── pages/
│   │   ├── index.vue        # Home page
│   │   ├── watch.vue        # Video player
│   │   ├── search.vue       # Search results
│   │   └── profile/
│   │       └── [did].vue    # Creator profile
│   ├── components/
│   │   └── VideoCard.vue    # Video thumbnail with hover preview
│   ├── composables/
│   │   ├── useApi.ts        # VOD API client
│   │   ├── useWatchHistory.ts # Local watch history
│   │   └── useShare.ts      # Social sharing utilities
│   └── types/
│       └── index.ts         # TypeScript types
├── nuxt.config.ts           # Nuxt configuration
└── package.json

Composables#

useApi()#

API client for the VOD backend.

const { 
  listVideos,           // Fetch video list
  batchCheckMetadata,   // Check which videos have thumbnails
  batchGetProfiles,     // Fetch creator profiles
  getPlaylistUrl,       // Get HLS playlist URL
  formatDuration,       // Format nanoseconds to "1:23:45"
} = useApi()

useWatchHistory()#

Track watched videos in localStorage.

const {
  recordWatch,          // Record a watch session
  getContinueWatching,  // Get videos with progress < 90%
  sortByRecommendation, // Sort videos by watch history
} = useWatchHistory()

useShare()#

Share videos and creators.

const {
  shareVideo,    // Copy/share video link
  shareCreator,  // Copy/share creator link
} = useShare()

Video Player#

Uses hls.js for HLS playback:

import Hls from 'hls.js'

const hls = new Hls()
hls.loadSource(playlistUrl)
hls.attachMedia(videoElement)

Hover Previews#

The VideoCard component shows sprite previews on hover:

  1. Fetches sprite VTT from /getVtt?uri=...
  2. Parses timestamp-to-coordinates mapping
  3. On hover, cycles through frames using CSS background-position

Static Generation#

The app uses ssr: false and generates a static SPA:

bun run generate

Output goes to .output/public/ (symlinked to dist/).

Styling#

  • CSS custom properties for theming (--bg, --text, --border, etc.)
  • Dark theme by default
  • Instrument Serif for headings
  • Inter for body text
  • Responsive breakpoints at 600px, 800px, 1000px, 1200px