# 🎬 Diarization Visualizer

A modern web-based visualization tool for exploring speaker diarization results with interactive video playback, segment filtering, and testing utilities.

## Features

### 🎥 Video Player
- HTML5 video with HTTP Range support for instant seeking
- Keyboard controls: Space (play/pause), J/K/L (±10s), Arrow keys (±5s)
- Frame-step navigation with comma/period keys
- Playback rate control (0.5x - 2x)
- Volume control with keyboard shortcuts

### 📊 Segment Timeline
- SVG-rendered timeline with speaker-colored segments
- Zoom levels: 1x, 2x, 5x, 10x with horizontal scrolling
- Click on segment to seek video
- Hover tooltips with segment details
- Visual distinction for unusable segments (hatched pattern)
- Playhead indicator following current video position

### 🔍 Filtering System
- **By Speaker**: Multi-select with speaker color indicators
- **By Status**: Checkboxes for usable/unusable segments
- **By Duration**: Range slider (min-max seconds)
- **By Confidence**: Range slider (0-100%)
- Quick filters: "Usable only", "Long (>5s)", "Short (<2s)"
- All filters applied client-side for instant response

### 📈 Statistics Panel
- Total segments / Usable segments
- Total duration / Usable duration  
- Usable percentage progress bar
- Per-speaker breakdown with duration bars
- Filtered vs. original statistics comparison

### 🧪 Testing Tools
- **Random Jump**: Jump to random usable segment
- **Sequential Playback**: Navigate through filtered segments
- **Previous/Next**: Segment-by-segment navigation
- **Export**: Download filtered segments as JSON or CSV

### 🔄 Live Processing
- Submit new YouTube URLs for processing
- Real-time progress tracking (polling)
- Pipeline stage indicators
- Auto-redirect on completion

## Quick Start

### Prerequisites
- Node.js 18+ (for frontend)
- Python 3.11+ with venv (for backend)
- Backend requirements installed (`pip install -r backend/requirements.txt`)

### Start Both Services

```bash
cd visualizer

# Make scripts executable (first time only)
chmod +x start.sh stop.sh

# Start both backend and frontend
./start.sh
```

**Access:**
- **Frontend**: http://localhost:3000
- **Backend API**: http://localhost:8000
- **API Docs**: http://localhost:8000/docs

### Stop Services

```bash
./stop.sh
```

### Start Manually

```bash
# Terminal 1: Backend
cd visualizer/backend
source ../../venv/bin/activate
python main.py

# Terminal 2: Frontend
cd visualizer/frontend
npm install  # first time only
npm run dev
```

## Architecture

```
┌─────────────────────────────────────────────────────────────┐
│                     Frontend (Next.js)                       │
│                     localhost:3000                           │
├─────────────────────────────────────────────────────────────┤
│  Home Page (/)              │  Video Detail (/video/[id])   │
│  ├── Video Grid             │  ├── VideoPlayer              │
│  ├── Thumbnails             │  ├── SegmentTimeline          │
│  └── Quick Stats            │  ├── FilterPanel              │
│                             │  ├── SegmentList              │
│  Process Page (/process)    │  ├── StatisticsPanel          │
│  ├── URL Input              │  └── TestingTools             │
│  └── Progress Tracker       │                               │
└─────────────────────────────────────────────────────────────┘
                              │
                              │ HTTP/REST
                              ▼
┌─────────────────────────────────────────────────────────────┐
│                     Backend (FastAPI)                        │
│                     localhost:8000                           │
├─────────────────────────────────────────────────────────────┤
│  GET  /api/videos           - List all videos               │
│  GET  /api/videos/{id}      - Video details + segments      │
│  GET  /api/videos/{id}/stream - Video streaming (Range)     │
│  GET  /api/videos/{id}/audio  - Audio streaming             │
│  GET  /api/videos/{id}/thumbnail - Thumbnail image          │
│  POST /api/process          - Submit new URL                │
│  GET  /api/jobs/{id}        - Job status                    │
└─────────────────────────────────────────────────────────────┘
                              │
                              │ File System
                              ▼
┌─────────────────────────────────────────────────────────────┐
│                    Data Directory                            │
│               data/fast_output_v6/{video_id}/               │
├─────────────────────────────────────────────────────────────┤
│  metadata.json     - Segments, speakers, timestamps         │
│  {video_id}.mp4    - Downloaded video file                  │
│  {video_id}.wav    - Audio file (16kHz mono)               │
│  thumbnail.jpg     - Video thumbnail                        │
└─────────────────────────────────────────────────────────────┘
```

## File Structure

