Skip to content

mieweb/pulseclip

Repository files navigation

Pulse Clip

Image

📖 Implementation Details | 🎯 The MIE Way

Features

  • 🎙️ Audio & Video Upload - Drag and drop support for common formats (MP3, WAV, MP4, MOV)
  • 🔌 Pluggable Providers - Provider-agnostic architecture (AssemblyAI implemented)
  • 📝 Word-Level Timestamps - Precise timestamp tracking for every word
  • 🎯 Interactive Transcript - Click any word to seek media playback
  • 🔍 Raw Data Access - View original provider responses for debugging
  • 🎨 Normalized Schema - Provider-agnostic transcript format for UI consistency

Architecture

graph TB
    Client[React Client]
    Server[Express Server]
    Registry[Provider Registry]
    AI[AssemblyAI Provider]
    
    Client -->|Upload File| Server
    Client -->|Request Transcription| Server
    Server -->|Route to Provider| Registry
    Registry -->|Delegate| AI
    AI -->|Normalize & Return| Server
    Server -->|Transcript + Raw| Client
    
    classDef frontend fill:#e1f5ff,stroke:#01579b
    classDef backend fill:#fff3e0,stroke:#e65100
    classDef provider fill:#f3e5f5,stroke:#4a148c
    
    class Client frontend
    class Server,Registry backend
    class AI provider
Loading

Project Structure

pulseclip/
├── client/                 # React frontend
│   ├── src/
│   │   ├── components/    # UI components
│   │   │   ├── FileUpload.tsx
│   │   │   ├── MediaPlayer.tsx
│   │   │   └── TranscriptViewer.tsx
│   │   ├── App.tsx        # Main application
│   │   └── types.ts       # TypeScript types
│   └── package.json
├── server/                 # Express backend
│   ├── src/
│   │   ├── providers/     # Transcription providers
│   │   │   ├── assemblyai.ts
│   │   │   └── registry.ts
│   │   ├── types/         # TypeScript types
│   │   │   └── transcription.ts
│   │   ├── cache.ts       # Transcription cache
│   │   ├── featured.ts    # Featured pulses management
│   │   └── index.ts       # Server entry point
│   ├── artipods/          # Artipod storage (gitignored)
│   │   └── {uuid}/        # Each artipod folder contains:
│   │       ├── media.ext      # Original media file
│   │       ├── thumbnail.png  # Thumbnail image
│   │       └── (future: transcript.json, beats.json, short.mp4)
│   ├── data/              # Persistent data
│   │   └── featured.json  # Featured pulses list
│   └── package.json
└── package.json           # Workspace root

Getting Started

Prerequisites

Installation

  1. Clone the repository:
git clone <repository-url>
cd voicepoc-
  1. Install dependencies:
npm install
  1. Set up environment variables:
cd server
cp .env.example .env
# Edit .env and add your ASSEMBLYAI_API_KEY
  1. Start the development servers:
# From the root directory
npm run dev

This will start:

Usage

  1. Open http://localhost:3000 in your browser
  2. Drag and drop an audio or video file (or click to browse)
  3. Select "AssemblyAI" from the provider dropdown
  4. Click "Transcribe" and wait for processing
  5. Click any word in the transcript to seek to that timestamp

API Endpoints

GET /api/providers

Returns list of available transcription providers.

Response:

{
  "providers": [
    {
      "id": "assemblyai",
      "displayName": "AssemblyAI"
    }
  ]
}

POST /api/upload

Upload a media file. Creates a new artipod with a UUID.

Request: multipart/form-data with file field

Response:

{
  "success": true,
  "artipodId": "61dd3471-dd98-4ff3-a5ae-27afee3fc8af",
  "filename": "audio.mp3",
  "url": "/artipods/61dd3471-dd98-4ff3-a5ae-27afee3fc8af/audio.mp3",
  "size": 1234567,
  "mimetype": "audio/mpeg"
}

GET /api/artipod/:artipodId

Get artipod info by UUID.

Response:

{
  "success": true,
  "artipodId": "61dd3471-dd98-4ff3-a5ae-27afee3fc8af",
  "filename": "audio.mp3",
  "url": "/artipods/61dd3471-dd98-4ff3-a5ae-27afee3fc8af/audio.mp3",
  "size": 1234567,
  "thumbnail": "/artipods/61dd3471-dd98-4ff3-a5ae-27afee3fc8af/thumbnail.png"
}

POST /api/transcribe

Transcribe media file using selected provider.

Request:

{
  "mediaUrl": "/artipods/61dd3471-dd98-4ff3-a5ae-27afee3fc8af/audio.mp3",
  "providerId": "assemblyai",
  "options": {
    "speakerLabels": false
  }
}

Response:

{
  "success": true,
  "provider": {
    "id": "assemblyai",
    "displayName": "AssemblyAI"
  },
  "transcript": {
    "durationMs": 120000,
    "words": [
      {
        "text": "Hello",
        "startMs": 100,
        "endMs": 500,
        "confidence": 0.95
      }
    ]
  },
  "raw": { /* Original provider response */ }
}

Normalized Transcript Schema

The system uses a provider-agnostic schema:

interface Transcript {
  durationMs: number;
  speakers?: Speaker[];
  words: TranscriptWord[];
  segments?: TranscriptSegment[];
}

interface TranscriptWord {
  text: string;
  startMs: number;
  endMs: number;
  speakerId?: string;
  confidence?: number;
}

Adding New Providers

To add a new transcription provider:

  1. Create a new provider class in server/src/providers/:
import { TranscriptionProvider, ProviderResult } from '../types/transcription';

export class MyProvider implements TranscriptionProvider {
  id = 'my-provider';
  displayName = 'My Provider';
  
  async transcribe(mediaUrl: string, options?: any): Promise<ProviderResult> {
    // Call provider API
    const response = await callProviderAPI(mediaUrl);
    
    // Normalize to common schema
    const normalized = this.normalize(response);
    
    return {
      normalized,
      raw: response
    };
  }
  
  private normalize(response: any): Transcript {
    // Convert provider response to normalized schema
  }
}
  1. Register the provider in server/src/providers/registry.ts:
export function initializeProviders(): ProviderRegistry {
  const registry = new ProviderRegistry();
  
  // Register new provider
  const myProviderKey = process.env.MY_PROVIDER_API_KEY;
  if (myProviderKey) {
    registry.register(new MyProvider(myProviderKey));
  }
  
  return registry;
}

Future Extensions

  • Google Medical STT provider integration
  • Speaker diarization visualization
  • Word-level editing capabilities
  • Server-side timestamp alignment verification
  • Export to EDL/subtitle formats
  • HIPAA-grade deployment with BAA-covered providers

License

ISC

About

No description, website, or topics provided.

Resources

License

Contributing

Security policy

Stars

1 star

Watchers

1 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors