I am working on an Android app that records video and allows the user to upload it directly to YouTube using the YouTube Data API v3. The code is similar to that described in:
YouTube API 3 Upload Video - Access not configured - Android
It successfully uploads files to YouTube in the majority of cases, however, when the file is very large (~ hours of footage, several GB of data), the upload fails. The upload reaches about half way through a 4GB file and then produces this message:
{
"code": 401,
"errors": [
{
"domain": "global",
"location": "Authorization",
"locationType": "header",
"message": "Invalid Credentials",
"reason": "authError"
}
],
"message": "Invalid Credentials"
}
There is no change between the successful and unsuccessful code. The credentials are the same. The upload works for about an hour before failing.
Other potentially useful information is found in the Android stacktrace:
W/GLSUser(1794): [amz][amz] Permission for com.package.name to access oauth2: https://www.googleapis.com/auth/youtube.upload will be managed remotely.
W/qdhwcomposer(318): Excessive delay reading vsync: took 1182 ms
W/HttpTransport(8543): exception thrown while executing request
W/HttpTransport(8543): java.io.IOException: unexpected end of stream
W/HttpTransport(8543): at libcore.net.http.FixedLengthOutputStream.close(FixedLengthOutputStream.java:58)
W/HttpTransport(8543): at com.google.api.client.http.javanet.NetHttpRequest.execute(NetHttpRequest.java:81)
W/HttpTransport(8543): at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:964)
W/HttpTransport(8543): at com.google.api.client.googleapis.media.MediaHttpUploader.executeCurrentRequest(MediaHttpUploader.java:559)
W/HttpTransport(8543): at com.google.api.client.googleapis.media.MediaHttpUploader.resumableUpload(MediaHttpUploader.java:434)
W/HttpTransport(8543): at com.google.api.client.googleapis.media.MediaHttpUploader.upload(MediaHttpUploader.java:345)
W/HttpTransport(8543): at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:418)
W/HttpTransport(8543): at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:343)
W/HttpTransport(8543): at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:460)
W/HttpTransport(8543): at com.multplx.android.trickbook.uploader.VideoUploadAsyncTask.doInBackground(VideoUploadAsyncTask.java:133)
W/HttpTransport(8543): at com.multplx.android.trickbook.uploader.VideoUploadAsyncTask.doInBackground(VideoUploadAsyncTask.java:1)
W/HttpTransport(8543): at android.os.AsyncTask$2.call(AsyncTask.java:287)
W/HttpTransport(8543): at java.util.concurrent.FutureTask.run(FutureTask.java:234)
W/HttpTransport(8543): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
W/HttpTransport(8543): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
W/HttpTransport(8543): at java.lang.Thread.run(Thread.java:841)
W/VideoUploadAsyncTask(8543): @ Exception : com.google.api.client.googleapis.json.GoogleJsonResponseException: 401 Unauthorized
Which corresponds to:
try {
// https://developers.google.com/youtube/v3/docs/videos/insert
Insert videoInsert = inserts[0];
uploader = videoInsert.getMediaHttpUploader();
uploader.setProgressListener(progressListener);
Video returnedVideo = videoInsert.execute();
} catch (IOException ioe) {
...
}