newpipeextractor_dart 1.0.0 copy "newpipeextractor_dart: ^1.0.0" to clipboard
newpipeextractor_dart: ^1.0.0 copied to clipboard

Flutter plugin wrapping NewPipe Extractor for YouTube data extraction. Extract video info, streams, subtitles, comments, channels, playlists, search results, and trending content — no API key required.

newpipeextractor_dart #

A Flutter plugin that wraps the NewPipe Extractor library (v0.26.2) for extracting media data from YouTube, SoundCloud, Bandcamp, PeerTube, and media.ccc.de on Android — no API key required.

Table of Contents #

Requirements #

Requirement Version
Flutter 3.10+
Dart SDK >=3.0.0 <4.0.0
Android minSdk 22 (Android 5.1+)
Android compileSdk 35

Android-only. This plugin uses native Java/Kotlin code via the NewPipe Extractor library. It does not support iOS, web, macOS, Windows, or Linux.

Dependencies bundled automatically:

Installation #

Add to your pubspec.yaml:

dependencies:
  newpipeextractor_dart:
    git:
      url: https://github.com/OttomanDeveloper/NewPipeExtractor_Dart.git

Then run:

flutter pub get

Import in your Dart code:

import 'package:newpipeextractor_dart/newpipeextractor_dart.dart';

Quick Start #

import 'package:newpipeextractor_dart/newpipeextractor_dart.dart';

// Search YouTube
final results = await SearchExtractor.searchYoutube(
  'flutter tutorial',
  [SearchFilter.videos.value],
);
for (final video in results.videos) {
  print('${video.name} — ${video.uploaderName}');
}

// Get full video info + streams
final video = await VideoExtractor.getStream(
  'https://www.youtube.com/watch?v=dQw4w9WgXcQ',
);
print('Title: ${video.videoInfo.name}');
print('Audio streams: ${video.audioOnlyStreams.length}');
print('Subtitles: ${video.subtitleStreams.length}');

// Best quality helpers
final bestAudio = video.audioWithHighestQuality;
final bestVideo = video.videoOnlyWithHighestQuality;

// Search suggestions (autocomplete)
final suggestions = await SearchExtractor.getSearchSuggestions('flutter');

// SoundCloud search (multi-service)
final scResults = await ServiceExtractor.search(
  ServiceId.soundCloud.value, 'lofi beats', [],
);

// Change content localization
await LocalizationExtractor.setLocalization('de', 'DE');

API Reference #

All extractors use static methods. Every method that calls the native layer returns a Future.

VideoExtractor #

Extracts video information and media streams from YouTube URLs.

Method Returns Description
getStream(String url) Future<YoutubeVideo> Full video info + all streams (audio, video, muxed, subtitles, segments, framesets)
getVideoInfo(String url) Future<VideoInfo> Video metadata only, no streams
getVideoSegments(String url) Future<List<StreamSegment>> Video chapters/segments
getRelatedStreams(String url) Future<SearchResult> Related videos, playlists, and channels
final video = await VideoExtractor.getStream(url);
print(video.videoInfo.streamType); // StreamType.videoStream, liveStream, etc.
print(video.videoInfo.hlsUrl);     // HLS manifest URL for live streams
print(video.videoInfo.isShort);    // true if YouTube Short

SearchExtractor #

YouTube and YouTube Music search with pagination and autocomplete.

Method Returns Description
searchYoutube(String query, List<String> filters) Future<SearchResult> Search YouTube — returns videos, playlists, channels
getNextPage() Future<SearchResult> Next page of YouTube search results
searchYoutubeMusic(String query, List<String> filters) Future<SearchResult> Search YouTube Music
getNextMusicPage() Future<SearchResult> Next page of YouTube Music results
getSearchSuggestions(String query) Future<List<String>> Autocomplete suggestions
// Use SearchFilter enum for type-safe filters
final results = await SearchExtractor.searchYoutube(
  'dart programming',
  [SearchFilter.videos.value],
);

// Paginate
final page2 = await SearchExtractor.getNextPage();

// Autocomplete
final suggestions = await SearchExtractor.getSearchSuggestions('flu');
// ['flutter', 'fluffy', 'flu symptoms', ...]

ChannelExtractor #

YouTube channel info, uploads, and tab-based browsing (Videos, Shorts, Live, Playlists).

Method Returns Description
getChannelInfo(String url) Future<YoutubeChannel> Channel metadata with available tabs
getChannelUploads(String url) Future<List<StreamInfoItem>> Channel uploads via feed
getChannelNextPage() Future<List<StreamInfoItem>> Next page of channel uploads
getChannelTabContent(String url, String tabFilter) Future<({List<StreamInfoItem> streams, List<PlaylistInfoItem> playlists, List<ChannelInfoItem> channels, bool hasNextPage})> Content from a specific channel tab
getChannelTabNextPage() Future<({List<StreamInfoItem> streams, List<PlaylistInfoItem> playlists, List<ChannelInfoItem> channels, bool hasNextPage})> Next page of tab content
final channel = await ChannelExtractor.getChannelInfo(url);
print(channel.name);
print(channel.isVerified);
print(channel.tabs); // [ChannelTab.videos, ChannelTab.shorts, ChannelTab.live, ...]

// Browse Shorts tab
final shorts = await ChannelExtractor.getChannelTabContent(url, 'shorts');
for (final item in shorts.streams) {
  print('${item.name} (${item.isShort})');
}

// Browse Playlists tab — now returns playlists too
final playlistsTab = await ChannelExtractor.getChannelTabContent(url, 'playlists');
for (final pl in playlistsTab.playlists) {
  print('${pl.name} — ${pl.streamCount} videos');
}

if (shorts.hasNextPage) {
  final more = await ChannelExtractor.getChannelTabNextPage();
}

PlaylistExtractor #

YouTube playlist details and paginated stream listing.

Method Returns Description
getPlaylistDetails(String url) Future<YoutubePlaylist> Playlist metadata
getPlaylistStreams(String url) Future<List<StreamInfoItem>> Videos in the playlist
getPlaylistNextPage() Future<List<StreamInfoItem>> Next page of playlist videos
final playlist = await PlaylistExtractor.getPlaylistDetails(url);
print('${playlist.name} — ${playlist.streamCount} videos');
print('Type: ${playlist.playlistType}'); // PlaylistType.normal, mixStream, etc.

final streams = await PlaylistExtractor.getPlaylistStreams(url);
final more = await PlaylistExtractor.getPlaylistNextPage();

CommentsExtractor #

YouTube comments with pagination and reply threads.

Method Returns Description
getComments(String url) Future<CommentsPage> First page of comments
getNextCommentsPage() Future<CommentsPage> Next page of comments
getCommentReplies(int commentIndex) Future<CommentsPage> Replies to a specific comment (by index from the last fetched page)
final page = await CommentsExtractor.getComments(videoUrl);
for (final comment in page.comments) {
  print('${comment.author}: ${comment.commentText}');
  print('  Likes: ${comment.likeCount}, Replies: ${comment.replyCount}');
  print('  Pinned: ${comment.pinned}, Hearted: ${comment.hearted}');
  print('  Channel owner: ${comment.isChannelOwner}');
}

// Load more comments
if (page.hasNextPage) {
  final page2 = await CommentsExtractor.getNextCommentsPage();
}

// Load replies to the first comment
if (page.comments.first.replyCount > 0) {
  final replies = await CommentsExtractor.getCommentReplies(0);
}

TrendingExtractor #

YouTube trending/kiosk content.

Method Returns Description
getTrendingVideos() Future<List<StreamInfoItem>> Trending videos (default locale)
listKiosks() Future<List<String>> Available kiosk IDs (e.g., "Trending", "Top 50")
getKioskContent(String kioskId) Future<List<StreamInfoItem>> Content from a specific kiosk
final trending = await TrendingExtractor.getTrendingVideos();

// Discover available kiosks
final kiosks = await TrendingExtractor.listKiosks();
// ['Trending', 'Top 50', 'New & Hot', ...]

final top50 = await TrendingExtractor.getKioskContent('Top 50');

UrlExtractor #

URL parsing and validation.

Method Returns Description
getIdFromStreamUrl(String url) Future<String?> Extract video ID from URL
getIdFromPlaylistUrl(String url) Future<String?> Extract playlist ID from URL
getIdFromChannelUrl(String url) Future<String?> Extract channel ID from URL
isValidStreamUrl(String url) Future<bool> Check if URL is a valid video URL
isValidPlaylistUrl(String url) Future<bool> Check if URL is a valid playlist URL
isValidChannelUrl(String url) Future<bool> Check if URL is a valid channel URL
final id = await UrlExtractor.getIdFromStreamUrl(
  'https://www.youtube.com/watch?v=dQw4w9WgXcQ',
); // 'dQw4w9WgXcQ'

final valid = await UrlExtractor.isValidStreamUrl(someUrl);

CookieExtractor #

Manage cookies for the HTTP client (used for reCAPTCHA persistence).

Method Returns Description
setCookie(String cookie) Future<void> Set cookie on the native HTTP client (persisted to SharedPreferences)
getCookieByUrl(String url) Future<String?> Get cookie string for a URL
decodeCookie(String cookie) Future<String?> URL-decode a cookie string

LocalizationExtractor #

Control the language and country for content extraction.

Method Returns Description
setLocalization(String languageCode, String countryCode) Future<void> Set content language and country (affects all subsequent requests)
// Get German content
await LocalizationExtractor.setLocalization('de', 'DE');

// Get Japanese trending
await LocalizationExtractor.setLocalization('ja', 'JP');
final trending = await TrendingExtractor.getTrendingVideos();

ServiceExtractor (Multi-Service) #

Generic extractor that works across all 5 supported services. Use ServiceId enum or raw service IDs.

Service ID Supported Features
YouTube 0 Streams, search, channels, playlists, kiosks, suggestions
SoundCloud 1 Streams, search, channels, playlists, kiosks, suggestions
media.ccc.de 2 Streams, search, channels, playlists, kiosks
PeerTube 3 Streams, search, channels, playlists, kiosks
Bandcamp 4 Streams, search, channels, playlists, kiosks
Method Returns Description
getAvailableServices() Future<List<ServiceInfo>> List all supported services
getStreamInfo(int serviceId, String url) Future<VideoInfo> Stream metadata for any service
getStream(int serviceId, String url) Future<YoutubeVideo> Full stream info + all media streams
getRelatedItems(int serviceId, String url) Future<SearchResult> Related content
search(int serviceId, String query, List<String> filters) Future<SearchResult> Search any service
searchNextPage(int serviceId) Future<SearchResult> Next search results page
getSuggestions(int serviceId, String query) Future<List<String>> Search autocomplete
getChannelInfo(int serviceId, String url) Future<YoutubeChannel> Channel/artist info
getChannelContent(int serviceId, String url) Future<List<StreamInfoItem>> Channel content
getChannelContentNextPage(int serviceId) Future<List<StreamInfoItem>> Next page of channel content
getPlaylistInfo(int serviceId, String url) Future<YoutubePlaylist> Playlist/album info
getPlaylistContent(int serviceId, String url) Future<List<StreamInfoItem>> Playlist tracks
getPlaylistContentNextPage(int serviceId) Future<List<StreamInfoItem>> Next page of playlist tracks
listKiosks(int serviceId) Future<List<String>> Available kiosks for a service
getKioskContent(int serviceId, String kioskId) Future<List<StreamInfoItem>> Kiosk content (charts, trending, etc.)
// Discover services
final services = await ServiceExtractor.getAvailableServices();
for (final s in services) {
  print('${s.name} (id: ${s.serviceId})');
}

// Search SoundCloud
final results = await ServiceExtractor.search(
  ServiceId.soundCloud.value, 'lofi beats', [],
);

// Get Bandcamp album
final album = await ServiceExtractor.getPlaylistInfo(
  ServiceId.bandcamp.value, bandcampAlbumUrl,
);
final tracks = await ServiceExtractor.getPlaylistContent(
  ServiceId.bandcamp.value, bandcampAlbumUrl,
);

// Browse PeerTube kiosks
final kiosks = await ServiceExtractor.listKiosks(ServiceId.peerTube.value);
final content = await ServiceExtractor.getKioskContent(
  ServiceId.peerTube.value, kiosks.first,
);

Models #

All models are immutable (@freezed), have copyWith, ==, hashCode, toJson/fromJson.

YoutubeVideo #

