YouTubePHP Documentation

YouTube
in package
implements EventEmitterInterface uses EventEmitterTrait, Resources

FinalYes

The YouTube client: the same role `Discord\Discord` plays under DiscordPHP.

It owns the OAuth grant, the Http transport, the Factory, the quota Meter, and one API object per resource of the Data API v3: $youtube->liveChatMessages, $youtube->videos, and the rest, generated from Google's discovery document (Resources).

$youtube = new YouTube([
    'client_id' => '...',
    'client_secret' => '...',
    'token_store' => new EnvFileTokenStore(__DIR__ . '/.env'),
    'device_prompt' => fn (array $device) => print("Enter {$device['user_code']} at {$device['verification_uri']}\n"),
]);

$youtube->on('ready', function (YouTube $youtube) {
    $youtube->liveBroadcasts->list(part: 'snippet', broadcastStatus: 'active')
        ->then(fn ($response) => print(count($response->items) . " live now\n"));
});

$youtube->run();

The grant looks after itself:

  • Start: a refresh token, from the options or the token_store, is traded for an access token. With none, a device_prompt signs in with Google's device flow and the store keeps the result.
  • Refresh: access tokens last an hour, and each is refreshed five minutes before it runs out. A call that still gets a 401 recovers the token and is retried once.
  • Revoked: when Google refuses the refresh token itself (invalid_grant) the client signs in again. A refresh that fails for any other reason, such as the network, is not a reason to ask anyone for a code.

With only an api_key the client reads public data and signs nobody in.

Events:

Event Arguments When
ready YouTube Signed in, with the account's channel loaded.
error Throwable, YouTube run() could not start.
token_refreshed YouTube A new access token from the refresh token.
reauthorized YouTube A new grant from signing in again.
grant_expires int seconds, YouTube Google will end the grant soon, see below.
quota.exhausted string bucket, CarbonImmutable reset, YouTube A quota bucket ran out today. Once a day each.
closed YouTube close() was called.

grant_expires means the Google Cloud project's OAuth consent screen is in Testing, where every grant ends after seven days. Publishing the app ends that.

Tags
since
1.0.0
author

Valithor Obsidion valithor@valgorithms.com

Table of Contents

Interfaces

EventEmitterInterface

Constants

REFRESH_BEFORE  : mixed = 300
Seconds before an access token expires that it is refreshed.
VERSION  : mixed = '1.0.0'

Properties

$abuseReports  : AbuseReportsApi
Reports of abuse.
$activities  : ActivitiesApi
What a channel has been doing: uploads, likes, playlist changes and the rest of its feed.
$captions  : CaptionsApi
The caption tracks of videos.
$channelBanners  : ChannelBannersApi
Uploading a channel's banner image.
$channels  : ChannelsApi
Channels, the signed-in account's own included.
$channelSections  : ChannelSectionsApi
The shelves on a channel's page.
$comments  : CommentsApi
Single comments and replies, and moderating them.
$commentThreads  : CommentThreadsApi
Top-level comments, with their replies.
$i18nLanguages  : I18nLanguagesApi
The interface languages YouTube supports.
$i18nRegions  : I18nRegionsApi
The content regions YouTube supports.
$liveBroadcasts  : LiveBroadcastsApi
Live broadcasts: scheduling one, binding it to a stream, going live and ending it.
$liveChatBans  : LiveChatBansApi
Banning people from a live chat, and lifting bans.
$liveChatMessages  : LiveChatMessagesApi
Live chat: reading it, posting to it, and deleting from it.
$liveChatModerators  : LiveChatModeratorsApi
A live chat's moderators.
$liveStreams  : LiveStreamsApi
The video streams that live broadcasts are fed from.
$members  : MembersApi
A channel's members, which the API also calls sponsors.
$membershipsLevels  : MembershipsLevelsApi
A channel's membership levels.
$playlistImages  : PlaylistImagesApi
Playlists' cover images.
$playlistItems  : PlaylistItemsApi
The videos in playlists.
$playlists  : PlaylistsApi
Playlists.
$search  : SearchApi
Searching for videos, channels and playlists. It has its own quota: 100 calls a day.
$subscriptions  : SubscriptionsApi
Subscriptions between channels.
$superChatEvents  : SuperChatEventsApi
The Super Chats and Super Stickers bought on the signed-in channel.
$tests  : TestsApi
An internal method Google uses to test the API.
$thirdPartyLinks  : ThirdPartyLinksApi
Links between a channel and third-party services.
$thumbnails  : ThumbnailsApi
Setting a video's custom thumbnail.
$videoAbuseReportReasons  : VideoAbuseReportReasonsApi
The reasons a video can be reported for.
$videoCategories  : VideoCategoriesApi
The categories a video can be filed under.
$videos  : VideosApi
Videos: listing, uploading, updating, rating and reporting them.
$videoTrainability  : VideoTrainabilityApi
Whether a video may be used to train AI models.
$watermarks  : WatermarksApi
A channel's watermark image.
$channel  : ?Channel
$exhausted  : array<string, string>
$expiresAt  : ?int
When the access token expires, as a Unix time, if known.
$factory  : Factory
$http  : Http
$loadingChannel  : ?PromiseInterface
$logger  : LoggerInterface
$loop  : LoopInterface
$meter  : Meter
$oauth  : OAuth
$options  : array<string, mixed>
$reauthorizer  : ReauthorizerInterface
$reauthorizing  : ?PromiseInterface
The sign-in in flight, shared the same way.
$refreshing  : ?PromiseInterface
The refresh in flight, shared by every caller that arrives during it.
$refreshTimer  : ?TimerInterface
$refreshToken  : ?string
$scopes  : array<int, string>
$token  : ?string
$tokenStore  : ?TokenStoreInterface

