There's no way for one to specify a channel ID to the Videos.insert API endpoint. But bear with me for a while...
The first time one issues the OAuth 2.0 authorization flow, his/her app is receiving something as the following JSON object:
{
"access_token": "1/fFAGRNJru1FTz70BzhT3Zg",
"expires_in": 3920,
"token_type": "Bearer",
"scope": "https://www.googleapis.com/auth/youtube.force-ssl",
"refresh_token": "1//xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI"
}
The access token is short-lived, while the refresh token is long-lived (but can be revoked at will). This kind of JSON object gets cached in a local file, for to be used later when the app needs a fresh access token (that is obtained from the API based on the stored refresh token). The access token needs to be passed on to each API endpoint that requires authorization.
The above two tokens are relative to the Google account that one has been logged into during the authorization process. Under most common circumstances, each Google account is uniquely associated to a certain YouTube account (i.e. channel). But there can be Google accounts that are associated with multiple YouTube channels (see this doc, the section Use Brand Accounts managed by your Google Account).
Now my conjecture: I do think that it's possible for one to have N such JSON objects (relative to the same scope; e.g. https://www.googleapis.com/auth/youtube.upload), each being associated with a different Youtube channel -- all under the umbrella of a single Google account --, all being stored locally in separate files (or even all in one file), such that, when issuing API calls that need to target a given channel, to choose programmatically the associated pair of tokens out of the whole set of N objects.
The second part of my answer contains source code illustrating my conjecture above. It's not my intention to present here a complete and/or an all-encompassing solution, but only to set forth an application frame that would fit the various ways a concrete PHP app may function (e.g. single desktop apps or apps that run autonomously on remote servers that have no browser installed).
The app manages a set of JSON files -- all stored in the same directory ($auth_conf_path). Each file contains the required credentials relative to a certain channel, such that to be able to create from it a proper instance of class Google_Client. The names of these JSON files are of form CHANNEL_ID.json, where CHANNEL_ID is the ID of the channel to which this file is referring to.
The app is split into two parts: one creating these credentials JSON files upon initiating OAuth authorization flows; the other making API calls relative to a given channel for which a credentials JSON file already exists.
The first part of the app, by using initChannelCredentials within an usual PHP OAuth flow, produces IDs of and credentials JSON files relative to YouTube channels to which the app was granted access to.
The second part of the app, upon obtaining an instance of Google_Client class from makeChannelClient, makes actual API endpoint calls relative to the channel identified by the ID passed to that function.
function initChannelCredentials(
$auth_conf_path, $scopes, $redirect_uri, $client_code)
{
if (!is_dir($auth_conf_path))
throw new InvalidArgumentException(sprintf(
'Auth config path "%s" does not exist', $auth_conf_path));
$client = new Google_Client();
$client->setAuthConfigFile(
$auth_conf_path . DIRECTORY_SEPARATOR . 'client_secrets.json');
$client->setRedirectUri($redirect_uri);
$client->setScopes($scopes);
$cred = $client->fetchAccessTokenWithAuthCode($client_code);
$youtube = new Google_Service_YouTube($client);
$response = $youtube->channels->listChannels('id', array(
'mine' => 'true'
));
$channel_id = $response[0]['id'];
$cred_file = $auth_conf_path . DIRECTORY_SEPARATOR . $channel_id . '.json';
if (file_exists($cred_file))
throw new InvalidArgumentException(sprintf(
'Credentials file for channel "%s" already exists', $channel_id));
file_put_contents($cred_file, json_encode($cred));
return $channel_id;
}
function makeChannelClient($auth_conf_path, $channel_id)
{
if (!is_dir($auth_conf_path))
throw new InvalidArgumentException(sprintf(
'Auth config path "%s" does not exist', $auth_conf_path));
$cred_file = $auth_conf_path . DIRECTORY_SEPARATOR . $channel_id . '.json';
if (!file_exists($cred_file))
throw new InvalidArgumentException(sprintf(
'Credentials file for channel "%s" does not exist', $channel_id));
if (!$cred = json_decode(file_get_contents($cred_file), true))
throw new LogicException(sprintf(
'Invalid content of credentials file for channel "%s"', $channel_id));
$client = new Google_Client();
$client->setAccessType('offline');
$client->setScopes($cred['scope']);
$client->setAccessToken($cred);
if ($client->isAccessTokenExpired()) {
$client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
file_put_contents($cred_file, json_encode($client->getAccessToken()));
}
return $client;
}
Note that an app as described above is a bit more general than the one subsumed to the original post and to my conjecture above. The credentials JSON files -- equally the YouTube channels -- managed by the app are not required to work all under the umbrella of a single Google account (as was prescribed by my conjecture). These channels may well be relative to different Google accounts, as long as the concrete incarnation of such a PHP app is able to handle properly multiple Google accounts.