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

Side by Side Diff: polymer_1.0.4/bower_components/google-youtube/google-youtube.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 <!--
2 Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
3 This code may only be used under the BSD style license found at https://polymer. github.io/LICENSE.txt
4 The complete set of authors may be found at https://polymer.github.io/AUTHORS.tx t
5 The complete set of contributors may be found at https://polymer.github.io/CONTR IBUTORS.txt
6 Code distributed by Google as part of the polymer project is also
7 subject to an additional IP rights grant found at https://polymer.github.io/PATE NTS.txt
8 -->
9
10 <link rel="import" href="../polymer/polymer.html">
11 <link rel="import" href="../iron-localstorage/iron-localstorage.html">
12 <link rel="import" href="../google-apis/google-youtube-api.html">
13
14 <!--
15 `google-youtube` encapsulates the YouTube player into a web component.
16
17 <google-youtube
18 video-id="..."
19 height="270px"
20 width="480px"
21 rel="0"
22 start="5"
23 autoplay="1">
24 </google-youtube>
25
26 `google-youtube` supports all of the [embedded player parameters](https://develo pers.google.com/youtube/player_parameters). Each can be set as an attribute on ` google-youtube`.
27
28 The standard set of [YouTube player events](https://developers.google.com/youtub e/iframe_api_reference#Events) are exposed, as well as methods for playing, paus ing, seeking to a specific time, and loading a new video.
29
30 @demo
31 -->
32 <dom-module id="google-youtube">
33 <template>
34 <style>
35 :host {
36 display: block;
37 }
38
39 :host([fluid]) {
40 width: 100%;
41 max-width: 100%;
42 position: relative;
43 }
44
45 :host([fluid]) iframe,
46 :host([fluid]) #thumbnail {
47 vertical-align: bottom;
48 position: absolute;
49 top: 0px;
50 left: 0px;
51 width: 100%;
52 height: 100%;
53 }
54
55 #container {
56 max-width: 100%;
57 max-height: 100%;
58 }
59
60 #thumbnail {
61 width: 100%;
62 height: 100%;
63 cursor: pointer;
64 }
65
66 /* Some browsers will refuse to play videos with 'display: none' set, so p osition the video well offscreen instead. */
67 #playtest {
68 position: absolute;
69 top: -9999px;
70 left: -9999px;
71 }
72 </style>
73
74 <div id="container" style$="{{_computeContainerStyle(width, height)}}">
75 <template is="dom-if" if="{{thumbnail}}">
76 <img id="thumbnail"
77 src$="{{thumbnail}}"
78 title="YouTube video thumbnail."
79 alt="YouTube video thumbnail."
80 on-tap="_handleThumbnailTap">
81 </template>
82
83 <template is="dom-if" if="{{!thumbnail}}">
84 <google-youtube-api on-api-load="_apiLoad"></google-youtube-api>
85 </template>
86
87 <!-- Use this._playsupportedLocalStorage as the value, since this.playsupp orted is set to
88 true as soon as initial playback has started, and we don't want that cached. -->
89 <iron-localstorage name="google-youtube-playsupported"
90 value="_playsupportedLocalStorage"
91 on-iron-localstorage-load="_determinePlaySupported">
92 </iron-localstorage>
93
94 <div id="player"></div>
95 </div>
96 </template>
97 </dom-module>
98
99 <script>
100 Polymer({
101 is: 'google-youtube',
102 /**
103 * Fired when the YouTube player is fully initialized and ready for use.
104 *
105 * @event google-youtube-ready
106 */
107
108 /**
109 * Fired when the state of the player changes. `e.detail.data` is set to one of
110 * [the documented](https://developers.google.com/youtube/iframe_api_referen ce#onStateChange)
111 * states.
112 *
113 * @event google-youtube-state-change
114 * @param {Object} e Event parameters.
115 */
116
117 /**
118 * Fired when playback fails due to an error. `e.detail.data` is set to one of
119 * [the documented](https://developers.google.com/youtube/iframe_api_referen ce#onError)
120 * error codes.
121 *
122 * @event google-youtube-error
123 * @param {Object} e Event parameters.
124 */
125
126 properties: {
127 /**
128 * Sets the id of the video to play. Changing this attribute will trigger a call
129 * to load a new video into the player (if `this.autoplay` is set to `1` and `playsupported` is true)
130 * or cue a new video otherwise.
131 *
132 * You can [search for videos programmatically](https://developers.google.co m/youtube/v3/docs/search/list)
133 * using the YouTube Data API, or just hardcode known video ids to display o n your page.
134 */
135 videoId: {
136 type: String,
137 value: 'mN7IAaRdi_k',
138 observer: '_videoIdChanged'
139 },
140
141 /**
142 * Whether programmatic `<video>.play()` for initial playback is supported in the current browser.
143 *
144 * Most mobile browsers [do not support](https://developer.apple.com/libra ry/safari/documentation/AudioVideo/Conceptual/Using_HTML5_Audio_Video/Device-Spe cificConsiderations/Device-SpecificConsiderations.html#//apple_ref/doc/uid/TP400 09523-CH5-SW1) autoplaying or scripted playback of videos.
145 * If you attempt to automatically initiate playback of a `<google-youtube >`, e.g. by calling the `play()` method before
146 * playback has initially begun, the YouTube Player will enter an unrecove rable "stuck" state.
147 * To protect against this, check the value of `playsupported` and don't c all `play()` if it is set to `false`.
148 * (You can hide/disable your custom play button, etc.)
149 *
150 * The `playsupported` value is determined at runtime, by dynamically crea ting a `<video>` element with an
151 * inlined data source and calling `play()` on it. (Inspired by [Modernizr ](https://github.com/Modernizr/Modernizr/blob/master/feature-detects/video/autop lay.js).)
152 *
153 * If you would rather not incur the minimal overhead involved in going th rough this process, you can explicitly set
154 * `playsupported` to `true` or `false` when initializing `<google-youtube >`. This is only recommended if you know that
155 * your web app will never (or only) be used on mobile browsers.
156 */
157 playsupported: {
158 type: Boolean,
159 value: null,
160 notify: true
161 },
162
163 /**
164 * "1" if video should start automatically
165 */
166 autoplay: {
167 type: Number,
168 value: 0
169 },
170 /**
171 * Whether playback has started.
172 *
173 * This defaults to `false` and is set to `true` once the first 'playing' event is fired by
174 * the underlying YouTube Player API.
175 *
176 * Once set to `true`, it will remain that way indefinitely.
177 * Paused/buffering/ended events won't cause `playbackstarted` to reset to `false`.
178 * Nor will loading a new video into the player.
179 */
180 playbackstarted: {
181 type: Boolean,
182 value: false,
183 notify: true
184 },
185
186 /**
187 * Sets the height of the player on the page.
188 * Accepts anything valid for a CSS measurement, e.g. '200px' or '50%'.
189 * If the unit of measurement is left off, 'px' is assumed.
190 */
191 height: {
192 type: String,
193 value: '270px'
194 },
195
196 /**
197 * Sets the width of the player on the page.
198 * Accepts anything valid for a CSS measurement, e.g. '200px' or '50%'.
199 * If the unit of measurement is left off, 'px' is assumed.
200 */
201 width: {
202 type: String,
203 value:'480px'
204 },
205
206 /**
207 * Exposes the current player state.
208 * Using this attribute is an alternative to listening to `google-youtube- state-change` events,
209 * and can simplify the logic in templates with conditional binding.
210 *
211 * The [possible values](https://developers.google.com/youtube/iframe_api_ reference#onStateChange):
212 * - -1 (unstarted)
213 * - 0 (ended)
214 * - 1 (playing)
215 * - 2 (paused)
216 * - 3 (buffering)
217 * - 5 (video cued)
218 */
219 state: {
220 type: Number,
221 value: -1,
222 notify: true
223 },
224
225 /**
226 * Exposes the current playback time, in seconds.
227 *
228 * You can divide this value by the `duration` to determine the playback p ercentage.
229 */
230 currenttime: {
231 type: Number,
232 value: 0,
233 notify: true
234 },
235
236 /**
237 * Exposes the video duration, in seconds.
238 *
239 * You can divide the `currenttime` to determine the playback percentage.
240 *
241 * @attribute duration
242 * @type number
243 */
244 duration: {
245 type: Number,
246 value: 1, // To avoid divide-by-zero errors if used before video is cued .
247 notify: true
248 },
249
250 /**
251 * Exposes the current playback time, formatted as a (HH:)MM:SS string.
252 */
253 currenttimeformatted: {
254 type: String,
255 value: '0:00',
256 notify: true
257 },
258
259 /**
260 * Exposes the video duration, formatted as a (HH:)MM:SS string.
261 */
262 durationformatted: {
263 type: String,
264 value: '0:00', // To avoid divide-by-zero errors if used before video is cued.
265 notify: true
266 },
267
268 /**
269 * The fraction of the bytes that have been loaded for the current video, in the range [0-1].
270 */
271 fractionloaded: {
272 type: Number,
273 value: 0,
274 notify: true
275 },
276
277 /**
278 * A shorthand to enable a set of player attributes that, used together, s imulate a "chromeless" YouTube player.
279 *
280 * Equivalent to setting the following attributes:
281 * - `controls="0"`
282 * - `modestbranding="1"`
283 * - `showinfo="0"`
284 * - `iv_load_policy="3"`
285 * - `rel="0"`
286 *
287 * The "chromeless" player has minimal YouTube branding in cued state, and the native controls
288 * will be disabled during playback. Creating your own custom play/pause/e tc. controls is recommended.
289 */
290 chromeless: {
291 type: Boolean,
292 value: false
293 },
294 /**
295 * The URL of an image to use as a custom thumbnail.
296 *
297 * This is optional; if not provided, the standard YouTube embed (which us es the thumbnail associated
298 * with the video on YouTube) will be used.
299 *
300 * If `thumbnail` is set, than an `<img>` containing the thumbnail will be used in lieu of the actual
301 * YouTube embed. When the thumbnail is clicked, the `<img>` is swapped ou t for the actual YouTube embed,
302 * which will have [`autoplay=1`](https://developers.google.com/youtube/pl ayer_parameters#autoplay) set by default (in additional to any other player para meters specified on this element).
303 *
304 * Please note that `autoplay=1` won't actually autoplay videos on mobile browsers, so two taps will be required
305 * to play the video there. Also, on desktop browsers, setting `autoplay=1 ` will prevent the playback
306 * from [incrementing the view count](https://support.google.com/youtube/a nswer/1714329) for the video.
307 */
308 thumbnail: {
309 type: String,
310 value: ''
311 },
312
313 /**
314 * If `fluid` is set, then the player will set its width to 100% to fill
315 * the parent container, while adding `padding-top` to preserve the
316 * aspect ratio provided by `width` and `height`. If `width` and `height`
317 * have not been set, the player will fall back to a 16:9 aspect ratio.
318 * This is useful for responsive designs where you don't want to
319 * introduce letterboxing on your video.
320 */
321 fluid: {
322 type: Boolean,
323 value: false
324 }
325
326 },
327
328 _computeContainerStyle: function(width, height) {
329 return 'width:' + width + '; height:' + height;
330 },
331 /**
332 * Detects whether programmatic <video>.play() is supported in the current b rowser.
333 *
334 * This is triggered via on-ironlocalstorage-load. The logic is:
335 * - If playsupported is explicitly set to true or false on the element, use that.
336 * - Otherwise, if there's a cached value in localStorage, use that.
337 * - Otherwise, create a hidden <video> element and call play() on it:
338 * - If playback starts, playsupported is true.
339 * - If playback doesn't start (within 500ms), playsupported is false.
340 * - Whatever happens, cache the result in localStorage.
341 */
342 _determinePlaySupported: function() {
343 // If playsupported isn't already being overridden by the page using this component, then attempt
344 // to determine if it's supported.
345 // This is deliberately checking with ==, to match either undefined or nul l.
346 if (this.playsupported == null) {
347 // If we don't have the results of a previous test cached in localStorag e, then run a new playback test.
348 if (this._playsupportedLocalStorage == null) {
349 var timeout;
350 var videoElement = document.createElement('video');
351
352 if ('play' in videoElement) {
353 videoElement.id = 'playtest';
354
355 var mp4Source = document.createElement('source');
356 mp4Source.src = "data:video/mp4;base64,AAAAFGZ0eXBNU05WAAACAE1TTlYAA AOUbW9vdgAAAGxtdmhkAAAAAM9ghv7PYIb+AAACWAAACu8AAQAAAQAAAAAAAAAAAAAAAAEAAAAAAAAAA AAAAAAAAAABAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAnh0c mFrAAAAXHRraGQAAAAHz2CG/s9ghv4AAAABAAAAAAAACu8AAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAA AAAAAAAAAABAAAAAAAAAAAAAAAAAABAAAAAAFAAAAA4AAAAAAHgbWRpYQAAACBtZGhkAAAAAM9ghv7PY Ib+AAALuAAANq8AAAAAAAAAIWhkbHIAAAAAbWhscnZpZGVBVlMgAAAAAAABAB4AAAABl21pbmYAAAAUd m1oZAAAAAAAAAAAAAAAAAAAACRkaW5mAAAAHGRyZWYAAAAAAAAAAQAAAAx1cmwgAAAAAQAAAVdzdGJsA AAAp3N0c2QAAAAAAAAAAQAAAJdhdmMxAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAFAAOABIAAAASAAAA AAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGP//AAAAEmNvbHJuY2xjAAEAAQABA AAAL2F2Y0MBTUAz/+EAGGdNQDOadCk/LgIgAAADACAAAAMA0eMGVAEABGjuPIAAAAAYc3R0cwAAAAAAA AABAAAADgAAA+gAAAAUc3RzcwAAAAAAAAABAAAAAQAAABxzdHNjAAAAAAAAAAEAAAABAAAADgAAAAEAA ABMc3RzegAAAAAAAAAAAAAADgAAAE8AAAAOAAAADQAAAA0AAAANAAAADQAAAA0AAAANAAAADQAAAA0AA AANAAAADQAAAA4AAAAOAAAAFHN0Y28AAAAAAAAAAQAAA7AAAAA0dXVpZFVTTVQh0k/Ou4hpXPrJx0AAA AAcTVREVAABABIAAAAKVcQAAAAAAAEAAAAAAAAAqHV1aWRVU01UIdJPzruIaVz6ycdAAAAAkE1URFQAB AAMAAAAC1XEAAACHAAeAAAABBXHAAEAQQBWAFMAIABNAGUAZABpAGEAAAAqAAAAASoOAAEAZABlAHQAZ QBjAHQAXwBhAHUAdABvAHAAbABhAHkAAAAyAAAAA1XEAAEAMgAwADAANQBtAGUALwAwADcALwAwADYAM AA2ACAAMwA6ADUAOgAwAAABA21kYXQAAAAYZ01AM5p0KT8uAiAAAAMAIAAAAwDR4wZUAAAABGjuPIAAA AAnZYiAIAAR//eBLT+oL1eA2Nlb/edvwWZflzEVLlhlXtJvSAEGRA3ZAAAACkGaAQCyJ/8AFBAAAAAJQ ZoCATP/AOmBAAAACUGaAwGz/wDpgAAAAAlBmgQCM/8A6YEAAAAJQZoFArP/AOmBAAAACUGaBgMz/wDpg QAAAAlBmgcDs/8A6YEAAAAJQZoIBDP/AOmAAAAACUGaCQSz/wDpgAAAAAlBmgoFM/8A6YEAAAAJQZoLB bP/AOmAAAAACkGaDAYyJ/8AFBAAAAAKQZoNBrIv/4cMeQ==";
357 videoElement.appendChild(mp4Source);
358
359 var webmSource = document.createElement('source');
360 webmSource.src = "data:video/webm;base64,GkXfo49CgoR3ZWJtQoeBAUKFgQE YU4BnAQAAAAAAF60RTZt0vE27jFOrhBVJqWZTrIIQA027jFOrhBZUrmtTrIIQbE27jFOrhBFNm3RTrII XmU27jFOrhBxTu2tTrIIWs+xPvwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFUmpZuQq17GDD0JATYCjbGliZWJtbCB2MC43Ljc gKyBsaWJtYXRyb3NrYSB2MC44LjFXQY9BVlNNYXRyb3NrYUZpbGVEiYRFnEAARGGIBc2Lz1QNtgBzpJC y3XZ0KNuKNZS4+fDpFxzUFlSua9iu1teBAXPFhL4G+bmDgQG5gQGIgQFVqoEAnIEAbeeBASMxT4Q/gAA AVe6BAIaFVl9WUDiqgQEj44OEE95DVSK1nIN1bmTgkbCBULqBPJqBAFSwgVBUuoE87EQAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB9DtnV B4eeBAKC4obaBAAAAkAMAnQEqUAA8AABHCIWFiIWEiAICAAamYnoOC6cfJa8f5Zvda4D+/7YOf//nNef QYACgnKGWgQFNANEBAAEQEAAYABhYL/QACIhgAPuC/rOgnKGWgQKbANEBAAEQEAAYABhYL/QACIhgAPu C/rKgnKGWgQPoANEBAAEQEAAYABhYL/QACIhgAPuC/rOgnKGWgQU1ANEBAAEQEAAYABhYL/QACIhgAPu C/rOgnKGWgQaDANEBAAEQEAAYABhYL/QACIhgAPuC/rKgnKGWgQfQANEBAAEQEAAYABhYL/QACIhgAPu C/rOgnKGWgQkdANEBAAEQEBRgAGFgv9AAIiGAAPuC/rOgnKGWgQprANEBAAEQEAAYABhYL/QACIhgAPu C/rKgnKGWgQu4ANEBAAEQEAAYABhYL/QACIhgAPuC/rOgnKGWgQ0FANEBAAEQEAAYABhYL/QACIhgAPu C/rOgnKGWgQ5TANEBAAEQEAAYABhYL/QACIhgAPuC/rKgnKGWgQ+gANEBAAEQEAAYABhYL/QACIhgAPu C/rOgnKGWgRDtANEBAAEQEAAYABhYL/QACIhgAPuC/rOgnKGWgRI7ANEBAAEQEAAYABhYL/QACIhgAPu C/rIcU7trQOC7jLOBALeH94EB8YIUzLuNs4IBTbeH94EB8YIUzLuNs4ICm7eH94EB8YIUzLuNs4ID6Le H94EB8YIUzLuNs4IFNbeH94EB8YIUzLuNs4IGg7eH94EB8YIUzLuNs4IH0LeH94EB8YIUzLuNs4IJHbe H94EB8YIUzLuNs4IKa7eH94EB8YIUzLuNs4ILuLeH94EB8YIUzLuNs4INBbeH94EB8YIUzLuNs4IOU7e H94EB8YIUzLuNs4IPoLeH94EB8YIUzLuNs4IQ7beH94EB8YIUzLuNs4ISO7eH94EB8YIUzBFNm3SPTbu MU6uEH0O2dVOsghTM";
361 videoElement.appendChild(webmSource);
362
363 document.body.appendChild(videoElement);
364
365 this.async(function() {
366 // Ideally, we'll get a 'playing' event if we're on a browser that supports programmatic play().
367 videoElement.onplaying = function(e) {
368 clearTimeout(timeout);
369
370 this.playsupported = (e && e.type === 'playing') || videoElement .currentTime !== 0;
371 this._playsupportedLocalStorage = this.playsupported;
372
373 videoElement.onplaying = null;
374
375 document.body.removeChild(videoElement);
376 }.bind(this);
377
378 // If we haven't received a 'playing' event within 500ms, then we' re most likely on a browser that doesn't
379 // support programmatic plays. Do a final check after 500ms and se t this.playsupported at that point.
380 timeout = setTimeout(videoElement.onplaying, 500);
381
382 // Try to initiate playback...
383 videoElement.play();
384 });
385 } else {
386 // If there's no play() method then we know that it's no supported.
387 this.playsupported = false;
388 this._playsupportedLocalStorage = false;
389 }
390 } else {
391 // If we do have the results of a previous test cached, then just use that.
392 // A browser's support for <video>.play() isn't likely to change.
393 this.playsupported = this._playsupportedLocalStorage;
394 }
395 }
396 },
397
398 /**
399 * Sets fluid width/height.
400 *
401 * If the fluid attribute is set, the aspect ratio of the video will
402 * be inferred (if set in pixels), or assumed to be 16:9. The element
403 * will give itself enough top padding to force the player to use the
404 * correct aspect ratio, even as the screen size changes.
405 *
406 */
407 ready: function() {
408 if (this.hasAttribute('fluid')) {
409 var ratio = parseInt(this.height, 10) / parseInt(this.width, 10);
410 if (isNaN(ratio)) {
411 ratio = 9/16;
412 }
413 ratio *= 100;
414 this.width = '100%';
415 this.height = 'auto';
416 this.style['padding-top'] = ratio + '%';
417 }
418 },
419
420 /**
421 * Clean up the underlying Player `<iframe>` when we're removed from the DOM .
422 */
423 detached: function() {
424 if (this._player) {
425 this._player.destroy();
426 }
427 },
428
429 /**
430 * Plays the current video.
431 *
432 * Note that on certain mobile browsers, playback
433 * [can't be initiated programmatically](https://developers.google.com/youtu be/iframe_api_reference#Mobile_considerations).
434 *
435 * If `this.playsupported` is not `true`, calling `play()` will have no effe ct.
436 *
437 * @method play
438 */
439 play: function() {
440 if (this._player && this._player.playVideo && this.playsupported) {
441 this._player.playVideo();
442 }
443 },
444
445 /**
446 * Modifies the volume of the current video.
447 *
448 * Developers should take care not to break expected user experience by prog rammatically
449 * modifying the volume on mobile browsers.
450 * Note that the YouTube player, in addition, does not display volume contro ls in a
451 * mobile environment.
452 *
453 * @method setVolume
454 * @param {number} volume The new volume, an integer between 0 (muted) and 1 00 (loudest).
455 */
456 setVolume: function(volume) {
457 if (this._player && this._player.setVolume) {
458 this._player.setVolume(volume);
459 }
460 },
461
462 /**
463 * Mutes the current video.
464 *
465 * Developers should take care not to break expected user experience by prog rammatically
466 * modifying the volume on mobile browsers.
467 * Note that the YouTube player, in addition, does not display volume contro ls in a
468 * mobile environment.
469 *
470 * @method mute
471 */
472 mute: function() {
473 if (this._player && this._player.mute) {
474 this._player.mute();
475 }
476 },
477
478 /**
479 * Unmutes the current video.
480 *
481 * Developers should take care not to break expected user experience by prog rammatically
482 * modifying the volume on mobile browsers.
483 * Note that the YouTube player, in addition, does not display volume contro ls in a
484 * mobile environment.
485 *
486 * @method unMute
487 */
488 unMute: function() {
489 if (this._player && this._player.unMute) {
490 this._player.unMute();
491 }
492 },
493
494 /**
495 * Pauses the current video.
496 *
497 * @method pause
498 */
499 pause: function() {
500 if (this._player && this._player.pauseVideo) {
501 this._player.pauseVideo();
502 }
503 },
504
505 /**
506 * Skips ahead (or back) to the specified number of seconds.
507 *
508 * @method seekTo
509 * @param {number} seconds Number of seconds to seek to.
510 */
511 seekTo: function(seconds) {
512 if (this._player && this._player.seekTo) {
513 this._player.seekTo(seconds, true);
514
515 // Explicitly call _updatePlaybackStats() to ensure that the new playbac k info is
516 // reflected in the bound attributes.
517 // The 100ms delay is somewhat arbitrary, but the YouTube player does ne ed time to
518 // update its internal state following the call to player.seekTo().
519 this.async(function() {
520 this._updatePlaybackStats();
521 }, null, 100);
522 }
523 },
524
525 _videoIdChanged: function() {
526 this.currenttime = 0;
527 this.currenttimeformatted = this._toHHMMSS(0);
528 this.fractionloaded = 0;
529 this.duration = 1;
530 this.durationformatted = this._toHHMMSS(0);
531
532 if (!this._player || !this._player.cueVideoById) {
533 this._pendingVideoId = this.videoId;
534 } else {
535 // Figure out whether we should cue or load (which will autoplay) the ne xt video.
536 if (this.playsupported && this.attributes['autoplay'] && this.attributes ['autoplay'].value == '1') {
537 this._player.loadVideoById(this.videoId);
538 } else {
539 this._player.cueVideoById(this.videoId);
540 }
541 }
542 },
543
544 _player: null,
545 __updatePlaybackStatsInterval: null,
546 _pendingVideoId: '',
547
548 _apiLoad: function() {
549 // Establish some defaults. Attributes set on the google-youtube element
550 // can override defaults, or specify additional player parameters. See
551 // https://developers.google.com/youtube/player_parameters
552 var playerVars = {
553 playsinline: 1,
554 controls: 2,
555 autohide: 1,
556 // This will (intentionally) be overwritten if this.attributes['autoplay '] is set.
557 autoplay: this.autoplay
558 };
559
560 if (this.chromeless) {
561 playerVars.controls = 0;
562 playerVars.modestbranding = 1;
563 playerVars.showinfo = 0;
564 // Disable annotations.
565 playerVars.iv_load_policy = 3;
566 // Disable related videos on the end screen.
567 playerVars.rel = 0;
568 }
569
570 for (var i = 0; i < this.attributes.length; i++) {
571 var attribute = this.attributes[i];
572 playerVars[attribute.nodeName] = attribute.value;
573 }
574
575 this._player = new YT.Player(this.$.player, {
576 videoId: this.videoId,
577 width: '100%',
578 height: '100%',
579 playerVars: playerVars,
580 events: {
581 onReady: function(e) {
582 if (this._pendingVideoId && this._pendingVideoId != this.videoId) {
583 this._player.cueVideoById(this._pendingVideoId);
584 this._pendingVideoId = '';
585 }
586
587 this.fire('google-youtube-ready', e);
588 }.bind(this),
589 onStateChange: function(e) {
590 this.state = e.data;
591
592 // The YouTube Player API only exposes playback data about a video o nce
593 // playback has begun.
594 if (this.state == 1) {
595 this.playbackstarted = true;
596
597 // After playback has begun, play() can always be used to resume p layback if the video is paused.
598 this.playsupported = true;
599
600 this.duration = this._player.getDuration();
601 this.durationformatted = this._toHHMMSS(this.duration);
602
603 if (!this.__updatePlaybackStatsInterval) {
604 this.__updatePlaybackStatsInterval = setInterval(this._updatePla ybackStats.bind(this), 1000);
605 }
606 } else {
607 // We only need to update the stats if the video is playing.
608 if (this.__updatePlaybackStatsInterval) {
609 clearInterval(this.__updatePlaybackStatsInterval);
610 this.__updatePlaybackStatsInterval = null;
611 }
612 }
613
614 this.fire('google-youtube-state-change', e);
615 }.bind(this),
616 onError: function(e) {
617 // Set the player state to 0 ('ended'), since playback will have sto pped.
618 this.state = 0;
619
620 this.fire('google-youtube-error', e);
621 }.bind(this)
622 }
623 });
624 },
625
626 _updatePlaybackStats: function() {
627 this.currenttime = Math.round(this._player.getCurrentTime());
628 this.currenttimeformatted = this._toHHMMSS(this.currenttime);
629 this.fractionloaded = this._player.getVideoLoadedFraction();
630 },
631
632 _toHHMMSS: function(totalSeconds) {
633 var hours = Math.floor(totalSeconds / 3600);
634 totalSeconds -= hours * 3600;
635 var minutes = Math.floor(totalSeconds / 60);
636 var seconds = Math.round(totalSeconds - (minutes * 60));
637
638 var hourPortion = '';
639 if (hours > 0) {
640 hourPortion += hours + ':';
641
642 if (minutes < 10) {
643 minutes = '0' + minutes;
644 }
645 }
646
647 if (seconds < 10) {
648 seconds = '0' + seconds;
649 }
650
651 return hourPortion + minutes + ':' + seconds;
652 },
653
654 _handleThumbnailTap: function() {
655 this.autoplay = 1;
656 this.thumbnail = '';
657 }
658 });
659 </script>
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698