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

Side by Side Diff: polymer_1.0.4/bower_components/google-castable-video/google-castable-video.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, 5 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-cast-sender-api.html">
3
4 <!-- TODO(tschaeff):
5 - ratechange to change playbackspeed (if even possible)
6 -->
7 <script>
8 (function() {
9 // Set static variable for the timeupdate delay.
10 var _GOOGLE_CASTABLE_VIDEO_TIMEUPDATE_DELAY = 250;
11 /**
12 The `google-castable-video` element enables your HTML5 videos to be casted to an y Chromecast.
13
14 It behaves exactly like an HTML5 video element except for some added methods and events.
15
16 Instead of listening for the video element's `timeupdate` event please listen fo r the `google-castable-video-timeupdate` event. This event is fired if the video is playing locally and on the Chromecast device.
17
18 ##### Example
19
20 <video is="google-castable-video">
21 <source src="video.mp4" type="video/mp4">
22 </video>
23
24 @demo
25 */
26 Polymer({
27
28 is: 'google-castable-video',
29
30 extends: 'video',
31
32 properties: {
33 /**
34 * The appId that references which receiver the Chromecast will load.
35 *
36 * @default chrome.cast.media.DEFAULT_MEDIA_RECEIVER_APP_ID
37 */
38 appId: {
39 type: String,
40 value: null
41 }
42 },
43
44 listeners: {
45 'seeked': '_onSeeked',
46 'volumechange': '_onVolumechange',
47 'timeupdate': '_onTimeupdate'
48 },
49
50 /**
51 * The real paused state for local and cast playback.
52 *
53 * @property bothPaused
54 * @type bool
55 * @default true
56 */
57 _bothPaused: true,
58 get bothPaused() {
59 return this._bothPaused;
60 },
61
62 /**
63 * Sets or returns the current playback position (in seconds).
64 * Since the local video is paused when the video is playing on the Chrome cast device
65 * the objects currentTime property doesn't represent the actual currentTi me of the video
66 * playing on the Chromecast device. To always get the actual position ple ase use bothCurrentTime.
67 *
68 * @property bothCurrentTime
69 * @type number
70 * @default 0
71 */
72 get bothCurrentTime() {
73 if (this._casting && this._castMedia) {
74 return this._castMedia.getEstimatedTime();
75 } else {
76 return this.currentTime;
77 }
78 },
79
80 set bothCurrentTime(val) {
81 return this.currentTime = val;
82 },
83
84 /**
85 * The mode state depending on whether the video is playing locally or on the cast device.
86 *
87 * @property casting
88 * @type bool
89 * @default false
90 */
91 _casting: false,
92 get casting() {
93 return this._casting;
94 },
95
96 /**
97 * Returns if any Chromecast is available.
98 *
99 * @property receiverAvailable
100 * @type bool
101 * @default false
102 */
103 _receiverAvailable: false,
104 get receiverAvailable() {
105 return this._receiverAvailable;
106 },
107
108 /**
109 * The `chrome.cast.Media` object.
110 *
111 * @property castMedia
112 * @type chrome.cast.Media
113 * @default null
114 */
115 _castMedia: null,
116 get castMedia() {
117 return this._castMedia;
118 },
119
120 /**
121 * The `chrome.cast.Session` object.
122 *
123 * @property session
124 * @type chrome.cast.Session
125 * @default null
126 */
127 _session: null,
128 get session() {
129 return this._session;
130 },
131
132 ready: function() {
133 // Initialize the cast api.
134 window['__onGCastApiAvailable'] = function(loaded, errorInfo) {
135 if (loaded) {
136 this._initializeCastApi();
137 } else {
138 this._triggerError('INITIALIZE_ERROR');
139 }
140 }.bind(this);
141 },
142
143 // Called internally when the cast sender api has been loaded.
144 _initializeCastApi: function() {
145 if (this.appId === null || typeof this.appId === "undefined") {
146 this.appId = chrome.cast.media.DEFAULT_MEDIA_RECEIVER_APP_ID;
147 // TODO ... process for selecting styled media receiver
148 }
149 var sessionRequest = new chrome.cast.SessionRequest(this.appId);
150 var apiConfig = new chrome.cast.ApiConfig(sessionRequest,
151 function(e){
152 // The sessionListener.
153 this._triggerCasting(true);
154 this._session = e;
155 if (this._session.media.length) {
156 this._onMediaDiscovered.call(this, 'onRequestSessionSuccess', this ._session.media[0]);
157 }
158 // Bind the session update listener.
159 this._session.addUpdateListener(this._sessionUpdateListener.bind(thi s));
160 // Set interval for cast timeupdate.
161 this._timeupdateInterval = setInterval(function(){
162 if (this._castMedia && this._castMedia.playerState === 'PLAYING') {
163 this._triggerTimeupdate(this._castMedia.getEstimatedTime());
164 this._bothPaused = false;
165 } else {
166 this._bothPaused = true;
167 }
168 }.bind(this), _GOOGLE_CASTABLE_VIDEO_TIMEUPDATE_DELAY);
169 // Start playing on cast if playing locally.
170 if (!this.paused) {
171 this.play();
172 this.pause(false);
173 }
174 }.bind(this),
175 function(e){
176 // The receiverListener
177 if (e === chrome.cast.ReceiverAvailability.AVAILABLE) {
178 this._triggerAvailability(true);
179 } else {
180 this._triggerAvailability(false);
181 }
182 }.bind(this));
183 chrome.cast.initialize(apiConfig, function(){
184 // The onInitSuccess method.
185 /**
186 * The `google-castable-video-initialized` event is fired when
187 * the cast client API has been initialized.
188 *
189 * @event google-castable-video-initialized
190 */
191 this.fire('google-castable-video-initialized');
192 }.bind(this), function(){
193 this._triggerError('INITIALIZE_ERROR');
194 });
195 },
196
197 /**
198 * Call this when the user clicks the cast icon.
199 * Opens the cast extension to create a session with the selected receiver.
200 *
201 * @method launchSessionManager
202 */
203 launchSessionManager: function(){
204 if (this._receiverAvailable) {
205 // Create the session with the receiver.
206 chrome.cast.requestSession(function(e){
207 // The onRequestSessionSuccess handler gets executed when we're conn ected.
208 this._triggerCasting(true);
209 this._session = e;
210 this._session.addUpdateListener(this._sessionUpdateListener.bind(thi s));
211 // If video is playing start playing on chromecast at same position.
212 if (!this.paused) {
213 this.play();
214 this.pause(false);
215 }
216 // Set interval for cast timeupdate.
217 this._timeupdateInterval = setInterval(function(){
218 if (this._castMedia && this._castMedia.playerState === 'PLAYING') {
219 this._triggerTimeupdate(this._castMedia.getEstimatedTime());
220 this._bothPaused = false;
221 } else {
222 this._bothPaused = true;
223 }
224 }.bind(this), _GOOGLE_CASTABLE_VIDEO_TIMEUPDATE_DELAY);
225 }.bind(this));
226 }
227 },
228
229 // Internal method gets called when the cast session status changes.
230 _sessionUpdateListener: function(isAlive){
231 if (!isAlive) {
232 this._triggerCasting(false);
233 this._synchronizeMedia(true);
234 // If video was playing on the receiver start playing locally.
235 if (this._castMedia.playerState === 'PLAYING') {
236 this.play();
237 }
238 this._castMedia = null;
239 this._session = null;
240 // The session died so remove the timeupdate interval.
241 clearInterval(this._timeupdateInterval);
242 }
243 },
244
245 // Internal method gets called when media was set through `launchsession`
246 // or was already playing on cast device.
247 _onMediaDiscovered: function(how, media) {
248 this._castMedia = media;
249 if (how === 'loadMedia') {
250 this._synchronizeMedia(false);
251 }
252 },
253
254 // Internal method to synchronize the media objects.
255 _synchronizeMedia: function(castMaster){
256 if (castMaster) {
257 var position = this._castMedia.getEstimatedTime();
258 this.currentTime = position;
259 } else {
260 var position = this.currentTime;
261 var req = new chrome.cast.media.SeekRequest();
262 req.currentTime = position;
263 this._castMedia.seek(req);
264 }
265 },
266 /**
267 * Call the `play` method from your controls.
268 *
269 * @method play
270 */
271 play: function(cast){
272 if ((cast != undefined && !cast) || (!cast && !this._casting)) {
273 Object.getPrototypeOf(Object.getPrototypeOf(this)).play.call(this);
274 // this.super();
275 } else {
276 // Handle cast media.
277 if (!this._castMedia) {
278 var mediaInfo = new chrome.cast.media.MediaInfo(this.currentSrc);
279 [].forEach.call( // loop through DOM video sources to find the conte ntType of the current source
280 document.querySelectorAll("video source"),
281 function(el) {
282 // the HTML5 video API resolves the DOM 'src' attribute to an abs olute URL for the value of 'currentSrc'; to make it matchable, then, we can only rely on the last segment of the URL
283 if (el.getAttribute("src").split('/').pop()===this.currentSrc.spl it('/').pop()) {
284 mediaInfo.contentType = el.getAttribute('type');
285 }
286 }
287 );
288 var request = new chrome.cast.media.LoadRequest(mediaInfo);
289 this._session.loadMedia(request,
290 this._onMediaDiscovered.bind(this, 'loadMedia'),
291 function(e){
292 this._triggerError('LOAD_MEDIA_ERROR');
293 }.bind(this)
294 );
295 } else {
296 this._castMedia.play();
297 }
298 }
299 },
300
301 /**
302 * Call the `pause` method from your controls.
303 *
304 * @method pause
305 */
306 pause: function(cast){
307 if ((cast != undefined && !cast) || (!cast && !this._casting)) {
308 Object.getPrototypeOf(Object.getPrototypeOf(this)).pause.call(this);
309 // this.super();
310 } else {
311 this._castMedia.pause();
312 }
313 },
314
315 /**
316 * The `google-castable-video-timeupdate` event is fired whenever
317 * the video's playback position changes.
318 *
319 * @event google-castable-video-timeupdate
320 * @param {Object} detail
321 * @param {number} detail.currentTime The current video position.
322 */
323 _triggerTimeupdate: function(position) {
324 this.fire('google-castable-video-timeupdate', { currentTime: position }) ;
325 },
326
327 /**
328 * The `google-castable-video-error` event is fired whenever
329 * an error occurs.
330 *
331 * @event google-castable-video-error
332 * @param {Object} detail
333 * @param {string} detail.error The error type.
334 */
335 _triggerError: function(description) {
336 this.fire('google-castable-video-error', { error: description });
337 },
338
339 /**
340 * The `google-castable-video-receiver-status` event is fired whenever
341 * the availability of Chromecasts changes. Use this to show or hide the c ast icon.
342 *
343 * @event google-castable-video-receiver-status
344 * @param {Object} detail
345 * @param {bool} detail.available Shows if receivers are available.
346 */
347 _triggerAvailability: function(availability) {
348 this._receiverAvailable = availability;
349 this.fire('google-castable-video-receiver-status', { available: availabi lity });
350 },
351
352 /**
353 * The `google-castable-video-casting` event is fired whenever the
354 * connection status to a Chromecast changes. Use this to change the cast icon.
355 *
356 * @event google-castable-video-casting
357 * @param {Object} detail
358 * @param {bool} detail.casting True if connected.
359 */
360 _triggerCasting: function(casting) {
361 this._casting = casting;
362 this.fire('google-castable-video-casting', { casting: casting });
363 },
364
365 // Redirecting `seeked` event to Chromecast.
366 _onSeeked: function(){
367 if (this._casting) {
368 var req = new chrome.cast.media.SeekRequest();
369 req.currentTime = this.currentTime;
370 this._castMedia.seek(req);
371 }
372 },
373
374 // Redirecting `volumechange` event to Chromecast.
375 _onVolumechange: function(){
376 if (this._casting) {
377 var volume = new chrome.cast.Volume(this.volume, this.muted);
378 var volumeRequest = new chrome.cast.media.VolumeRequest(volume);
379 this._castMedia.setVolume(volumeRequest);
380 }
381 },
382
383 // Redirecting `timeupdate` event to `google-castable-video-timeupdate`.
384 _onTimeupdate: function(){
385 this._triggerTimeupdate(this.currentTime);
386 this._bothPaused = this.paused;
387 }
388 });
389 })();
390 </script>
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698