Methods

__construct()  : mixed
bootstrap()  : PromiseInterface<string|int, Channel|null>
Signs in, loads the account's channel, and emits `ready`.
close()  : void
Stops the client's own timers. The loop belongs to whoever runs it, and is left alone.
getChannel()  : ?Channel
The signed-in account's channel, once {@see me()} has loaded it.
getFactory()  : Factory
getHttp()  : Http
getLogger()  : LoggerInterface
getLoop()  : LoopInterface
getMeter()  : Meter
Today's quota count.
getOAuth()  : OAuth
getScopes()  : array<int, string>
isSignedIn()  : bool
Whether calls go out with an access token, rather than an API key or nothing.
me()  : PromiseInterface<string|int, Channel>
The signed-in account's channel. Loaded once, for one unit of quota.
reauthorize()  : PromiseInterface<string|int, string>
Gets a brand-new grant from the configured {@see ReauthorizerInterface}.
refreshAccessToken()  : PromiseInterface<string|int, string>
Trades the refresh token for a fresh access token. Concurrent callers share one attempt. Emits `token_refreshed`.
request()  : PromiseInterface<string|int, mixed>
Sends one API call, recovering from a dead token once. The generated resource APIs go through here; so can a call to a method this build does not know.
run()  : void
Bootstraps, then runs the event loop.
stream()  : PromiseInterface<string|int, ResponseInterface>
Opens a server-streamed call, recovering from a dead token the same way.
acquireToken()  : PromiseInterface<string|int, string|null>
applyToken()  : void
Adopts a token payload from any grant: hands it to the transport, plans the next refresh, and writes it through to the store.
bootResources()  : void
Builds every resource API against this client.
now()  : int
persist()  : void
A store that cannot be written is logged and swallowed: losing it must not fail a call that otherwise worked.
quotaExhausted()  : void
Tells listeners once a day, per bucket, that its quota is gone.
recovering()  : PromiseInterface
recoverToken()  : PromiseInterface<string|int, string>
Gets back to a usable token: refresh if there is a refresh token, sign in again if there is not or Google has revoked it.
resolveOptions()  : array<string, mixed>
scheduleRefresh()  : void
Refreshes the access token a little before it runs out.

Constants

REFRESH_BEFORE

Seconds before an access token expires that it is refreshed.

public mixed REFRESH_BEFORE = 300

VERSION

public mixed VERSION = '1.0.0'

Properties

$activities read-only

What a channel has been doing: uploads, likes, playlist changes and the rest of its feed.

public ActivitiesApi $activities

$liveBroadcasts read-only

Live broadcasts: scheduling one, binding it to a stream, going live and ending it.

public LiveBroadcastsApi $liveBroadcasts

$members read-only

A channel's members, which the API also calls sponsors.

public MembersApi $members

Searching for videos, channels and playlists. It has its own quota: 100 calls a day.

public SearchApi $search

$superChatEvents read-only

The Super Chats and Super Stickers bought on the signed-in channel.

public SuperChatEventsApi $superChatEvents

$tests read-only

An internal method Google uses to test the API.

public TestsApi $tests

$videos read-only

Videos: listing, uploading, updating, rating and reporting them.

public VideosApi $videos

$exhausted

private array<string, string> $exhausted = []

Bucket => the quota day it was reported exhausted.

$expiresAt

When the access token expires, as a Unix time, if known.

private ?int $expiresAt = null

$loadingChannel

private ?PromiseInterface $loadingChannel = null

$logger

private LoggerInterface $logger

$options

private array<string, mixed> $options

$reauthorizing

The sign-in in flight, shared the same way.

private ?PromiseInterface $reauthorizing = null

$refreshing

The refresh in flight, shared by every caller that arrives during it.

private ?PromiseInterface $refreshing = null

$refreshTimer

private ?TimerInterface $refreshTimer = null

$refreshToken

private ?string $refreshToken

$scopes

private array<int, string> $scopes = []

The scopes the grant holds, once Google has said.

Methods

__construct()

public __construct([array<string, mixed> $options = [] ]) : mixed
Parameters
$options : array<string, mixed> = []

