Skip to content

Commit c1d67fd

Browse files
"Added sample: javascript/upload_video.js"
1 parent 92a5ea5 commit c1d67fd

1 file changed

Lines changed: 199 additions & 0 deletions

File tree

javascript/upload_video.js

Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
/*
2+
Copyright 2015 Google Inc. All Rights Reserved.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
var signinCallback = function (result){
18+
if(result.access_token) {
19+
var uploadVideo = new UploadVideo();
20+
uploadVideo.ready(result.access_token);
21+
}
22+
};
23+
24+
var STATUS_POLLING_INTERVAL_MILLIS = 60 * 1000; // One minute.
25+
26+
27+
/**
28+
* YouTube video uploader class
29+
*
30+
* @constructor
31+
*/
32+
var UploadVideo = function() {
33+
/**
34+
* The array of tags for the new YouTube video.
35+
*
36+
* @attribute tags
37+
* @type Array.<string>
38+
* @default ['google-cors-upload']
39+
*/
40+
this.tags = ['youtube-cors-upload'];
41+
42+
/**
43+
* The numeric YouTube
44+
* [category id](https://developers.google.com/apis-explorer/#p/youtube/v3/youtube.videoCategories.list?part=snippet&regionCode=us).
45+
*
46+
* @attribute categoryId
47+
* @type number
48+
* @default 22
49+
*/
50+
this.categoryId = 22;
51+
52+
/**
53+
* The id of the new video.
54+
*
55+
* @attribute videoId
56+
* @type string
57+
* @default ''
58+
*/
59+
this.videoId = '';
60+
61+
this.uploadStartTime = 0;
62+
};
63+
64+
65+
UploadVideo.prototype.ready = function(accessToken) {
66+
this.accessToken = accessToken;
67+
this.gapi = gapi;
68+
this.authenticated = true;
69+
this.gapi.client.request({
70+
path: '/youtube/v3/channels',
71+
params: {
72+
part: 'snippet',
73+
mine: true
74+
},
75+
callback: function(response) {
76+
if (response.error) {
77+
console.log(response.error.message);
78+
} else {
79+
$('#channel-name').text(response.items[0].snippet.title);
80+
$('#channel-thumbnail').attr('src', response.items[0].snippet.thumbnails.default.url);
81+
82+
$('.pre-sign-in').hide();
83+
$('.post-sign-in').show();
84+
}
85+
}.bind(this)
86+
});
87+
$('#button').on("click", this.handleUploadClicked.bind(this));
88+
};
89+
90+
/**
91+
* Uploads a video file to YouTube.
92+
*
93+
* @method uploadFile
94+
* @param {object} file File object corresponding to the video to upload.
95+
*/
96+
UploadVideo.prototype.uploadFile = function(file) {
97+
var metadata = {
98+
snippet: {
99+
title: $('#title').val(),
100+
description: $('#description').text(),
101+
tags: this.tags,
102+
categoryId: this.categoryId
103+
},
104+
status: {
105+
privacyStatus: $('#privacy-status option:selected').text()
106+
}
107+
};
108+
var uploader = new MediaUploader({
109+
baseUrl: 'https://www.googleapis.com/upload/youtube/v3/videos',
110+
file: file,
111+
token: this.accessToken,
112+
metadata: metadata,
113+
params: {
114+
part: Object.keys(metadata).join(',')
115+
},
116+
onError: function(data) {
117+
var message = data;
118+
// Assuming the error is raised by the YouTube API, data will be
119+
// a JSON string with error.message set. That may not be the
120+
// only time onError will be raised, though.
121+
try {
122+
var errorResponse = JSON.parse(data);
123+
message = errorResponse.error.message;
124+
} finally {
125+
alert(message);
126+
}
127+
}.bind(this),
128+
onProgress: function(data) {
129+
var currentTime = Date.now();
130+
var bytesUploaded = data.loaded;
131+
var totalBytes = data.total;
132+
// The times are in millis, so we need to divide by 1000 to get seconds.
133+
var bytesPerSecond = bytesUploaded / ((currentTime - this.uploadStartTime) / 1000);
134+
var estimatedSecondsRemaining = (totalBytes - bytesUploaded) / bytesPerSecond;
135+
var percentageComplete = (bytesUploaded * 100) / totalBytes;
136+
137+
$('#upload-progress').attr({
138+
value: bytesUploaded,
139+
max: totalBytes
140+
});
141+
142+
$('#percent-transferred').text(percentageComplete);
143+
$('#bytes-transferred').text(bytesUploaded);
144+
$('#total-bytes').text(totalBytes);
145+
146+
$('.during-upload').show();
147+
}.bind(this),
148+
onComplete: function(data) {
149+
var uploadResponse = JSON.parse(data);
150+
this.videoId = uploadResponse.id;
151+
$('#video-id').text(this.videoId);
152+
$('.post-upload').show();
153+
this.pollForVideoStatus();
154+
}.bind(this)
155+
});
156+
// This won't correspond to the *exact* start of the upload, but it should be close enough.
157+
this.uploadStartTime = Date.now();
158+
uploader.upload();
159+
};
160+
161+
UploadVideo.prototype.handleUploadClicked = function() {
162+
$('#button').attr('disabled', true);
163+
this.uploadFile($('#file').get(0).files[0]);
164+
};
165+
166+
UploadVideo.prototype.pollForVideoStatus = function() {
167+
this.gapi.client.request({
168+
path: '/youtube/v3/videos',
169+
params: {
170+
part: 'status,player',
171+
id: this.videoId
172+
},
173+
callback: function(response) {
174+
if (response.error) {
175+
// The status polling failed.
176+
console.log(response.error.message);
177+
setTimeout(this.pollForVideoStatus.bind(this), STATUS_POLLING_INTERVAL_MILLIS);
178+
} else {
179+
var uploadStatus = response.items[0].status.uploadStatus;
180+
switch (uploadStatus) {
181+
// This is a non-final status, so we need to poll again.
182+
case 'uploaded':
183+
$('#post-upload-status').append('<li>Upload status: ' + uploadStatus + '</li>');
184+
setTimeout(this.pollForVideoStatus.bind(this), STATUS_POLLING_INTERVAL_MILLIS);
185+
break;
186+
// The video was successfully transcoded and is available.
187+
case 'processed':
188+
$('#player').append(response.items[0].player.embedHtml);
189+
$('#post-upload-status').append('<li>Final status.</li>');
190+
break;
191+
// All other statuses indicate a permanent transcoding failure.
192+
default:
193+
$('#post-upload-status').append('<li>Transcoding failed.</li>');
194+
break;
195+
}
196+
}
197+
}.bind(this)
198+
});
199+
};

0 commit comments

Comments
 (0)