Complete video with all streams and metadata.

Field Type Default
videoInfo VideoInfo required
audioOnlyStreams List<AudioOnlyStream> []
videoOnlyStreams List<VideoOnlyStream> []
videoStreams List<VideoStream> []
subtitleStreams List<SubtitleStream> []
segments List<StreamSegment> []
framesets List<Frameset> []

VideoInfo #

Full video metadata (28 fields).

Field Type Description
id String? Video ID (e.g., dQw4w9WgXcQ)
url String? Full video URL
name String? Video title
uploaderName String? Channel name
uploaderUrl String? Channel URL
uploaderAvatars List<String> Channel avatar image URLs
uploadDate String? Textual upload date
description String? Video description
length int? Duration in seconds
viewCount int? View count
likeCount int? Like count
dislikeCount int? Dislike count
category String? Video category
ageLimit int? Age restriction
tags List<String> Video tags
thumbnails List<String> Thumbnail URLs (multiple resolutions)
streamType StreamType Video type (video, live, audio, etc.)
hlsUrl String? HLS manifest URL (live streams)
dashMpdUrl String? DASH manifest URL
isShort bool Whether this is a YouTube Short
isUploaderVerified bool Verified badge on uploader
privacy Privacy Privacy status
uploaderSubscriberCount int? Uploader's subscriber count
subChannelName String? Sub-channel/topic name
subChannelUrl String? Sub-channel URL
subChannelAvatars List<String> Sub-channel avatars
licence String? Content licence
supportInfo String? Creator support/donation info

StreamInfoItem #

Lightweight video item used in lists (search results, playlists, trending, etc.).

Field Type Description
url String? Video URL
id String? Video ID
name String? Video title
uploaderName String? Channel name
uploaderUrl String? Channel URL
uploaderAvatars List<String> Channel avatars
uploadDate String? Textual upload date
date String? ISO date string
duration int? Duration in seconds
viewCount int? View count
isShort bool YouTube Short flag
thumbnails List<String> Thumbnail URLs

YoutubeChannel #

Field Type Description
id String? Channel ID
name String? Channel name
url String? Channel URL
avatars List<String> Avatar URLs
banners List<String> Banner URLs
description String? Channel description
feedUrl String? RSS feed URL
subscriberCount int? Subscriber count
isVerified bool Verified badge
tabs List<ChannelTab> Available tabs (Videos, Shorts, Live, etc.)

YoutubePlaylist #

Field Type Description
id String? Playlist ID
name String? Playlist name
url String? Playlist URL
uploaderName String? Creator name
uploaderAvatars List<String> Creator avatars
uploaderUrl String? Creator channel URL
banners List<String> Playlist banner URLs
thumbnails List<String> Playlist thumbnails
streamCount int Number of videos
description String? Playlist description
playlistType PlaylistType Type (normal, mix, album)

YoutubeComment #

Field Type Description
author String? Comment author
commentText String? Comment text
uploadDate String? When posted
uploaderAvatars List<String> Author's avatars
uploaderUrl String? Author's channel URL
commentId String? Comment ID
likeCount int? Like count
hearted bool Hearted by video creator
pinned bool Pinned by video creator
replyCount int Number of replies
isChannelOwner bool Author is the video uploader
isUploaderVerified bool Author has verified badge
streamPosition int? Timestamp reference in video

SearchResult #

Field Type
videos List<StreamInfoItem>
playlists List<PlaylistInfoItem>
channels List<ChannelInfoItem>

CommentsPage #

Field Type
comments List<YoutubeComment>
hasNextPage bool

Stream Models #

AudioOnlyStream — Audio track with bitrate and track metadata.

Field Type Description
url String? Stream URL
averageBitrate int Bitrate in kbps
formatName String? Format name (e.g., m4a, webm)
formatSuffix String? File extension
formatMimeType String? MIME type
audioTrackName String? Track name (for multi-audio videos)
audioTrackLocale String? Language code of audio track
audioTrackType String? Track type (ORIGINAL, DUBBED, DESCRIPTIVE)

VideoOnlyStream — Video track (no audio).

Field Type Description
url String? Stream URL
resolution String? Resolution (e.g., 1080p, 720p60)
fps int Frames per second
formatName String? Format name
formatSuffix String? File extension
formatMimeType String? MIME type

