A Dart library to fetch YouTube transcripts and subtitles. Works with auto-generated and manually created transcripts. No API key required!
This is a Dart port of the popular Python library youtube-transcript-api.
- ✅ Fetch transcripts for any YouTube video
- ✅ Support for both manually created and auto-generated subtitles
- ✅ Multiple language support with automatic fallback
- ✅ Translation support for available transcripts
- ✅ Multiple output formats (Text, JSON, WebVTT, SRT, CSV)
- ✅ Proxy support (including Webshare rotating proxies)
- ✅ No API key required
- ✅ Works in both Dart and Flutter applications
- ✅ Command-line interface included
- ✅ Bypasses YouTube's PoToken protection using InnerTube API
Add this to your package's pubspec.yaml file:
dependencies:
youtube_transcript_api: ^1.0.0Then run:
dart pub getOr for Flutter:
flutter pub getimport 'package:youtube_transcript_api/youtube_transcript_api.dart';
void main() async {
final api = YouTubeTranscriptApi();
try {
// Fetch transcript for a video
final transcript = await api.fetch('dQw4w9WgXcQ');
// Print each snippet
for (var snippet in transcript) {
print('[${snippet.start}] ${snippet.text}');
}
} finally {
api.dispose();
}
}// Try to fetch German transcript, fallback to English
final transcript = await api.fetch(
'dQw4w9WgXcQ',
languages: ['de', 'en'],
);final transcriptList = await api.list('dQw4w9WgXcQ');
for (var transcript in transcriptList) {
print('${transcript.language} [${transcript.languageCode}]');
print(' Generated: ${transcript.isGenerated}');
print(' Translatable: ${transcript.isTranslatable}');
}// Find manually created transcript
final manual = await api.findManuallyCreatedTranscript(
'dQw4w9WgXcQ',
['en'],
);
// Find auto-generated transcript
final generated = await api.findGeneratedTranscript(
'dQw4w9WgXcQ',
['en'],
);final transcriptList = await api.list('dQw4w9WgXcQ');
final transcript = transcriptList.findTranscript(['en']);
// Translate to German
final germanTranscript = transcript.translate('de');
final fetched = await germanTranscript.fetch();final transcript = await api.fetch('dQw4w9WgXcQ');
// Plain text
final textFormatter = TextFormatter();
print(textFormatter.format(transcript));
// JSON
final jsonFormatter = JsonFormatter(pretty: true);
print(jsonFormatter.format(transcript));
// WebVTT
final vttFormatter = VttFormatter();
print(vttFormatter.format(transcript));
// SRT
final srtFormatter = SrtFormatter();
print(srtFormatter.format(transcript));
// CSV
final csvFormatter = CsvFormatter();
print(csvFormatter.format(transcript));final api = YouTubeTranscriptApi(
proxyConfig: GenericProxyConfig(
httpUrl: 'http://proxy.example.com:8080',
httpsUrl: 'https://proxy.example.com:8443',
),
);final api = YouTubeTranscriptApi(
proxyConfig: WebshareProxyConfig(
username: 'your-username',
password: 'your-password',
location: 'US', // Optional location filter
),
);Activate the package globally:
dart pub global activate youtube_transcript_api# Fetch transcript as plain text
youtube_transcript_api dQw4w9WgXcQ
# Fetch in specific language
youtube_transcript_api dQw4w9WgXcQ -l de
# List available transcripts
youtube_transcript_api dQw4w9WgXcQ --list
# Save as JSON file
youtube_transcript_api dQw4w9WgXcQ -f json -o transcript.json
# Save as SRT subtitle file
youtube_transcript_api dQw4w9WgXcQ -f srt -o subtitle.srt
# Multiple languages with fallback
youtube_transcript_api dQw4w9WgXcQ -l de,en,fr-v, --video-id YouTube video ID
-l, --languages Comma-separated language codes (default: en)
-f, --format Output format: text, json, vtt, srt, csv
(default: text)
-o, --output Output file path (default: stdout)
--list List all available transcripts
--manual-only Only fetch manually created transcripts
--generated-only Only fetch auto-generated transcripts
--preserve-formatting Preserve HTML formatting in text
-h, --help Show help message
The library provides detailed exceptions for different error scenarios:
try {
final transcript = await api.fetch('video-id');
} on VideoUnavailableException catch (e) {
print('Video not available: ${e.videoId}');
} on TranscriptsDisabledException catch (e) {
print('Transcripts are disabled for this video');
} on NoTranscriptFoundException catch (e) {
print('No transcript found for languages: ${e.requestedLanguages}');
print('Available languages: ${e.availableLanguages}');
} on TooManyRequestsException catch (e) {
print('Rate limited by YouTube. Consider using a proxy.');
} on IpBlockedException catch (e) {
print('IP blocked by YouTube. Use a proxy.');
} on TranscriptException catch (e) {
print('General error: $e');
}This library uses YouTube's InnerTube API to bypass PoToken protection and access transcripts reliably. It pretends to be an Android client, which helps avoid bot detection and rate limiting.
final api = YouTubeTranscriptApi(
headers: {
'User-Agent': 'MyCustomAgent/1.0',
},
timeout: Duration(seconds: 60),
);- YouTube may rate-limit or block requests from certain IP addresses. Consider using proxies if you encounter issues.
- The library relies on YouTube's internal API, which may change without notice.
- Some videos may not have transcripts available.
- Private or age-restricted videos may not be accessible.
| Platform | Status |
|---|---|
| ✅ Android | Fully supported |
| ✅ iOS | Fully supported |
| ✅ Web | Fully supported |
| ✅ Windows | Fully supported |
| ✅ macOS | Fully supported |
| ✅ Linux | Fully supported |
Contributions are welcome! Please feel free to submit a Pull Request.
See CONTRIBUTING.md for guidelines.
This project is licensed under the MIT License - see the LICENSE file for details.
- Inspired by and based on the Python youtube-transcript-api by jdepoix
- Ported to Dart with InnerTube API integration for improved reliability
See CHANGELOG.md for a detailed changelog.
- 📖 Documentation: See QUICK_START.md
- 💻 Examples: Check the example directory
- 🐛 Issues: Report on GitHub Issues
- 💬 Discussions: Join GitHub Discussions
Made with ❤️ for the Dart & Flutter community
If you find this package useful, please consider giving it a ⭐ on GitHub!