
Publish a video on a YouTube user channel
Developing an Android application for creating slide shows from photos, I was faced with the task of publishing ready-made videos on YouTube’s personal channel.
I had to tinker with, because Firstly, we use cloud computing and data processing can take longer than token works. And secondly, in order to implement the function, I had to face some inaccuracies and questions in the Google manual. Details under the cut.

The essence of the task:
When the user has selected all the photos on his Android and decided on the musical accompaniment, the data for processing is sent to the server, and the user is asked to indicate where to place the finished video: in the on-line collection on our server, on the general application channel on YouTube or your personal YouTube channel. (Also a link to download the video comes to the email address).
In the case of choosing a publication on a personal channel, we ask permission and upon confirmation we get the token necessary to access the channel, which is stored on the server along with user data and remains valid for 60 minutes.
But if the user has slow Internet (prolonged upload of photos) or a queue has accumulated on the server, token becomes invalid, a second request is required. For this situation, we immediately began to request token and refresh token, the validity period of the second is unlimited and we can publish the video even after 60 minutes.
Bugs fixed:
More details on what token and refresh token are and how to use them are in the manual, but there are things here that didn’t work exactly as described.
1. The very first difficulty: the token received on the device was invalid when used on the server.
In the end, we decided like this
On Android we use:
As a result, we get the authorization code, then we get token and refresh token ourselves
As a result, we get an answer of the form:
We get token and refresh token and send them to the server
On the server side like this:
To check the validity of the token:
As a result, we get an answer of the form:
If there is enough token life, then use it; if not, we get a new token, use refresh token:
As a result, we get an answer of the form:
We use the received token for the intended purpose.
2. Further, the parameters “scope”, “state” and “client_secret”: in some cases, where documentation must specify these parameters, the program generated an error if we installed them, and worked fine if not installed. And vice versa - sometimes they had to be used not only where indicated.
For example, the “state” parameter often returns the value in the form of the nearest US state where the Google server is located - this increases the speed of data exchange between the server and the device. In some cases, this parameter is specified as required. But in Russia it is useless.
“Scope” is responsible for what service we want to use when accessing Google. It is not clear where to get the full list of values for this parameter. Since we needed YouTube, we simply guessed it by specifying it. At the same time, it is not clear what parameter value should be if we want to refer, for example, to the Google calendar?
One of Google’s documentation requests needs the client_secret parameter. We do not have it. And if we receive and indicate, nothing works.
3. Most of our application is made on webserver. But when asking token, the webserver was invalid, so we applied installedapps and the requests came up to it. To be honest, they didn’t understand why.
4. In the documentation developers.google.com/accounts/docs/OAuth2InstalledApp#formingtheurltwo possible options for the redirect_uri parameter are indicated: “urn: ietf: wg: oauth: 2.0: oob” and localhost . How to use localhost , I did not understand, with “urn: ietf: wg: oauth: 2.0: oob” everything worked.
5. The question also remains open how to use the token received from the Android account on the device itself. Those. an account is tied to Android, and it is from this account that you can get token, but it is unclear how to use it. We use what we request from the user account.
6. It is not clear yet what scope to use specifically for “logging in with your GOOGLE account”? We use "to control YouTube."
7. And also wonder why the Google library for OAUTH2 Android weighs so much? Using it, our application becomes several times heavier, so we refused to use it.
Thanks for attention! I will be glad if someone helps my comments, as well as if someone can answer my questions.
I had to tinker with, because Firstly, we use cloud computing and data processing can take longer than token works. And secondly, in order to implement the function, I had to face some inaccuracies and questions in the Google manual. Details under the cut.

