YoutubeExplodeDart

repository·master·Indexed 19 days ago

https://github.com/hexer10/youtube_explode_dart

A Dart port of the C# YoutubeExplode library that provides an interface to query metadata for YouTube videos, playlists, and channels, and to resolve and download video/audio streams and closed captions without requiring an official API key. It includes support for searching content, retrieving channel uploads, and handling JavaScript challenges via DenoEJSSolver.

Tokens
8.4K
Snippets
34
Records
45
Agent score
62%

What's inside youtube_explode_dart

  1. Download a video stream

    master

    YouTube videos provide different stream types:

    • Muxed: Contains both audio and video (limited to 360p30).
    • Audio-only: Contains only audio.
    • Video-only: Contains only video.

    To download, first request the stream manifest using yt.videos.streams.getManifest(videoId). You can optionally specify ytClients (e.g., YoutubeApiClient.safari) to merge streams from different clients. After filtering the manifest for a specific streamInfo, use yt.videos.streams.get(streamInfo) to obtain the actual byte Stream and pipe it to a file.

    var yt = YoutubeExplode();
    
    // 1. Get the manifest
    var manifest = yt.videos.streams.getManifest('Dpp1sIL1m5Q');
    
    // 2. Filter for a specific stream
    // highest bitrate audio-only stream
    var streamInfo = manifest.audioOnly.withHigestBitrate();
    
    // 3. Get the actual byte stream
    var stream = yt.videos.streams.get(streamInfo);
    
    // 4. Pipe to a file
    var file = File(filePath);
    var fileStream = file.openWrite();
    await stream.pipe(fileStream);
    await fileStream.flush();
    await fileStream.close();
  2. Customize iOS launch screen assets

    master

    To change the launch screen image in your Flutter iOS application, you can either replace the image files directly in the filesystem or use Xcode.

    Option 1: Filesystem replacement Replace the existing image files located in the ios/Runner/Assets.xcassets/LaunchImage.imageset/ directory with your own assets.

    Option 2: Using Xcode

    1. Open the iOS project in Xcode by running open ios/Runner.xcworkspace from your terminal.
    2. In the Xcode Project Navigator, navigate to Runner/Assets.xcassets.
    3. Drag and drop your desired images into the asset catalog.
    open ios/Runner.xcworkspace
  3. Use a signature solver with Deno

    master

    Some YouTube clients require a JavaScript challenge to be completed for downloads. This requires a JS runtime. Currently, the library supports DenoEJSSolver which requires the Deno runtime. Initialize the solver and pass it to the YoutubeExplode constructor via the jsSolver parameter.

    import 'package:youtube_explode_dart/solvers.dart';
    
    final solver = await DenoEJSSolver.init();
    var yt = YoutubeExplode(jsSolver: solver);
  4. Understand the SearchResult data models

    master

    The SearchResult class is an abstract base for different types of items returned from a YouTube search. When performing a search, you will receive a list of these objects, which you can distinguish using type checks (e.g., is SearchVideo).

    There are three main implementations of SearchResult:

    1. SearchVideo: Represents a single video.
    2. SearchPlaylist: Represents a playlist.
    3. SearchChannel: Represents a YouTube channel.

    All search results include a list of thumbnails and a unique id.

  5. Choose a YoutubeApiClient for different streaming needs

    master

    The YoutubeApiClient class provides several pre-configured client profiles that determine how the library interacts with YouTube's internal APIs. Choosing the right client is critical for bypassing restrictions, avoiding 403 errors, or obtaining specific stream qualities.

    • androidSdkless (Recommended for general use): An Android client without the androidSdkVersion field. It does not require a PO Token and provides better compatibility for streaming audio/video without 403 errors.
    • ios: Has limited streams but does not require signature deciphering.
    • safari: Provides high-quality muxed streams in the HLS (m3u8) format.
    • androidVr: Provides high-quality videos (not just VR).
    • tv: Used to bypass certain restrictions on videos.
    • androidMusic: Specifically for YouTube Music; works only for music and does not require signature deciphering.

    Specialized Clients

    • android: Provides muxed streams but is less reliable than ios. Note that this client includes androidSdkVersion, which may require a PO Token.
    • mweb: Sometimes includes low-quality streams (e.g., 144p12).
    • mediaConnect: Uses the MEDIA_CONNECT_FRONTEND client.

    Deprecated Clients

    • webCreator: Deprecated; YouTube always requires authentication for this client.
    • tvSimplyEmbedded: Deprecated; works for restricted videos and provides low-quality muxed streams (requires signature deciphering), but fails if embedding is disabled. It also requires authentication.
  6. Enable logging for troubleshooting

    master

    If you encounter issues, enable fine-grained logging using the logging package before initializing any YoutubeExplode code. This will help in capturing detailed logs and stack traces for reporting.

    import 'package:logging/logging.dart';
    
    // Before any YoutubeExplode code
    Logger.root.level = Level.FINER;
    Logger.root.onRecord.listen((e) {
      print(e);
      if (e.error != null) {
       print(e.error);
       print(e.stackTrace);
      }
    });
  7. Get related videos

    master

    Retrieve a list of related videos for a specific Video instance using yt.videos.getRelatedVideos(video). If the list is long, you can fetch subsequent pages using the nextPage() method on the returned object. If no related videos are found, the method returns null.

    var video = yt.videos.get('https://youtube.com/watch?v=Dpp1sIL1m5Q');
    var relatedVideos = await yt.videos.getRelatedVideos(video);
    
    if (relatedVideos != null) {
      print(relatedVideos);
      // To get the next page
      relatedVideos = await relatedVideos.nextPage();
    }
  8. Extract closed captions

    master

    To get closed captions, first retrieve the track manifest using yt.videos.closedCaptions.getManifest(videoId). Use manifest.getByLanguage(languageCode) to find a specific track. Once you have the trackInfo, use yt.videos.closedCaptions.get(trackInfo) to get the actual caption track, which allows you to retrieve text at specific timestamps using track.getByTime(duration).

    var yt = YoutubeExplode();
    var trackManifest = await yt.videos.closedCaptions.getManifest('_QdPW8JrYzQ');
    var trackInfo = trackManifest.getByLanguage('en');
    
    if (trackInfo != null) {
      var track = await yt.videos.closedCaptions.get(trackInfo);
      var caption = track.getByTime(Duration(seconds: 61));
      var text = caption?.text; // "And the game was afoot."
    }
  9. Work with playlists

    master

    Use yt.playlists.get(id) to retrieve playlist metadata. To iterate through the videos in a playlist, use yt.playlists.getVideos(playlistId), which returns a stream of videos. You can also fetch the entire list as a collection using await yt.playlists.getVideos(playlistId) or use .take(n) to limit the results.

    var yt = YoutubeExplode();
    
    // Get playlist metadata.
    var playlist = await yt.playlists.get('xxxxx');
    var title = playlist.title;
    
    // Iterate through videos
    await for (var video in yt.playlists.getVideos(playlist.id)) {
      var videoTitle = video.title;
    }
    
    // Get first 20 playlist videos
    var somePlaylistVideos = await yt.playlists.getVideos(playlist.id).take(20);
  10. Get metadata of a video

    master

    You can retrieve metadata for a YouTube video by providing either a video ID or a URL string to yt.videos.get(). This returns a Video instance containing properties like title, author, and duration.

    // You can provide either a video ID or URL as String or an instance of `VideoId`.
    var video = yt.videos.get('https://youtube.com/watch?v=Dpp1sIL1m5Q'); // Returns a Video instance.
    
    var title = video.title; // "Scamazon Prime"
    var author = video.author; // "Jim Browning"
    var duration = video.duration; // Instance of Duration - 0:19:48.00000