Youtube REST API Client

pub package

Native Dart interface to multiple Google REST APIs, including:

How does this package differ from the googleapis package?

  • It's not generated, it's manually coded and limited to a targeted set to just YouTube APIs
  • Since it's not generated the package includes additional useful features like a cli (Command Line Interface) and the experimental Chatbot
  • A tighter focus to the package means focused documentation and focused examples

New for version 2.0.0

As of the 2.0.0 release of this package there is a cli utility included that can be used to return data for any API call currently supported by the package. If you want to get started quicky with the cli utility run these commands in a terminal session:

pub global activate yt

yt --help

Please see the cli documentation README.md for more detailed usage information.

NOTE: Cloud Vision API support has been permanently removed from this package and will be available as it's own package. Additionally, cache support has been temporarily removed.

API Commands Supported

Data API

Live Streaming API

Custom Features (experimental)

  • download chat history from a LiveChat
  • simple chatbot functionality for LiveChat

Getting Started

To use this package, add the dependency to your pubspec.yaml file:

dependencies:
  ...
  yt: ^2.0.5

Obtaining Authorization Credentials

YouTube API access requires an access token or API key depending on the API and the type of information being accessed. As a general rule of thumb, read-only public information cand be accessed through an API key, otherwise an access token is required.

The yt library supports two mechanisms for authentication. All of the authentication schemes require some configuration in the Google API console. The document Obtaining authorization credentials covers authentication with OAuth 2.0 which works for both the Data API and the Live Streaming API the same document also covers authenticating with API keys which works only with the Data API.

More in depth documentation on how OAuth2 works within the yt library is available in the OAuth 2.0 for Mobile & Desktop Apps document. Overall, for OAuth2 the library takes a provided single use auth code and generates a long lived OAuth2 refresh token that is persisted as a hidden file.

Both of the above authentication methods will work for Flutter apps as well, however you may want to instead allow your app's users to use their own YouTube credentials. Instructions for authenticating this way are included at the end of this document in the Usage within Flutter section.

A number of the examples use OAuth 2.0 for authentication. The examples have the OAuth2 credentials made available to sample the code though a .json or .yaml file that contains these lines:

clientId: [client id from the API console]
clientSecret: [client secret from the API console]
code: [single use auth code]

The .json version of this file can be generated using the cli utility:

#make sure you've created an app instance in the Goolge API console
#make sure you've already activated the cli utility "pub global activate yt"

yt authorize

#follow the prompts to provide clientID, clientSecret, then use a browser to 
#authenticate and generate the one-time code

After following the steps provided by the cli command, your credential file will be auto created as $HOME/.yt/credentials.json

Alternatively, if you want to manually create your credentials file, then you will need to use a browser to generate the required one-time code. Once you have followed the instructions outlined in the YouTube docs for creating the app instance and obtaining the OAuth2 credentials, then the next step is to enter this url into a desktop browser:

https://accounts.google.com/o/oauth2/auth?client_id=[client_id_from_the_API_console]&redirect_uri=urn:ietf:wg:oauth:2.0:oob&scope=https://www.googleapis.com/auth/youtube&response_type=code

After following the steps to authorize the provdided account with the app created in the API console, you will be presented with an single use authorization code. The code is entered as the code line in the yaml or _json_file referenced above.

Using of the Data API

Youtube provides multiple methods for API authentication. The Data API can use both API key and OAuth for authentication the example below shows how both of these

import 'package:yt/yt.dart';

//if you used "yt authorize" to generate a credentials file
final yt = await Yt.withOAuth();

//authenticate using OAuth - manually created file
//final yt = await Yt.withOAuth(OAuthCredentials.fromYaml('example/youtube.yaml'));

//some APIs can use an API Key for authentication
//final yt = await Yt.withKey('[youtube api key]');

// List of videos from playlist
var playlistResponse = await yt.playlists.list(
      channelId: '[youtube channel id]', maxResults: 25);

playlistResponse.items
    .forEach((playlist) => print('${playlist.snippet?.title}'));

Upload a Video

final yt = await Yt.withOAuth();

final body = <String, dynamic>{
  'snippet': {
    'title': 'TEST title',
    'description': 'Test Description',
    'tags': ['tag1', 'tag2'],
    'categoryId': "22"
  },
  'status': {
    'privacyStatus': 'private',
    "embeddable": true,
    "license": "youtube"
  }
};

final videoItem = await yt.videos.insert(
    body: body,
    videoFile:
        File('[path to a video to upload]'),
    notifySubscribers: false);

print(videoItem);

Using the Live Streaming API

import 'package:yt/yt.dart';

final yt = await Yt.withOAuth();

///the live streaming broadcast API client
final br = yt.broadcast;

///the thumbnail data API client
final th = yt.thumbnails;

///create a private broadcast for 2 hours from now
final broadcastItem = await br.insert(body: {
  'snippet': {
    'title': 'TEST Broadcast',
    'description': 'Test',
    'scheduledStartTime':
        DateTime.now().add(Duration(hours: 2)).toUtc().toIso8601String()
  },
  'status': {'privacyStatus': 'private'},
  'contentDetails': {
    'monitorStream': {
      'enableMonitorStream': false,
      'broadcastStreamDelayMs': 10
    },
    'enableDvr': true,
    'enableContentEncryption': true,
    'enableEmbed': true,
    'recordFromStart': true,
    'startWithSlate': false
  }
}, part: 'snippet,status,contentDetails');