The essence of the task:
When the user has selected all the photos on his Android and decided on the musical accompaniment, the data for processing is sent to the server, and the user is asked to indicate where to place the finished video: in the on-line collection on our server, on the general application channel on YouTube or your personal YouTube channel. (Also a link to download the video comes to the email address).
In the case of choosing a publication on a personal channel, we ask permission and upon confirmation we get the token necessary to access the channel, which is stored on the server along with user data and remains valid for 60 minutes.
But if the user has slow Internet (prolonged upload of photos) or a queue has accumulated on the server, token becomes invalid, a second request is required. For this situation, we immediately began to request token and refresh token, the validity period of the second is unlimited and we can publish the video even after 60 minutes.
Bugs fixed:
More details on what token and refresh token are and how to use them are in the manual, but there are things here that didn’t work exactly as described.
1. The very first difficulty: the token received on the device was invalid when used on the server.
In the end, we decided like this
On Android we use:
Intent intent = new Intent(...);
intent.setData(Uri.parse("https://accounts.google.com/o/oauth2/auth?"+
"scope= " + scope + "&" +
"redirect_uri=" + redirect_uri + "&" +
"response_type=" + response_type + "&" +
"client_id=" + client_id));
startActivityForResult(intent);
As a result, we get the authorization code, then we get token and refresh token ourselves
HttpPosthttppost = newHttpPost("https://accounts.google.com/o/oauth2/token");
httppost.setHeader("Content-Type", "application/x-www-form-urlencoded");
ListnameValuePairs = newArrayList();
nameValuePairs.add(newBasicNameValuePair("code", code));
nameValuePairs.add(newBasicNameValuePair("client_id", client_id));
nameValuePairs.add(newBasicNameValuePair("redirect_uri", redirect_uri));
nameValuePairs.add(newBasicNameValuePair("grant_type", "authorization_code"));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
BufferedReader reader = new BufferedReader(new InputStreamReader(entity.getContent()));
String responseLines;
while ((line = reader.readLine()) != null) {
responseLines += line;
}
JSONObject jsonObject = new JSONObject(responseLines);
As a result, we get an answer of the form:
{
"access_token":"1/fFAGRNJru1FTz70BzhT3Zg",
"expires_in":3920,
"token_type":"Bearer",
"refresh_token":"1/xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI"
}
We get token and refresh token and send them to the server
On the server side like this:
To check the validity of the token:
var verificationUri = "https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=" + youTubeToken;
var hc = new HttpClient();
var response = hc.GetAsync(verificationUri).Result;
string tokenInfo = response.Content.ReadAsStringAsync().Result;
JsonTextParser parse = new JsonTextParser();
JsonObject jsonObj = parse.Parse(tokenInfo);
As a result, we get an answer of the form:
{
"access_token":"1/fFAGRNJru1FTz70BzhT3Zg",
"expires_in":320,
"token_type":"Bearer"
}
If there is enough token life, then use it; if not, we get a new token, use refresh token:
WebClient client = new WebClient();
NameValueCollectionloginFormValues = newNameValueCollection();
loginFormValues.Add("client_id", client_id);
loginFormValues.Add("refresh_token", refreshYouTubeToken);
loginFormValues.Add("grant_type", "refresh_token");
Byte[] response = client.UploadValues("https://accounts.google.com/o/oauth2/token", loginFormValues);
string result = Encoding.UTF8.GetString(response);
JsonTextParser parse = newJsonTextParser();
JsonObjectjsonObj = parse.Parse(result);
As a result, we get an answer of the form:
{
"access_token":"1/fFBGRNJru1FQd44AzqT3Zg",
"expires_in":3600,
"token_type":"Bearer",
}
We use the received token for the intended purpose.
2. Further, the parameters “scope”, “state” and “client_secret”: in some cases, where documentation must specify these parameters, the program generated an error if we installed them, and worked fine if not installed. And vice versa - sometimes they had to be used not only where indicated.
For example, the “state” parameter often returns the value in the form of the nearest US state where the Google server is located - this increases the speed of data exchange between the server and the device. In some cases, this parameter is specified as required. But in Russia it is useless.
“Scope” is responsible for what service we want to use when accessing Google. It is not clear where to get the full list of values for this parameter. Since we needed YouTube, we simply guessed it by specifying it. At the same time, it is not clear what parameter value should be if we want to refer, for example, to the Google calendar?
One of Google’s documentation requests needs the client_secret parameter. We do not have it. And if we receive and indicate, nothing works.
3. Most of our application is made on webserver. But when asking token, the webserver was invalid, so we applied installedapps and the requests came up to it. To be honest, they didn’t understand why.
4. In the documentation developers.google.com/accounts/docs/OAuth2InstalledApp#formingtheurltwo possible options for the redirect_uri parameter are indicated: “urn: ietf: wg: oauth: 2.0: oob” and localhost . How to use localhost , I did not understand, with “urn: ietf: wg: oauth: 2.0: oob” everything worked.
5. The question also remains open how to use the token received from the Android account on the device itself. Those. an account is tied to Android, and it is from this account that you can get token, but it is unclear how to use it. We use what we request from the user account.
6. It is not clear yet what scope to use specifically for “logging in with your GOOGLE account”? We use "to control YouTube."
7. And also wonder why the Google library for OAUTH2 Android weighs so much? Using it, our application becomes several times heavier, so we refused to use it.
Thanks for attention! I will be glad if someone helps my comments, as well as if someone can answer my questions.