VideoStream — Muxed video + audio stream. Same fields as VideoOnlyStream.

SubtitleStream — Subtitle/caption track.

Field Type Description
url String? Subtitle file URL
format String? Format (VTT, TTML, SRT, etc.)
languageCode String? Language code (e.g., en, es)
isAutoGenerated bool Whether auto-generated by YouTube

Other Models #

StreamSegment — Video chapter/segment.

Field Type
url String?
title String?
previewUrl String?
startTimeSeconds int

Frameset — Storyboard/preview thumbnail grid.

Field Type
urls List<String>
width int
height int
totalCount int

ChannelInfoItem — Lightweight channel in search results.

Field Type
url, name, description String?
thumbnails List<String>
subscriberCount int?
streamCount int
isVerified bool

PlaylistInfoItem — Lightweight playlist in search results.

Field Type
url, name, uploaderName String?
thumbnails List<String>
streamCount int

ServiceInfo — Describes an available extraction service.

Field Type
serviceId int (required)
name String (required)
baseUrl String?

Enums #

StreamType #

Identifies the type of media stream.

Value Description
videoStream Standard video
audioStream Audio-only content
liveStream Live video stream
audioLiveStream Live audio stream
postLiveStream Ended live stream (VOD)
none Unknown/default

PlaylistType #

Value Description
normal Regular playlist
mixStream Auto-generated mix from a video
mixChannel Auto-generated mix from a channel
mixAlbum Album mix

Privacy #

Value Description
public_ Public
unlisted Unlisted
private_ Private
internal_ Internal
other Unknown

ChannelTab #

Value Tab name
videos Videos
shorts Shorts
live Live streams
playlists Playlists
channels Featured channels
albums Albums/podcasts

SearchFilter #

Value Filter string
all 'all'
videos 'videos'
channels 'channels'
playlists 'playlists'
musicSongs 'music_songs'
musicVideos 'music_videos'
musicAlbums 'music_albums'
musicPlaylists 'music_playlists'
musicArtists 'music_artists'

ServiceId #

Value ID
youtube 0
soundCloud 1
mediaCccDe 2
peerTube 3
bandcamp 4

Exceptions #

All exceptions extend the sealed class ExtractorException:

try {
  final video = await VideoExtractor.getStream(url);
} on ExtractorException catch (e) {
  switch (e) {
    case BadUrlException():
      print('Invalid URL: ${e.message}');
    case FatalFailureException():
      print('YouTube changed something: ${e.message}');
    case TransientFailureException():
      print('Temporary error, try again: ${e.message}');
    case RequestLimitExceededException():
      print('Rate limited: ${e.message}');
    case ReCaptchaRequiredException():
      print('CAPTCHA needed at: ${e.challengeUrl}');
    case StreamIsNullException():
      print('No stream available: ${e.message}');
  }
}
Exception When it's thrown
BadUrlException URL is null, empty, or malformed
StreamIsNullException Attempted to access a stream that wasn't loaded
FatalFailureException HTTP 4xx error (likely a YouTube API change)
TransientFailureException HTTP 5xx error (YouTube-side issue, retry later)
RequestLimitExceededException HTTP 429 or Google rate-limiting redirect
ReCaptchaRequiredException YouTube requires CAPTCHA verification (has challengeUrl field)

Extension Methods #

YoutubeVideoHelpers on YoutubeVideo — convenience getters for selecting the best stream:

Method Returns Description
videoOnlyWithHighestQuality VideoOnlyStream? Highest resolution video-only stream
videoWithHighestQuality VideoStream? Highest resolution muxed stream
audioWithHighestQuality AudioOnlyStream? Highest bitrate audio stream
audioWithBestAacQuality AudioOnlyStream? Best AAC (m4a) audio stream
audioWithBestOggQuality AudioOnlyStream? Best OGG (webm) audio stream
bestAudioForVideo(VideoOnlyStream) AudioOnlyStream? Best audio format matching a video stream (AAC for MP4, OGG for WebM)
final video = await VideoExtractor.getStream(url);