///bind the broadcast to an existing stream
await br.bind(
    broadcastId: broadcastItem.id,
    streamId: '[one of your valid stream ids]');

///upload the thumbnail
await th.set(
    videoId: broadcastItem.id,
    thumbnail: File('[path to an image to upload]'));

Download a LiveChat

import 'package:yt/yt.dart';

final yt = await Yt.withOAuth();

var broadcastResponse = await yt.broadcast.list(broadcastStatus: 'active');

if (broadcastResponse.items.isNotEmpty) {
  //will download and output to stdout
  await yt.chat.downloadHistory(liveBroadcastItem: broadcastResponse.items.first);
}

Experimental Chatbot

final yt = await Yt.withOAuth();

//the live streaming broadcast API client
final br = yt.broadcast;

//look for an active broadcast
var broadcastResponse = await br.list(broadcastStatus: 'active');

//get an upcoming broadcast, if there's no active
if (broadcastResponse.items.isEmpty) {
  broadcastResponse =
      await br.list(broadcastStatus: 'upcoming', maxResults: 1);
}

if (broadcastResponse.items.isNotEmpty) {
  final liveBroadcastItem = broadcastResponse.items.first;

  //setup the chatbot with a custom dialog
  final chatbot = Chatbot.fromYaml(File('chatbot.yaml'));

  //if being run periodically you will want to provide a TimeStore to persist
  //a timestamp that will ensure the chatbot doesn't repeat answers
  await yt.chat
      .answerBot(liveBroadcastItem: liveBroadcastItem, chatbot: chatbot);
}

Usage within Flutter

This library does not include any Flutter dependencies but it can be easily integrated with Flutter code using any of the authentication mechanisms described above. In addition, for some applications there may be a desire to use the user's own YouTube credentials for authentication. The library uses the concept of a TokenGenerator to allow for this. TokenGenerator is an abstract class that is extended within the library through the JwtGenerator and OAuthGenerator classes, and generates the authentication token used in API calls to YouTube.

For a Flutter app the TokenGenerator can be extended to allow for auth tokens to be generated through the google_sign_in pacakge provided by the flutter.dev team. Keep in mind that you must fulfill all of the requirements for the google_sign_in package before attempting to use the code below. The code to use google_sign_in for authentication:

import 'package:google_sign_in/google_sign_in.dart';
import 'package:yt/yt.dart';

class YtLoginGenerator implements TokenGenerator {
  final GoogleSignIn _googleSignIn = GoogleSignIn(
    scopes: [
      'email',
      'https://www.googleapis.com/auth/youtube',
    ],
  );

  @override
  Future<Token> generate() async {
    var _currentUser = await _googleSignIn.signInSilently();

    if (_currentUser == null) _currentUser = await _googleSignIn.signIn();

    final token = (await _currentUser!.authentication).accessToken;

    if (token == null) throw Exception();

    return Token(
        accessToken: token, expiresIn: 3599, scope: null, tokenType: '');
  }
}

With the generator in place, it becomes quite easy to include google sign-in for YouTube into your Flutter app. In one of your controllers you would include code like:

  //class definitions for a Flutter app
  ...
  final items = <Playlist>[];

  late final Yt yt;

  Playlists? playlists;

  @override
  void initState() {
    super.initState();

    _init();
  }

  void _init() async {
    yt = await Yt.withGenerator(YtLoginGenerator());
  }

  void _getPlaylists() async {
    items.clear();

    setState(() {
      items.addAll(await yt.playlists.list(mine: true));
    });
  }

    @override
  Widget build(BuildContext context) {
    //ListView.builder
    ...
    floatingActionButton: FloatingActionButton(
        onPressed: _getPlaylists,
        child: Icon(Icons.add),
      )
  }

Available Examples

What's Next?

  • A working sample Flutter app
  • Expanded API Commands

Breaking change in v2.0.0 from v1.2.x

The Yt object now returuns a Future and the reference to a specific API module is no longer a Future. So now you can use the following code:

final yt = await Yt.withOAuth(); //uses default credentials file, created with "yt authorize" cli utility

final playlists = yt.playlists;

var playlistResponse = await yt.playlists.list(
      channelId: '[youtube channel id]', maxResults: 25);

in place of:

final yt = Yt.withOAuth(OAuthCredentials.fromYaml('example/youtube.yaml'));

final playlists = await yt.playlists;

var playlistResponse = await yt.playlists.list(
      channelId: '[youtube channel id]', maxResults: 25);

Breaking change in v1.1.0 from v1.0.x

The latest revision has been updated so that it better matches the actual Youtube Data API for thumbnail upload. So, whereas in v1.0.x you would use this code to upload a thumbnail:

final th = await yt.thumbnails;

///get info on where to upload your thumbnail for the broadcast
final locationUrl = await th.location(videoId: broadcastItem.id);

///upload the thumbnail
await th.set(
    videoId: broadcastItem.id,
    uploadId: Uri.parse(locationUrl).queryParameters['upload_id']!,
    thumbnail: File('[path to an image to upload]'));

In v1.1.x the code has been simplified and matches the API definition:


///upload the thumbnail
final th = await yt.thumbnails;

await th.set(
    videoId: broadcastItem.id,
    thumbnail: File('[path to an image to upload]'));

Buy me a coffee

Libraries

authorization_exception
emoji_formatter
extras
phrase_match
time_store
token_generator
util
yt
The YouTube Live Streaming API reference explains how to schedule live broadcasts and video streams on YouTube using the YouTube Live Streaming API.