client_id string The OAuth client's id. client_secret string Its secret. Google needs it even for a device client. token ?string An access token. refresh_token ?string A refresh token, from an earlier sign-in. api_key ?string For public data, when nobody signs in. scopes list What a sign-in asks for. Default: Scope::YOUTUBE. token_store ?TokenStoreInterface Where the grant is kept between runs. device_prompt ?callable Signs in with the device flow, showing it the code. reauthorize ?ReauthorizerInterface Any other way to sign in again. quota array daily, search, uploads: the project's allowances. reserve: units background work leaves alone. path: a file to keep the count in. loop ?LoopInterface logger ?LoggerInterface socket_options array For React\Socket\Connector. driver ?DriverInterface Replaces the HTTP driver, for tests. clock ?\Closure(): float Replaces the clock, for tests.

bootstrap()

Signs in, loads the account's channel, and emits `ready`.

public bootstrap() : PromiseInterface<string|int, Channel|null>
Return values
PromiseInterface<string|int, Channel|null> —

The signed-in account's channel, or null with only an API key.

close()

Stops the client's own timers. The loop belongs to whoever runs it, and is left alone.

public close() : void

getChannel()

The signed-in account's channel, once {@see me()} has loaded it.

public getChannel() : ?Channel
Return values
?Channel

getLogger()

public getLogger() : LoggerInterface
Return values
LoggerInterface

getLoop()

public getLoop() : LoopInterface
Return values
LoopInterface

getScopes()

public getScopes() : array<int, string>
Return values
array<int, string> —

The scopes the grant holds, once Google has said.

isSignedIn()

Whether calls go out with an access token, rather than an API key or nothing.

public isSignedIn() : bool
Return values
bool

me()

The signed-in account's channel. Loaded once, for one unit of quota.

public me() : PromiseInterface<string|int, Channel>
Return values
PromiseInterface<string|int, Channel>

reauthorize()

Gets a brand-new grant from the configured {@see ReauthorizerInterface}.

public reauthorize() : PromiseInterface<string|int, string>

Concurrent callers share one attempt, so a burst of 401s cannot ask anyone for a code twice. Emits reauthorized.

Return values
PromiseInterface<string|int, string> —

The new access token.

refreshAccessToken()

Trades the refresh token for a fresh access token. Concurrent callers share one attempt. Emits `token_refreshed`.

public refreshAccessToken() : PromiseInterface<string|int, string>
Return values
PromiseInterface<string|int, string> —

The new access token.

request()

Sends one API call, recovering from a dead token once. The generated resource APIs go through here; so can a call to a method this build does not know.

public request(string $endpoint, string $method, string $path[, array<string, mixed> $query = [] ][, array<string, mixed>|JsonSerializable|null $body = null ][, ?Media $media = null ][, ?string $uploadPath = null ][, bool $download = false ]) : PromiseInterface<string|int, mixed>

A 401 refreshes the token (or signs in again, if that is what it takes) and the call is retried once. If that fails too, the original 401 is what surfaces: the caller asked about the call, not about the plumbing.

Parameters
$endpoint : string
$method : string
$path : string
$query : array<string, mixed> = []
$body : array<string, mixed>|JsonSerializable|null = null
$media : ?Media = null
$uploadPath : ?string = null
$download : bool = false
Return values
PromiseInterface<string|int, mixed> —

The decoded JSON, unhydrated.

run()

Bootstraps, then runs the event loop.

public run() : void

stream()

Opens a server-streamed call, recovering from a dead token the same way.

public stream(string $endpoint, string $path[, array<string, mixed> $query = [] ]) : PromiseInterface<string|int, ResponseInterface>
Parameters
$endpoint : string
$path : string
$query : array<string, mixed> = []
Return values
PromiseInterface<string|int, ResponseInterface> —

See Http::stream().

acquireToken()

private acquireToken() : PromiseInterface<string|int, string|null>
Return values
PromiseInterface<string|int, string|null> —

The access token, or null with only an API key.

applyToken()

Adopts a token payload from any grant: hands it to the transport, plans the next refresh, and writes it through to the store.

private applyToken(array<string, mixed> $token) : void
Parameters
$token : array<string, mixed>

bootResources()

Builds every resource API against this client.

private bootResources() : void

now()

private now() : int
Return values
int

persist()

A store that cannot be written is logged and swallowed: losing it must not fail a call that otherwise worked.

private persist(array<string, mixed> $token) : void
Parameters
$token : array<string, mixed>

quotaExhausted()

Tells listeners once a day, per bucket, that its quota is gone.

private quotaExhausted(string $endpoint) : void
Parameters
$endpoint : string

recovering()

private recovering(string $endpoint, callable(): PromiseInterface $send[, bool $retry = true ]) : PromiseInterface
Parameters
$endpoint : string
$send : callable(): PromiseInterface
$retry : bool = true
Return values
PromiseInterface

recoverToken()

Gets back to a usable token: refresh if there is a refresh token, sign in again if there is not or Google has revoked it.

private recoverToken() : PromiseInterface<string|int, string>
Return values
PromiseInterface<string|int, string>

resolveOptions()

private resolveOptions(array<string, mixed> $options) : array<string, mixed>
Parameters
$options : array<string, mixed>
Return values
array<string, mixed>

scheduleRefresh()

Refreshes the access token a little before it runs out.

private scheduleRefresh() : void
On this page

Search results