// Best video + matching audio for download
final bestVideo = video.videoOnlyWithHighestQuality;
if (bestVideo != null) {
  final bestAudio = video.bestAudioForVideo(bestVideo);
  print('Video: ${bestVideo.resolution} ${bestVideo.formatSuffix}');
  print('Audio: ${bestAudio?.averageBitrate}kbps ${bestAudio?.formatSuffix}');
}

Utilities #

reCAPTCHA Handling #

YouTube may require CAPTCHA verification when detecting automated requests. This plugin handles it via an in-app WebView.

Setup (call once at app startup):

setReCaptchaNavigator((String challengeUrl) async {
  // Navigate to the ReCaptchaPage widget
  await Navigator.of(context).push(
    MaterialPageRoute(
      builder: (_) => const ReCaptchaPage(),
      settings: RouteSettings(arguments: challengeUrl),
    ),
  );
});

The ReCaptchaPage widget displays a WebView with the CAPTCHA challenge. Once the user solves it, cookies are automatically saved to the native HTTP client and persisted across app restarts.

All extractor methods automatically retry after a successful CAPTCHA solve.

ExtractorHttpClient #

Low-level HTTP utility for stream downloading.

Member Description
defaultHeaders Default User-Agent headers
getContentLength(String url) Get the byte size of a stream URL
getStream({required String url, required int size, Map<String, String>? headers, bool validate, int start, int errorCount}) Download a stream as chunks with automatic retry on failure

Limitations #

Platform #

  • Android-only. The plugin depends on the NewPipe Extractor Java library running on the JVM. iOS, web, and desktop are not supported.
  • minSdk 22 (Android 5.1). Devices below this cannot use the plugin.

YouTube #

  • No official API. This plugin reverse-engineers YouTube's internal API via NewPipe Extractor. YouTube can and does change their API without notice, which may break extraction until the NewPipe Extractor library is updated.
  • Rate limiting. YouTube throttles automated requests. Heavy usage will trigger reCAPTCHA challenges or HTTP 429 errors.
  • Age-restricted content may fail to extract depending on YouTube's current verification requirements.
  • Members-only / premium content is flagged but cannot be extracted without authentication.
  • Muxed streams capped at 720p. Higher resolutions are only available as separate video-only + audio-only streams that must be muxed client-side.
  • Comment replies use index-based lookup from the last fetched page — calling getCommentReplies(index) only works with indices from the most recently returned comment page.
  • Pagination is stateful. Search, comments, channel uploads, and playlist streams store pagination state on the native side. Calling getNextPage() returns the next page of the most recent query. Interleaving different queries will lose pagination state.

Multi-Service (SoundCloud, Bandcamp, PeerTube, media.ccc.de) #

  • Feature coverage varies by service. Not all services support all features (e.g., some may not have search suggestions or kiosks).
  • Channel content pagination for non-YouTube services may be limited depending on the service's feed support.
  • Service-specific features (e.g., SoundCloud likes, Bandcamp radio) are not exposed — only the generic extraction interface (search, streams, channels, playlists, kiosks) is available.
  • PeerTube instances require the instance URL in the content URL — there is no instance discovery mechanism.
  • No authentication. Private or premium content on any service cannot be accessed.

General #

  • No background extraction. All extraction runs on a single background thread. Concurrent calls from multiple isolates will queue sequentially.
  • Network dependent. All extraction requires an active internet connection. There is no offline caching.
  • No download manager. The plugin provides stream URLs but does not handle downloading, muxing, or file management.
  • Stream URLs expire. Media stream URLs returned by extractors are temporary and will expire (typically within hours). Do not persist them — re-extract when needed.

Author #

Muhammad UsmanGitHub

License #

BSD 3-Clause License — see LICENSE for details.

0
likes
0
points
152
downloads

Publisher

verified publisherottomancoder.com

Weekly Downloads

Flutter plugin wrapping NewPipe Extractor for YouTube data extraction. Extract video info, streams, subtitles, comments, channels, playlists, search results, and trending content — no API key required.

Repository (GitHub)
View/report issues

Topics

#youtube #video #extractor #newpipe #streaming

License

unknown (license)

Dependencies

flutter, flutter_inappwebview, freezed_annotation, http, json_annotation

More

Packages that depend on newpipeextractor_dart

Packages that implement newpipeextractor_dart