Official Dart/Flutter SDK for YouTubeTranscript.dev
Extract, transcribe, and translate YouTube video transcripts with a single function call.
- Captions + ASR — Extracts existing captions or transcribes audio when none are available
- 100+ languages — Translate any transcript on the fly
- Batch processing — Up to 100 videos in a single request
- Export anywhere — SRT, WebVTT, plain text, timestamped text
- Built-in search — Find keywords across transcript segments
- Typed exceptions — Granular error handling with
NoCaptionsException,RateLimitException, etc. - Automatic retries — Resilient HTTP layer with configurable retry on 5xx errors
- Flutter ready — Works in any Dart app, ships with an example Flutter widget
dart pub add youtubetranscriptOr add it manually to your pubspec.yaml:
dependencies:
youtubetranscript: ^0.1.0import 'package:youtubetranscript/youtubetranscript.dart';
void main() async {
final yt = YouTubeTranscript('your_api_key');
// Extract transcript
final result = await yt.transcribe('dQw4w9WgXcQ');
print('${result.segments.length} segments, ${result.wordCount} words');
for (final seg in result.segments) {
print('[${seg.startFormatted}] ${seg.text}');
}
yt.close();
}Get your free API key at youtubetranscript.dev/dashboard
final spanish = await yt.transcribe('dQw4w9WgXcQ', language: 'es');
final japanese = await yt.transcribe('dQw4w9WgXcQ', language: 'ja');For videos without captions — transcribe directly from audio:
final job = await yt.transcribeAsr('video_id');
final result = await yt.waitForJob(job.jobId); // polls until done
print(result.text);Process up to 100 videos in one request:
final batch = await yt.batch(['video1', 'video2', 'video3']);
for (final t in batch.completed) {
print('${t.videoId}: ${t.wordCount} words');
}result.toSrt(); // SRT subtitles
result.toVtt(); // WebVTT subtitles
result.toPlainText(); // Plain text
result.toTimestampedText(); // [MM:SS] textfinal matches = result.search('keyword');
for (final seg in matches) {
print('[${seg.startFormatted}] ${seg.text}');
}final stats = await yt.stats();
print('Plan: ${stats.plan}');
print('Credits remaining: ${stats.creditsRemaining}');Every API error maps to a typed exception so you can handle each case precisely:
try {
final result = await yt.transcribe('video_id');
} on NoCaptionsException {
// No captions available — fall back to ASR
final job = await yt.transcribeAsr('video_id');
final result = await yt.waitForJob(job.jobId);
} on AuthenticationException {
print('Invalid API key — check youtubetranscript.dev/dashboard');
} on InsufficientCreditsException {
print('Out of credits — top up at youtubetranscript.dev/pricing');
} on RateLimitException catch (e) {
print('Rate limited — retry after ${e.retryAfter}s');
} on YouTubeTranscriptException catch (e) {
print('API error: ${e.message}');
}A ready-to-use TranscriptViewer widget is included in the examples — with search, segment listing, and error states:
TranscriptViewer(
apiKey: 'your_api_key',
videoId: 'dQw4w9WgXcQ',
)See example/flutter_widget.dart for the full source.
| Method | Description |
|---|---|
transcribe(video, {language, source, format}) |
Extract transcript from a video |
transcribeAsr(video, {language, webhookUrl}) |
Transcribe from audio (async) |
getJob(jobId) |
Check ASR job status |
waitForJob(jobId, {pollInterval, timeout}) |
Poll until ASR job completes |
batch(videoIds, {language}) |
Batch extract up to 100 videos |
getBatch(batchId) |
Check batch status |
listTranscripts({search, language}) |
Browse transcript history |
getTranscript(videoId) |
Retrieve a saved transcript |
stats() |
Account credits & usage info |
deleteTranscript({videoId, ids}) |
Delete transcripts |
| Operation | Cost |
|---|---|
| Captions extraction | 1 credit |
| Translation | 1 credit per 2,500 chars |
| ASR audio transcription | 1 credit per 90 seconds |
| Re-fetch owned transcript | Free |
| Language | Package |
|---|---|
| Python | youtubetranscript on PyPI |
| JavaScript/Node | youtubetranscript on npm |
| Dart/Flutter | You are here |
MIT — see LICENSE