```
visualizer/
├── backend/
│   ├── main.py              # FastAPI entry point
│   ├── openapi.json         # API specification
│   ├── requirements.txt     # Python dependencies
│   ├── routes/
│   │   ├── videos.py        # Video endpoints (list, details, stream)
│   │   └── pipeline.py      # Processing endpoints
│   └── services/
│       └── video_downloader.py  # YouTube download logic
├── frontend/
│   ├── app/
│   │   ├── layout.tsx       # Root layout with nav
│   │   ├── page.tsx         # Home page (video grid)
│   │   ├── video/[id]/page.tsx  # Video detail page
│   │   └── process/page.tsx # URL processing page
│   ├── components/
│   │   ├── VideoPlayer.tsx  # HTML5 video with controls
│   │   ├── SegmentTimeline.tsx  # SVG timeline
│   │   ├── FilterPanel.tsx  # Filter controls
│   │   ├── SegmentList.tsx  # Scrollable segment table
│   │   ├── StatisticsPanel.tsx  # Quality metrics
│   │   └── TestingTools.tsx # Random/sequential tools
│   ├── lib/
│   │   ├── api.ts           # API client
│   │   ├── types.ts         # TypeScript interfaces
│   │   └── utils.ts         # Formatting, colors
│   ├── package.json
│   ├── tailwind.config.ts   # Dark theme config
│   └── tsconfig.json
├── start.sh                 # Start both services
├── stop.sh                  # Stop services
└── README.md                # This file
```

## Keyboard Shortcuts

| Key | Action |
|-----|--------|
| `Space` | Play/Pause |
| `K` | Play/Pause |
| `J` | Rewind 10 seconds |
| `L` | Forward 10 seconds |
| `←` | Rewind 5 seconds |
| `→` | Forward 5 seconds |
| `↑` | Volume up |
| `↓` | Volume down |
| `,` | Previous frame |
| `.` | Next frame |
| `[` | Previous segment |
| `]` | Next segment |

## API Reference

See http://localhost:8000/docs for interactive API documentation (Swagger UI).

### Key Endpoints

#### List Videos
```bash
curl http://localhost:8000/api/videos
```

#### Get Video Details
```bash
curl http://localhost:8000/api/videos/{video_id}
```

#### Stream Video
```bash
curl -H "Range: bytes=0-" http://localhost:8000/api/videos/{video_id}/stream
```

#### Process New URL
```bash
curl -X POST http://localhost:8000/api/process \
  -H "Content-Type: application/json" \
  -d '{"url": "https://www.youtube.com/watch?v=VIDEO_ID"}'
```

## Configuration

### Environment Variables

| Variable | Default | Description |
|----------|---------|-------------|
| `NEXT_PUBLIC_API_URL` | `http://localhost:8000` | Backend API URL |

### Backend Configuration

The backend reads processed videos from `data/fast_output_v6/`. This path is configured in `backend/routes/videos.py`.

## Troubleshooting

### Backend won't start
- Check if port 8000 is in use: `lsof -i:8000`
- Verify venv is activated
- Check backend.log for errors

### Frontend won't start
- Check if port 3000 is in use: `lsof -i:3000`
- Run `npm install` in frontend directory
- Check frontend.log for errors

### Video won't play
- Ensure video file exists in `data/fast_output_v6/{video_id}/`
- Check browser console for CORS errors
- Verify backend is running and accessible

### No videos showing
- Process at least one video with the main pipeline first
- Check `data/fast_output_v6/` for output directories
- Each video needs `metadata.json` and media files

## Development

### Frontend Development
```bash
cd frontend
npm run dev    # Development server with hot reload
npm run build  # Production build
npm run lint   # Run linter
```

### Adding New Components
1. Create component in `frontend/components/`
2. Add TypeScript interfaces in `frontend/lib/types.ts`
3. Import and use in page components

### Adding New API Endpoints
1. Add route in `backend/routes/`
2. Update OpenAPI spec in `backend/openapi.json`
3. Add client function in `frontend/lib/api.ts`
4. Add TypeScript types in `frontend/lib/types.ts`

## Recent Fixes (Dec 19, 2025)

### Pipeline Integration Fix
**Issue**: When processing new videos via `/api/process`, the pipeline would complete but videos wouldn't appear in the list.

**Root Cause**: The backend's `pipeline.py` used `Config().output_dir` which is a **relative path** (`data/fast_output_v6`). When the backend runs from `visualizer/backend/`, this resolved to `visualizer/backend/data/fast_output_v6` instead of the correct `/workspace/newPipeline/data/fast_output_v6`.

**Fix**: Added `get_absolute_output_dir()` function in `backend/routes/pipeline.py` that converts the relative path to absolute using the project root:
```python
def get_absolute_output_dir() -> Path:
    """Get absolute path to output directory from project root."""
    config = Config()
    return (root_dir / config.output_dir).resolve()
```

### Other Fixes Applied
- **Metadata field name handling**: Backend now handles both `video_title`/`title` and `original_duration`/`duration` field names
- **Video player fallback**: Falls back to audio-only mode when MP4 file is missing  
- **FilterPanel nested button**: Fixed HTML validation error with nested buttons

## License

MIT License - Part of the Speaker Diarization Pipeline project.
