Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(31)

Side by Side Diff: polymer_1.0.4/bower_components/google-youtube-upload/google-youtube-upload.html

Issue 1205703007: Add polymer 1.0 to npm_modules (Closed) Base URL: https://chromium.googlesource.com/infra/third_party/npm_modules.git@master
Patch Set: Renamed folder to 1.0.4 Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 <link rel="import" href="../polymer/polymer.html">
2 <link rel="import" href="../google-signin/google-signin.html">
3 <link rel="import" href="../google-apis/google-client-loader.html">
4 <!--
5 Element enabling you to upload videos to YouTube.
6
7 ##### Examples
8
9 Manual upload with a `Video Upload` button once a video file is selected:
10
11 <google-youtube-upload client-id="..."></google-youtube-upload>
12
13 Automatic upload on video file select, with a custom title, and 'unlisted' priva cy:
14
15 <google-youtube-upload
16 auto
17 video-title="My Awesome Video"
18 privacy-status="unlisted"
19 client-id="...">
20 </google-youtube-upload>
21
22 @demo
23 -->
24 <dom-module id="google-youtube-upload">
25 <link rel="import" type="css" href="google-youtube-upload.css">
26 <template>
27 <script src="../cors-upload-sample/upload.js"></script>
28 <google-client-loader on-js-api-load="_clientLoaded"></google-client-loader>
29 <div id="login-logout">
30 <img id="channel-image" src="{{_channel.thumbnail}}" style$="{{_computeCha nnelImageStyle(_channel.thumbnail)}}">
31 <span id="channel-name">{{_channel.name}}</span>
32
33 <google-signin
34 client-id="{{clientId}}"
35 scopes="https://www.googleapis.com/auth/youtube.upload https://www.googl eapis.com/auth/youtube.readonly">
36 </google-signin>
37 </div>
38
39 <div style="_computeUploadDivStyle(authenticated)}}">
40 <input type="file" id="file" class="button" accept="video/*" on-change="_h andleFileChanged">
41
42 <button on-click="_handleUploadClicked" style$="{{_computeUploadButtonStyl e(auto}}" disabled="{{!_selectedFile}}">Upload Video</button>
43
44 <p id="disclaimer">By uploading a video, you certify that you own all righ ts to the content or that you are authorized by the owner to make the content pu blicly available on YouTube, and that it otherwise complies with the YouTube Ter ms of Service located at <a href="http://www.youtube.com/t/terms" target="_blank ">http://www.youtube.com/t/terms</a></p>
45 </div>
46 </template>
47 </dom-module>
48 <script>
49 (function() {
50 // One minute.
51 var STATUS_POLLING_ITERVAL_MILLIS = 60 * 1000;
52
53 Polymer( {
54
55 is: 'google-youtube-upload',
56 /**
57 * Fired when the upload begins.
58 *
59 * `e.detail` is set to the
60 * [file](https://developer.mozilla.org/en-US/docs/Web/API/File)
61 * being uploaded.
62 *
63 * @event youtube-upload-start
64 * @param {Object} e Event parameters.
65 */
66
67 /**
68 * Fired while the upload is in progress.
69 *
70 * `e.detail.progressEvent` is set to the corresponding
71 * [XMLHttpRequestProgressEvent](http://www.w3.org/TR/progress-events/).
72 *
73 * `e.detail.estimatedSecondsRemaining` is set to an estimate of the time remaining
74 * in the upload, based on the average upload speed so far.
75 *
76 * `e.detail.bytesPerSecond` is set to the average number of bytes sent pe r second
77 * sent so far.
78 *
79 * `e.fractionComplete` is set to the fraction of the upload that's comple te, in the range [0, 1].
80 *
81 * @event youtube-upload-progress
82 * @param {Object} e Event parameters.
83 */
84
85 /**
86 * Fired when YouTube upload has failed.
87 *
88 * Since the actual upload failed, it's not possible for the YouTube serve r to attempt to
89 * process the video, and no `youtube-processing-poll` events will be fire d.
90 *
91 * `e.detail` is set to a string explaining what went wrong.
92 *
93 * @event youtube-upload-fail
94 * @param {Object} e Event parameters
95 */
96
97 /**
98 * Fired when video upload has completed, and YouTube has begun processing the video.
99 *
100 * At this point, the video is not yet playable, and there is no guarantee that
101 * the server-side YouTube processing will succeed.
102 *
103 * One or more `youtube-processing-poll` events will then be fired after t his event,
104 * followed by either a `youtube-processing-complete` or `youtube-processi ng-fail`.
105 *
106 * `e.detail` is set to the YouTube video id of the video.
107 *
108 * @event youtube-upload-complete
109 * @param {Object} e Event parameters.
110 */
111
112 /**
113 * Fired while server-side processing is in progress.
114 *
115 * Server-side processing can take an
116 * [unpredictable amount of time](https://support.google.com/youtube/answe r/71674?hl=en&ref_topic=2888603),
117 * and these events will be periodically fired each time the processing st atus is polled.
118 *
119 * `e.detail` is set to a
120 * [status](https://developers.google.com/youtube/v3/docs/videos#status)
121 * object.
122 *
123 * @event youtube-processing-poll
124 * @param {Object} e Event parameters
125 */
126
127 /**
128 * Fired when server-side processing is successful and the video is
129 * available for playback on YouTube.
130 *
131 * The video can be played at `https://youtu.be/VIDEO_ID` and can be
132 * embedded using the
133 * [`google-youtube`](https://github.com/GoogleWebComponents/google-youtub e) element.
134 *
135 * `e.detail` is set to the YouTube video id of the video.
136 *
137 * @event youtube-processing-complete
138 * @param {Object} e Event parameters
139 */
140
141 /**
142 * Fired when the video
143 * [failed transcoding](https://support.google.com/youtube/topic/2888603?h l=en&ref_topic=16547)
144 * and can't be played on YouTube.
145 *
146 * `e.detail` is set to a
147 * [status](https://developers.google.com/youtube/v3/docs/videos#status)
148 * object which has more details about the failure.
149 *
150 * @event youtube-processing-fail
151 * @param {Object} e Event parameters
152 */
153 properties: {
154 /**
155 * An OAuth 2 clientId reference, obtained from the
156 * [Google Developers Console](https://console.developers.google.com).
157 *
158 * Follow
159 * [the steps](https://developers.google.com/console/help/new/#generatin goauth2)
160 * for registering for OAuth 2, ensure that the
161 * [YouTube Data API v3](https://developers.google.com/youtube/registeri ng_an_application)
162 * is enabled for your API project, and ensure that the JavaScript Origi n
163 * is set to the domain hosting the page on which
164 * you'll be using this element.
165 *
166 * @attribute clientId
167 * @type string
168 * @default ''
169 */
170 clientId: {
171 type: String,
172 value: ''
173 },
174
175 /**
176 * Whether files should be automatically uploaded.
177 *
178 * @attribute auto
179 * @type boolean
180 * @default false
181 */
182 auto: {
183 type: Boolean,
184 value: false
185 },
186
187 /**
188 * Whether the user has authenticated or not.
189 *
190 * @attribute authenticated
191 * @type boolean
192 */
193 authenticated: {
194 type: Boolean,
195 value: false,
196 readOnly: true
197 },
198
199 /**
200 * The title for the new YouTube video.
201 *
202 * @attribute videoTitle
203 * @type string
204 * @default 'Untitled Video'
205 */
206 videoTitle: {
207 type: String,
208 value: 'Untitled Video'
209 },
210
211 /**
212 * The description for the new YouTube video.
213 *
214 * @attribute description
215 * @type string
216 * @default 'Uploaded via a web component! Check out https://github.com/ GoogleWebComponents/google-youtube-upload'
217 */
218 description: {
219 type: String,
220 value: 'Uploaded via a web component! Check out https://github.com/Goo gleWebComponents/google-youtube-upload'
221 },
222
223 /**
224 * The array of tags for the new YouTube video.
225 *
226 * @attribute tags
227 * @type Array.<string>
228 * @default ['google-youtube-upload']
229 */
230 tags: {
231 type: Array,
232 value: function() { return ['google-youtube-upload']}
233 },
234
235 /**
236 * The numeric YouTube
237 * [cateogry id](https://developers.google.com/apis-explorer/#p/youtube/ v3/youtube.videoCategories.list?part=snippet&regionCode=us).
238 *
239 * @attribute categoryId
240 * @type number
241 * @default 22
242 */
243 categoryId: {
244 type: Number,
245 value: 22
246 },
247
248 /**
249 * The [privacy setting](https://support.google.com/youtube/answer/15717 7?hl=en)
250 * for the new video.
251 *
252 * Valid values are 'public', 'private', and 'unlisted'.
253 *
254 * @attribute privacyStatus
255 * @type string
256 * @default 'public'
257 */
258 privacyStatus: {
259 type: String,
260 value: 'public'
261 },
262
263 /**
264 * The id of the new video.
265 *
266 * This is set as soon as a `youtube-upload-complete` event is fired.
267 *
268 * @attribute videoId
269 * @type string
270 * @default ''
271 */
272 videoId: {
273 type: String,
274 value: '',
275 readOnly: true,
276 notify: true
277 },
278
279 _channel: {
280 type: Object,
281 value: function() { return {
282 name: 'Not Logged In',
283 thumbnail: ''
284 };}
285 },
286 _selectedFile: {
287 type: Object,
288 value: null
289 }
290 },
291
292 _uploadStartTime: 0,
293
294 ready: function() {
295 document.addEventListener('google-signin-success', function(e) {
296
297 this.accessToken = gapi.auth2.getAuthInstance().currentUser.get().getA uthResponse().access_token;
298 this._setAuthenticated(true);
299 this._loadChannels();
300 }.bind(this));
301
302 document.addEventListener('google-signed-out', function(e) {
303 this._setAuthenticated(false);
304 this._loadChannelRequested = false;
305 this.set('_channel.name', 'Not Logged In');
306 this.set('_channel.thumbnail', '');
307 }.bind(this));
308 },
309
310 _clientLoaded: function() {
311 this._loadChannels();
312 },
313
314 _loadChannels: function() {
315 if (gapi && gapi.client && this.authenticated && !this._loadChannelReque sted) {
316 this._loadChannelRequested = true;
317 gapi.client.request({
318 path: '/youtube/v3/channels',
319 params: {
320 part: 'snippet',
321 mine: true
322 },
323 callback: function(response) {
324 if (response.error) {
325 this.fire('youtube-upload-fail', response.error.message);
326 } else {
327 this.set('_channel.name', response.items[0].snippet.title);
328 this.set('_channel.thumbnail', response.items[0].snippet.thumbna ils.default.url);
329 }
330 }.bind(this)
331 });
332 }
333 },
334 _computeChannelImageStyle: function(thumbnail) {
335 return 'display:' + (thumbnail ? 'inline' : 'none');
336 },
337
338 _computeUploadDivStyle: function(authenticated) {
339 return 'display:' + (authenticated ? 'block' : 'none');
340 },
341 _computeUploadButtonStyle: function(auto) {
342 return 'display:' + (auto ? 'none' : 'block');
343 },
344 /**
345 * Uploads a video file to YouTube.
346 *
347 * `this.accessToken` must already be set to a valid OAuth 2 access token.
348 *
349 * @method uploadFile
350 * @param {object} file File object corresponding to the video to upload.
351 */
352 uploadFile: function(file) {
353 var metadata = {
354 snippet: {
355 title: this.videoTitle,
356 description: this.description,
357 tags: this.tags,
358 categoryId: this.categoryId
359 },
360 status: {
361 privacyStatus: this.privacyStatus
362 }
363 };
364
365 var uploader = new MediaUploader({
366 baseUrl: 'https://www.googleapis.com/upload/youtube/v3/videos',
367 file: file,
368 token: this.accessToken,
369 metadata: metadata,
370 params: {
371 part: Object.keys(metadata).join(',')
372 },
373 onError: function(data) {
374 var message = data;
375
376 // Assuming the error is raised by the YouTube API, data will be
377 // a JSON string with error.message set. I am not 100% sure that's t he
378 // only time onError will be raised, though.
379 try {
380 var errorResponse = JSON.parse(data);
381 message = errorResponse.error.message;
382 } finally {
383 this.fire('youtube-upload-fail', message);
384 }
385 }.bind(this),
386 onProgress: function(data) {
387 var currentTime = Date.now();
388 var bytesUploaded = data.loaded;
389 var totalBytes = data.total;
390
391 // The times are in millis, so we need to divide by 1000 to get seco nds.
392 var bytesPerSecond = bytesUploaded / ((currentTime - this._uploadSta rtTime) / 1000);
393 var estimatedSecondsRemaining = (totalBytes - bytesUploaded) / bytes PerSecond;
394 var fractionComplete = bytesUploaded / totalBytes;
395
396 this.fire('youtube-upload-progress', {
397 progressEvent: data,
398 bytesPerSecond: bytesPerSecond,
399 estimatedSecondsRemaining: estimatedSecondsRemaining,
400 fractionComplete: fractionComplete
401 });
402 }.bind(this),
403 onComplete: function(data) {
404 var uploadResponse = JSON.parse(data);
405 this.fire('youtube-upload-complete', uploadResponse.id);
406 this._setVideoId(uploadResponse.id);
407
408 this._pollForVideoStatus();
409 }.bind(this)
410 });
411
412 this.fire('youtube-upload-start', file);
413 // This won't correspond to the *exact* start of the upload, but it shou ld be close enough.
414 this._uploadStartTime = Date.now();
415 uploader.upload();
416 },
417
418 _handleFileChanged: function() {
419 this._selectedFile = this.$.file.files[0];
420
421 if (this.auto) {
422 this.uploadFile(this._selectedFile);
423 }
424 },
425
426 _handleUploadClicked: function() {
427 this.uploadFile(this._selectedFile);
428 },
429
430 _pollForVideoStatus: function() {
431 gapi.client.request({
432 path: '/youtube/v3/videos',
433 params: {
434 part: 'status',
435 id: this.videoId
436 },
437 callback: function(response) {
438 if (response.error) {
439 // Not exactly sure how to handle this one, since it means the sta tus polling failed.
440 setTimeout(this._pollForVideoStatus.bind(this), STATUS_POLLING_ITE RVAL_MILLIS);
441 } else {
442 var status = response.items[0].status;
443
444 switch (status.uploadStatus) {
445 // This is a non-final status, so we need to poll again.
446 case 'uploaded':
447 this.fire('youtube-processing-poll', status);
448 setTimeout(this._pollForVideoStatus.bind(this), STATUS_POLLING _ITERVAL_MILLIS);
449 break;
450
451 // The video was successfully transcoded and is available.
452 case 'processed':
453 this.fire('youtube-processing-complete', this.videoId);
454 break;
455
456 // All other statuses indicate a permanent transcoding failure.
457 default:
458 this.fire('youtube-processing-fail', status);
459 break;
460 }
461 }
462 }.bind(this)
463 });
464 }
465 });
466 })();
467 </script>
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698