618 lines
16 KiB
Markdown
618 lines
16 KiB
Markdown
# YouTube Summarizer JavaScript SDK
|
|
|
|
Official JavaScript/TypeScript client library for the YouTube Summarizer Developer Platform. Extract transcripts, generate summaries, and integrate AI-powered video analysis into your web and Node.js applications.
|
|
|
|
[](https://badge.fury.io/js/youtube-summarizer-sdk)
|
|
[](http://www.typescriptlang.org/)
|
|
[](https://opensource.org/licenses/MIT)
|
|
|
|
## Features
|
|
|
|
- **Universal Support** - Works in Node.js and modern browsers
|
|
- **TypeScript First** - Full TypeScript support with complete type definitions
|
|
- **Dual Transcript Sources** - YouTube captions, Whisper AI, or both
|
|
- **Real-time Updates** - WebSocket support for progress tracking
|
|
- **Batch Processing** - Process multiple videos simultaneously
|
|
- **MCP Integration** - Model Context Protocol support for AI development
|
|
- **Promise-based API** - Modern async/await patterns
|
|
- **Zero Dependencies** - Lightweight with minimal runtime dependencies
|
|
|
|
## Installation
|
|
|
|
```bash
|
|
npm install youtube-summarizer-sdk
|
|
```
|
|
|
|
### CDN Usage (Browser)
|
|
|
|
```html
|
|
<script src="https://unpkg.com/youtube-summarizer-sdk@4.2.0/dist/index.umd.js"></script>
|
|
```
|
|
|
|
## Quick Start
|
|
|
|
### Node.js / TypeScript
|
|
|
|
```typescript
|
|
import { createClient, TranscriptSource } from 'youtube-summarizer-sdk';
|
|
|
|
const client = createClient({
|
|
apiKey: 'ys_pro_your_api_key_here'
|
|
});
|
|
|
|
async function main() {
|
|
try {
|
|
// Extract transcript from YouTube video
|
|
const result = await client.extractAndWait({
|
|
video_url: 'https://youtube.com/watch?v=dQw4w9WgXcQ',
|
|
transcript_source: TranscriptSource.YOUTUBE,
|
|
include_quality_analysis: true
|
|
});
|
|
|
|
console.log('Transcript:', result.transcript?.slice(0, 200) + '...');
|
|
console.log('Quality Score:', result.quality_score);
|
|
console.log('Processing Time:', result.processing_time_seconds + 's');
|
|
} catch (error) {
|
|
console.error('Error:', error.message);
|
|
} finally {
|
|
await client.close();
|
|
}
|
|
}
|
|
|
|
main();
|
|
```
|
|
|
|
### Browser (ES Modules)
|
|
|
|
```html
|
|
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<title>YouTube Summarizer SDK</title>
|
|
</head>
|
|
<body>
|
|
<script type="module">
|
|
import { createClient } from 'https://unpkg.com/youtube-summarizer-sdk@4.2.0/dist/index.esm.js';
|
|
|
|
const client = createClient({
|
|
apiKey: 'your_api_key_here'
|
|
});
|
|
|
|
async function extractTranscript() {
|
|
try {
|
|
const result = await client.extractAndWait({
|
|
video_url: 'https://youtube.com/watch?v=dQw4w9WgXcQ'
|
|
});
|
|
|
|
document.body.innerHTML = `
|
|
<h2>Transcript Extracted</h2>
|
|
<p><strong>Video:</strong> ${result.video_url}</p>
|
|
<p><strong>Quality:</strong> ${result.quality_score}</p>
|
|
<pre>${result.transcript}</pre>
|
|
`;
|
|
} catch (error) {
|
|
document.body.innerHTML = `<p>Error: ${error.message}</p>`;
|
|
}
|
|
}
|
|
|
|
extractTranscript();
|
|
</script>
|
|
</body>
|
|
</html>
|
|
```
|
|
|
|
### Browser (UMD)
|
|
|
|
```html
|
|
<script src="https://unpkg.com/youtube-summarizer-sdk@4.2.0/dist/index.umd.js"></script>
|
|
<script>
|
|
const { createClient, TranscriptSource } = YouTubeSummarizerSDK;
|
|
|
|
const client = createClient({
|
|
apiKey: 'your_api_key_here'
|
|
});
|
|
|
|
client.extractAndWait({
|
|
video_url: 'https://youtube.com/watch?v=dQw4w9WgXcQ',
|
|
transcript_source: TranscriptSource.BOTH
|
|
}).then(result => {
|
|
console.log('Dual transcripts extracted:', result);
|
|
}).catch(error => {
|
|
console.error('Error:', error);
|
|
});
|
|
</script>
|
|
```
|
|
|
|
## Core Features
|
|
|
|
### Transcript Extraction
|
|
|
|
```typescript
|
|
import { createClient, TranscriptSource, WhisperModelSize, ProcessingPriority } from 'youtube-summarizer-sdk';
|
|
|
|
const client = createClient({ apiKey: 'your_api_key' });
|
|
|
|
// YouTube captions
|
|
const youtubeResult = await client.extractAndWait({
|
|
video_url: 'https://youtube.com/watch?v=VIDEO_ID',
|
|
transcript_source: TranscriptSource.YOUTUBE
|
|
});
|
|
|
|
// Whisper AI transcription
|
|
const whisperResult = await client.extractAndWait({
|
|
video_url: 'https://youtube.com/watch?v=VIDEO_ID',
|
|
transcript_source: TranscriptSource.WHISPER,
|
|
whisper_model_size: WhisperModelSize.SMALL,
|
|
priority: ProcessingPriority.HIGH
|
|
});
|
|
|
|
// Both sources with comparison
|
|
const dualResult = await client.extractAndWait({
|
|
video_url: 'https://youtube.com/watch?v=VIDEO_ID',
|
|
transcript_source: TranscriptSource.BOTH,
|
|
include_quality_analysis: true
|
|
});
|
|
|
|
if ('quality_comparison' in dualResult) {
|
|
console.log('Similarity Score:', dualResult.quality_comparison.similarity_score);
|
|
console.log('Recommended Source:', dualResult.quality_comparison.recommendation);
|
|
}
|
|
```
|
|
|
|
### Batch Processing
|
|
|
|
```typescript
|
|
// Process multiple videos
|
|
const batchJob = await client.batchProcess({
|
|
video_urls: [
|
|
'https://youtube.com/watch?v=VIDEO1',
|
|
'https://youtube.com/watch?v=VIDEO2',
|
|
'https://youtube.com/watch?v=VIDEO3'
|
|
],
|
|
batch_name: 'Educational Series',
|
|
transcript_source: TranscriptSource.YOUTUBE,
|
|
parallel_processing: true,
|
|
max_concurrent_jobs: 3
|
|
});
|
|
|
|
console.log('Batch ID:', batchJob.batch_id);
|
|
console.log('Videos:', batchJob.video_count);
|
|
```
|
|
|
|
### Real-time Progress Tracking
|
|
|
|
```typescript
|
|
// Connect WebSocket for real-time updates
|
|
await client.connectWebSocket();
|
|
|
|
// Submit job
|
|
const job = await client.extractTranscript({
|
|
video_url: 'https://youtube.com/watch?v=VIDEO_ID'
|
|
});
|
|
|
|
// Listen for progress updates
|
|
for await (const update of client.listenForUpdates()) {
|
|
if (update.data.job_id === job.job_id) {
|
|
console.log(`Progress: ${update.data.progress || 0}%`);
|
|
|
|
if (update.event === 'job.completed') {
|
|
const result = await client.getJobResult(job.job_id);
|
|
console.log('Final result:', result);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
await client.disconnectWebSocket();
|
|
```
|
|
|
|
### Processing Estimates
|
|
|
|
```typescript
|
|
// Get time and cost estimate
|
|
const estimate = await client.getProcessingEstimate(
|
|
'https://youtube.com/watch?v=VIDEO_ID',
|
|
'whisper'
|
|
);
|
|
|
|
console.log(`Estimated time: ${estimate.estimated_time_seconds}s`);
|
|
console.log(`Estimated cost: $${estimate.estimated_cost?.toFixed(4)}`);
|
|
```
|
|
|
|
### Data Export
|
|
|
|
```typescript
|
|
// Export data in various formats
|
|
const exportData = await client.exportData({
|
|
format: 'json', // json, csv, markdown, pdf
|
|
dateFrom: '2024-01-01',
|
|
dateTo: '2024-12-31',
|
|
includeTranscripts: true
|
|
});
|
|
|
|
console.log('Export completed:', exportData);
|
|
```
|
|
|
|
## MCP (Model Context Protocol) Integration
|
|
|
|
The SDK includes MCP support for AI development environments like Claude Code:
|
|
|
|
```typescript
|
|
import { createMCPInterface } from 'youtube-summarizer-sdk';
|
|
|
|
// Create MCP interface
|
|
const mcp = createMCPInterface({
|
|
apiKey: 'your_api_key'
|
|
});
|
|
|
|
// List available tools
|
|
const tools = await mcp.listTools();
|
|
console.log('Available tools:', tools);
|
|
|
|
// Execute MCP tool
|
|
const result = await mcp.callTool({
|
|
name: 'extract_transcript',
|
|
arguments: {
|
|
video_url: 'https://youtube.com/watch?v=VIDEO_ID',
|
|
transcript_source: 'youtube',
|
|
wait_for_completion: true
|
|
}
|
|
});
|
|
|
|
console.log('MCP result:', result);
|
|
```
|
|
|
|
## Configuration
|
|
|
|
### Client Options
|
|
|
|
```typescript
|
|
import { createClient, SDKConfig } from 'youtube-summarizer-sdk';
|
|
|
|
const config: SDKConfig = {
|
|
apiKey: 'your_api_key',
|
|
baseUrl: 'https://api.youtube-summarizer.com', // Optional
|
|
timeout: 60000, // Request timeout in ms
|
|
maxRetries: 3, // Maximum retry attempts
|
|
retryDelay: 1000, // Delay between retries in ms
|
|
userAgent: 'my-app/1.0.0' // Custom user agent
|
|
};
|
|
|
|
const client = createClient(config);
|
|
```
|
|
|
|
### WebSocket Configuration
|
|
|
|
```typescript
|
|
await client.connectWebSocket({
|
|
url: 'wss://api.youtube-summarizer.com/ws',
|
|
autoReconnect: true,
|
|
maxReconnectAttempts: 5,
|
|
heartbeatInterval: 30000,
|
|
reconnectDelay: 5000
|
|
});
|
|
```
|
|
|
|
## API Reference
|
|
|
|
### Client Methods
|
|
|
|
```typescript
|
|
// Core transcript extraction
|
|
await client.extractTranscript(request: TranscriptRequest): Promise<JobResponse>
|
|
await client.batchProcess(request: BatchProcessingRequest): Promise<BatchJobResponse>
|
|
await client.getJobStatus(jobId: string): Promise<JobResponse>
|
|
await client.getJobResult(jobId: string): Promise<TranscriptResult | DualTranscriptResult>
|
|
await client.cancelJob(jobId: string): Promise<Record<string, any>>
|
|
|
|
// Utility methods
|
|
await client.getProcessingEstimate(videoUrl: string, source?: string): Promise<ProcessingTimeEstimate>
|
|
await client.getUsageStats(): Promise<APIUsageStats>
|
|
await client.searchSummaries(options: SearchOptions): Promise<Record<string, any>>
|
|
await client.exportData(options: ExportOptions): Promise<Record<string, any>>
|
|
|
|
// Convenience methods
|
|
await client.extractAndWait(request: TranscriptRequest, pollInterval?: number, timeout?: number): Promise<TranscriptResult | DualTranscriptResult>
|
|
await client.waitForJob(jobId: string, pollInterval?: number, timeout?: number): Promise<TranscriptResult | DualTranscriptResult>
|
|
|
|
// WebSocket methods
|
|
await client.connectWebSocket(config?: WebSocketConfig): Promise<boolean>
|
|
for await (const update of client.listenForUpdates()) { /* handle updates */ }
|
|
await client.disconnectWebSocket(): Promise<void>
|
|
|
|
// Cleanup
|
|
await client.close(): Promise<void>
|
|
```
|
|
|
|
### Type Definitions
|
|
|
|
```typescript
|
|
// Enums
|
|
enum TranscriptSource { YOUTUBE = 'youtube', WHISPER = 'whisper', BOTH = 'both' }
|
|
enum WhisperModelSize { TINY = 'tiny', BASE = 'base', SMALL = 'small', MEDIUM = 'medium', LARGE = 'large' }
|
|
enum ProcessingPriority { LOW = 'low', NORMAL = 'normal', HIGH = 'high', URGENT = 'urgent' }
|
|
enum JobStatus { QUEUED = 'queued', PROCESSING = 'processing', COMPLETED = 'completed', FAILED = 'failed', CANCELLED = 'cancelled' }
|
|
|
|
// Request interfaces
|
|
interface TranscriptRequest {
|
|
video_url: string;
|
|
transcript_source?: TranscriptSource;
|
|
whisper_model_size?: WhisperModelSize;
|
|
priority?: ProcessingPriority;
|
|
webhook_url?: string;
|
|
include_quality_analysis?: boolean;
|
|
custom_prompt?: string;
|
|
tags?: string[];
|
|
}
|
|
|
|
interface BatchProcessingRequest {
|
|
video_urls: string[];
|
|
batch_name: string;
|
|
transcript_source?: TranscriptSource;
|
|
priority?: ProcessingPriority;
|
|
webhook_url?: string;
|
|
parallel_processing?: boolean;
|
|
max_concurrent_jobs?: number;
|
|
}
|
|
|
|
// Response interfaces
|
|
interface TranscriptResult {
|
|
job_id: string;
|
|
video_id: string;
|
|
video_url: string;
|
|
transcript_source: TranscriptSource;
|
|
transcript?: string;
|
|
segments?: Array<Record<string, any>>;
|
|
processing_time_seconds: number;
|
|
quality_score?: number;
|
|
confidence_score?: number;
|
|
metadata: Record<string, any>;
|
|
}
|
|
|
|
interface DualTranscriptResult {
|
|
job_id: string;
|
|
video_id: string;
|
|
video_url: string;
|
|
youtube_transcript?: string;
|
|
whisper_transcript?: string;
|
|
youtube_segments?: Array<Record<string, any>>;
|
|
whisper_segments?: Array<Record<string, any>>;
|
|
quality_comparison?: QualityComparison;
|
|
processing_time_seconds: number;
|
|
metadata: Record<string, any>;
|
|
}
|
|
```
|
|
|
|
## Error Handling
|
|
|
|
```typescript
|
|
import {
|
|
YouTubeSummarizerError,
|
|
AuthenticationError,
|
|
RateLimitError,
|
|
ValidationError,
|
|
JobTimeoutError,
|
|
NetworkError
|
|
} from 'youtube-summarizer-sdk';
|
|
|
|
try {
|
|
const result = await client.extractTranscript(request);
|
|
} catch (error) {
|
|
if (error instanceof AuthenticationError) {
|
|
console.error('Invalid API key');
|
|
} else if (error instanceof RateLimitError) {
|
|
console.error(`Rate limited. Remaining: ${error.remaining}, Reset: ${error.resetTime}`);
|
|
} else if (error instanceof ValidationError) {
|
|
console.error('Validation failed:', error.validationErrors);
|
|
} else if (error instanceof JobTimeoutError) {
|
|
console.error(`Job ${error.jobId} timed out after ${error.timeoutSeconds}s`);
|
|
} else if (error instanceof NetworkError) {
|
|
console.error('Network error:', error.message);
|
|
} else if (error instanceof YouTubeSummarizerError) {
|
|
console.error('SDK error:', error.message, error.details);
|
|
} else {
|
|
console.error('Unexpected error:', error);
|
|
}
|
|
}
|
|
```
|
|
|
|
## Examples
|
|
|
|
### React Hook
|
|
|
|
```typescript
|
|
import { useState, useEffect } from 'react';
|
|
import { createClient, TranscriptRequest, TranscriptResult } from 'youtube-summarizer-sdk';
|
|
|
|
const client = createClient({ apiKey: process.env.REACT_APP_YT_SUMMARIZER_API_KEY! });
|
|
|
|
function useTranscriptExtraction() {
|
|
const [isLoading, setIsLoading] = useState(false);
|
|
const [result, setResult] = useState<TranscriptResult | null>(null);
|
|
const [error, setError] = useState<string | null>(null);
|
|
|
|
const extractTranscript = async (request: TranscriptRequest) => {
|
|
setIsLoading(true);
|
|
setError(null);
|
|
|
|
try {
|
|
const result = await client.extractAndWait(request);
|
|
setResult(result);
|
|
} catch (err) {
|
|
setError(err instanceof Error ? err.message : 'Unknown error');
|
|
} finally {
|
|
setIsLoading(false);
|
|
}
|
|
};
|
|
|
|
useEffect(() => {
|
|
return () => {
|
|
client.close();
|
|
};
|
|
}, []);
|
|
|
|
return { extractTranscript, isLoading, result, error };
|
|
}
|
|
|
|
// Usage in component
|
|
function VideoProcessor() {
|
|
const { extractTranscript, isLoading, result, error } = useTranscriptExtraction();
|
|
|
|
const handleSubmit = (videoUrl: string) => {
|
|
extractTranscript({ video_url: videoUrl });
|
|
};
|
|
|
|
return (
|
|
<div>
|
|
<input
|
|
type="url"
|
|
placeholder="YouTube URL"
|
|
onSubmit={handleSubmit}
|
|
disabled={isLoading}
|
|
/>
|
|
{isLoading && <p>Extracting transcript...</p>}
|
|
{error && <p>Error: {error}</p>}
|
|
{result && <pre>{result.transcript}</pre>}
|
|
</div>
|
|
);
|
|
}
|
|
```
|
|
|
|
### Node.js CLI Tool
|
|
|
|
```javascript
|
|
#!/usr/bin/env node
|
|
const { createClient } = require('youtube-summarizer-sdk');
|
|
|
|
const client = createClient({
|
|
apiKey: process.env.YOUTUBE_SUMMARIZER_API_KEY
|
|
});
|
|
|
|
async function main() {
|
|
const videoUrl = process.argv[2];
|
|
|
|
if (!videoUrl) {
|
|
console.error('Usage: node transcript-extractor.js <youtube-url>');
|
|
process.exit(1);
|
|
}
|
|
|
|
try {
|
|
console.log('Extracting transcript from:', videoUrl);
|
|
|
|
const result = await client.extractAndWait({
|
|
video_url: videoUrl,
|
|
transcript_source: 'youtube'
|
|
});
|
|
|
|
console.log('\nTranscript extracted successfully!');
|
|
console.log('Quality Score:', result.quality_score);
|
|
console.log('Processing Time:', result.processing_time_seconds + 's');
|
|
console.log('\nTranscript:');
|
|
console.log(result.transcript);
|
|
|
|
} catch (error) {
|
|
console.error('Error:', error.message);
|
|
process.exit(1);
|
|
} finally {
|
|
await client.close();
|
|
}
|
|
}
|
|
|
|
main().catch(console.error);
|
|
```
|
|
|
|
### Express.js API
|
|
|
|
```javascript
|
|
const express = require('express');
|
|
const { createClient } = require('youtube-summarizer-sdk');
|
|
|
|
const app = express();
|
|
const client = createClient({ apiKey: process.env.YOUTUBE_SUMMARIZER_API_KEY });
|
|
|
|
app.use(express.json());
|
|
|
|
app.post('/api/extract-transcript', async (req, res) => {
|
|
try {
|
|
const { video_url, transcript_source = 'youtube' } = req.body;
|
|
|
|
if (!video_url) {
|
|
return res.status(400).json({ error: 'video_url is required' });
|
|
}
|
|
|
|
const result = await client.extractAndWait({
|
|
video_url,
|
|
transcript_source
|
|
});
|
|
|
|
res.json({
|
|
success: true,
|
|
data: {
|
|
transcript: result.transcript,
|
|
quality_score: result.quality_score,
|
|
processing_time: result.processing_time_seconds
|
|
}
|
|
});
|
|
|
|
} catch (error) {
|
|
console.error('Transcript extraction failed:', error);
|
|
res.status(500).json({
|
|
error: 'Transcript extraction failed',
|
|
message: error.message
|
|
});
|
|
}
|
|
});
|
|
|
|
app.listen(3000, () => {
|
|
console.log('Server running on port 3000');
|
|
});
|
|
```
|
|
|
|
## Browser Compatibility
|
|
|
|
- **Modern Browsers**: Chrome 76+, Firefox 70+, Safari 14+, Edge 79+
|
|
- **Node.js**: 16.0.0+
|
|
- **ES Modules**: Full support for import/export syntax
|
|
- **CommonJS**: Compatible with require() syntax
|
|
|
|
## Development
|
|
|
|
```bash
|
|
git clone https://github.com/youtube-summarizer/javascript-sdk
|
|
cd javascript-sdk
|
|
npm install
|
|
|
|
# Build the SDK
|
|
npm run build
|
|
|
|
# Run tests
|
|
npm test
|
|
|
|
# Type checking
|
|
npm run type-check
|
|
|
|
# Linting
|
|
npm run lint
|
|
|
|
# Generate documentation
|
|
npm run docs
|
|
```
|
|
|
|
## API Tiers & Rate Limits
|
|
|
|
| Tier | Requests/Minute | Requests/Day | Requests/Month |
|
|
|------|----------------|--------------|----------------|
|
|
| Free | 10 | 1,000 | 10,000 |
|
|
| Pro | 100 | 25,000 | 500,000 |
|
|
| Enterprise | 1,000 | 100,000 | 2,000,000 |
|
|
|
|
## Support
|
|
|
|
- **Documentation**: https://docs.youtube-summarizer.com/javascript-sdk
|
|
- **API Reference**: https://api.youtube-summarizer.com/docs
|
|
- **Issues**: https://github.com/youtube-summarizer/javascript-sdk/issues
|
|
- **Email**: support@youtube-summarizer.com
|
|
|
|
## License
|
|
|
|
This SDK is licensed under the MIT License. See the [LICENSE](LICENSE) file for details. |