@gumlet/player.js 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/player.js ADDED
@@ -0,0 +1,1076 @@
1
+ /*! Player.js - v1.0.0 - 2023-05-25
2
+ * http://github.com/gumlet/player.js
3
+ * Copyright (c) 2023 Gumlet; Licensed , , */
4
+ (function(window, document){
5
+ var playerjs = {};
6
+
7
+ playerjs.DEBUG = false;
8
+ playerjs.VERSION = '0.0.11';
9
+ playerjs.CONTEXT = 'player.js';
10
+ playerjs.POST_MESSAGE = !!window.postMessage;
11
+
12
+ /*
13
+ * Utils.
14
+ */
15
+ playerjs.origin = function(url){
16
+ // Grab the origin of a URL
17
+ if (url.substr(0, 2) === '//'){
18
+ url = window.location.protocol + url;
19
+ }
20
+
21
+ return url.split('/').slice(0,3).join('/');
22
+ };
23
+
24
+ playerjs.addEvent = function(elem, type, eventHandle) {
25
+ if (!elem) { return; }
26
+ if ( elem.addEventListener ) {
27
+ elem.addEventListener( type, eventHandle, false );
28
+ } else if ( elem.attachEvent ) {
29
+ elem.attachEvent( "on" + type, eventHandle );
30
+ } else {
31
+ elem["on"+type]=eventHandle;
32
+ }
33
+ };
34
+
35
+ // usage: log('inside coolFunc',this,arguments);
36
+ // http://paulirish.com/2009/log-a-lightweight-wrapper-for-consolelog/
37
+ playerjs.log = function(){
38
+ playerjs.log.history = playerjs.log.history || []; // store logs to an array for reference
39
+ playerjs.log.history.push(arguments);
40
+ if(window.console && playerjs.DEBUG){
41
+ window.console.log( Array.prototype.slice.call(arguments) );
42
+ }
43
+ };
44
+
45
+ // isFunctions
46
+ playerjs.isString = function (obj) {
47
+ return Object.prototype.toString.call(obj) === '[object String]';
48
+ };
49
+
50
+ playerjs.isObject = function(obj){
51
+ return Object.prototype.toString.call(obj) === "[object Object]";
52
+ };
53
+
54
+ playerjs.isArray = function(obj){
55
+ return Object.prototype.toString.call(obj) === "[object Array]";
56
+ };
57
+
58
+ playerjs.isNone = function(obj){
59
+ return (obj === null || obj === undefined);
60
+ };
61
+
62
+ playerjs.has = function(obj, key){
63
+ return Object.prototype.hasOwnProperty.call(obj, key);
64
+ };
65
+
66
+ // ie8 doesn't support indexOf in arrays, based on underscore.
67
+ playerjs.indexOf = function(array, item) {
68
+ if (array == null){ return -1; }
69
+ var i = 0, length = array.length;
70
+ if (Array.prototype.IndexOf && array.indexOf === Array.prototype.IndexOf) {
71
+ return array.indexOf(item);
72
+ }
73
+ for (; i < length; i++) {
74
+ if (array[i] === item) { return i; }
75
+ }
76
+ return -1;
77
+ };
78
+
79
+ // Assert
80
+ playerjs.assert = function(test, msg) {
81
+ if (!test) {
82
+ throw msg || "Player.js Assert Failed";
83
+ }
84
+ };
85
+ /*
86
+ * Keeper is just a method for keeping track of all the callbacks.
87
+ */
88
+
89
+ playerjs.Keeper = function(){
90
+ this.init();
91
+ };
92
+
93
+ playerjs.Keeper.prototype.init = function(){
94
+ this.data = {};
95
+ };
96
+
97
+ playerjs.Keeper.prototype.getUUID = function(){
98
+ // Create a random id. #http://stackoverflow.com/a/2117523/564191
99
+ return 'listener-xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
100
+ var r = Math.random()*16|0, v = c === 'x' ? r : (r&0x3|0x8);
101
+ return v.toString(16);
102
+ });
103
+ };
104
+
105
+ playerjs.Keeper.prototype.has = function(event, id){
106
+ if (!this.data.hasOwnProperty(event)){
107
+ return false;
108
+ }
109
+
110
+ if (playerjs.isNone(id)){
111
+ return true;
112
+ }
113
+
114
+ // Figure out if we have the event.
115
+ var events = this.data[event];
116
+
117
+ for (var i = 0; i < events.length; i++){
118
+ if (events[i].id === id){
119
+ return true;
120
+ }
121
+ }
122
+
123
+ return false;
124
+ };
125
+
126
+ playerjs.Keeper.prototype.add = function(id, event, cb, ctx, one){
127
+ var d = {
128
+ id: id,
129
+ event: event,
130
+ cb: cb,
131
+ ctx: ctx,
132
+ one: one
133
+ };
134
+
135
+ if (this.has(event)){
136
+ this.data[event].push(d);
137
+ } else {
138
+ this.data[event] = [d];
139
+ }
140
+ };
141
+
142
+ playerjs.Keeper.prototype.execute = function(event, id, data, ctx){
143
+ if (!this.has(event, id)){
144
+ return false;
145
+ }
146
+
147
+ var keep = [],
148
+ execute = [];
149
+
150
+ for (var i=0; i< this.data[event].length; i++){
151
+ var d = this.data[event][i];
152
+
153
+ // There are omni events, in that they do not have an id. i.e "ready".
154
+ // Or there is an ID and we only want to execute the right id'd method.
155
+ if (playerjs.isNone(id) || (!playerjs.isNone(id) && d.id === id )){
156
+
157
+ execute.push({
158
+ cb: d.cb,
159
+ ctx: d.ctx? d.ctx: ctx,
160
+ data: data
161
+ });
162
+
163
+ // If we only wanted to execute this once.
164
+ if (d.one === false){
165
+ keep.push(d);
166
+ }
167
+ } else {
168
+ keep.push(d);
169
+ }
170
+ }
171
+
172
+ if (keep.length === 0){
173
+ delete this.data[event];
174
+ } else {
175
+ this.data[event] = keep;
176
+ }
177
+
178
+ // We need to execute everything after we deal with the one stuff. otherwise
179
+ // we have issues to order of operations.
180
+ for (var n=0; n < execute.length; n++){
181
+ var e = execute[n];
182
+ e.cb.call(e.ctx, e.data);
183
+ }
184
+ };
185
+
186
+ playerjs.Keeper.prototype.on = function(id, event, cb, ctx){
187
+ this.add(id, event, cb, ctx, false);
188
+ };
189
+
190
+ playerjs.Keeper.prototype.one = function(id, event, cb, ctx){
191
+ this.add(id, event, cb, ctx, true);
192
+ };
193
+
194
+ playerjs.Keeper.prototype.off = function(event, cb){
195
+ // We should probably restructure so this is a bit less of a pain.
196
+ var listeners = [];
197
+
198
+ if (!this.data.hasOwnProperty(event)){
199
+ return listeners;
200
+ }
201
+
202
+ var keep = [];
203
+
204
+ // Loop through everything.
205
+ for (var i=0; i< this.data[event].length; i++){
206
+ var data = this.data[event][i];
207
+ // If we only keep if there was a CB and the CB is there.
208
+ if (!playerjs.isNone(cb) && data.cb !== cb) {
209
+ keep.push(data);
210
+ } else if (!playerjs.isNone(data.id)) {
211
+ listeners.push(data.id);
212
+ }
213
+ }
214
+
215
+ if (keep.length === 0){
216
+ delete this.data[event];
217
+ } else {
218
+ this.data[event] = keep;
219
+ }
220
+
221
+ return listeners;
222
+ };
223
+
224
+ /*
225
+ * Player.js is a javascript library for interacting with iframes via
226
+ * postMessage that use an Open Player Spec
227
+ *
228
+ */
229
+
230
+ playerjs.Player = function(elem, options){
231
+ if (!(this instanceof playerjs.Player)) {
232
+ return new playerjs.Player(elem, options);
233
+ }
234
+ this.init(elem, options);
235
+ };
236
+
237
+ playerjs.EVENTS = {
238
+ READY: 'ready',
239
+ PLAY: 'play',
240
+ PAUSE: 'pause',
241
+ ENDED: 'ended',
242
+ TIMEUPDATE: 'timeupdate',
243
+ PROGRESS: 'progress',
244
+ ERROR: 'error'
245
+ };
246
+
247
+ playerjs.EVENTS.all = function(){
248
+ var all = [];
249
+ for (var key in playerjs.EVENTS) {
250
+ if (playerjs.has(playerjs.EVENTS, key) && playerjs.isString(playerjs.EVENTS[key])) {
251
+ all.push(playerjs.EVENTS[key]);
252
+ }
253
+ }
254
+ return all;
255
+ };
256
+
257
+ playerjs.METHODS = {
258
+ PLAY: 'play',
259
+ PAUSE: 'pause',
260
+ GETPAUSED: 'getPaused',
261
+ MUTE: 'mute',
262
+ UNMUTE: 'unmute',
263
+ GETMUTED: 'getMuted',
264
+ SETVOLUME: 'setVolume',
265
+ GETVOLUME: 'getVolume',
266
+ GETDURATION: 'getDuration',
267
+ SETCURRENTTIME: 'setCurrentTime',
268
+ GETCURRENTTIME:'getCurrentTime',
269
+ SETLOOP: 'setLoop',
270
+ GETLOOP: 'getLoop',
271
+ REMOVEEVENTLISTENER: 'removeEventListener',
272
+ ADDEVENTLISTENER: 'addEventListener'
273
+ };
274
+
275
+ playerjs.METHODS.all = function(){
276
+ var all = [];
277
+ for (var key in playerjs.METHODS) {
278
+ if (playerjs.has(playerjs.METHODS, key) && playerjs.isString(playerjs.METHODS[key])) {
279
+ all.push(playerjs.METHODS[key]);
280
+ }
281
+ }
282
+ return all;
283
+ };
284
+
285
+ playerjs.READIED = [];
286
+
287
+ playerjs.Player.prototype.init = function(elem, options){
288
+
289
+ var self = this;
290
+
291
+ if (playerjs.isString(elem)){
292
+ elem = document.getElementById(elem);
293
+ }
294
+
295
+ this.elem = elem;
296
+
297
+ // make sure we have an iframe
298
+ playerjs.assert(elem.nodeName === 'IFRAME',
299
+ 'playerjs.Player constructor requires an Iframe, got "'+elem.nodeName+'"');
300
+ playerjs.assert(elem.src,
301
+ 'playerjs.Player constructor requires a Iframe with a \'src\' attribute.');
302
+
303
+ // Figure out the origin of where we are sending messages.
304
+ this.origin = playerjs.origin(elem.src);
305
+
306
+ // Event handling.
307
+ this.keeper = new playerjs.Keeper();
308
+
309
+ // Queuing before ready.
310
+ this.isReady = false;
311
+ this.queue = [];
312
+
313
+ // Assume that everything is supported, unless we know otherwise.
314
+ this.events = playerjs.EVENTS.all();
315
+ this.methods = playerjs.METHODS.all();
316
+
317
+ if (playerjs.POST_MESSAGE){
318
+ // Set up the reciever.
319
+ playerjs.addEvent(window, 'message', function(e){
320
+ self.receive(e);
321
+ });
322
+ } else {
323
+ playerjs.log('Post Message is not Available.');
324
+ }
325
+
326
+ // See if we caught the src event first, otherwise assume we haven't loaded
327
+ if (playerjs.indexOf(playerjs.READIED, elem.src) > -1){
328
+ self.loaded = true;
329
+ } else {
330
+ // Try the onload event, just lets us give another test.
331
+ this.elem.onload = function(){
332
+ self.loaded = true;
333
+ };
334
+ }
335
+ };
336
+
337
+ playerjs.Player.prototype.send = function(data, callback, ctx){
338
+ // Add the context and version to the data.
339
+ data.context = playerjs.CONTEXT;
340
+ data.version = playerjs.VERSION;
341
+
342
+ // We are expecting a response.
343
+ if (callback) {
344
+ // Create a UUID
345
+ var id = this.keeper.getUUID();
346
+
347
+ // Set the listener.
348
+ data.listener = id;
349
+
350
+ // Only hang on to this listener once.
351
+ this.keeper.one(id, data.method, callback, ctx);
352
+ }
353
+
354
+ if (!this.isReady && data.value !== 'ready'){
355
+ playerjs.log('Player.queue', data);
356
+ this.queue.push(data);
357
+ return false;
358
+ }
359
+
360
+ playerjs.log('Player.send', data, this.origin);
361
+
362
+ if (this.loaded === true){
363
+ this.elem.contentWindow.postMessage(JSON.stringify(data), this.origin);
364
+ }
365
+
366
+ return true;
367
+ };
368
+
369
+ playerjs.Player.prototype.receive = function(e){
370
+ playerjs.log('Player.receive', e);
371
+
372
+ if (e.origin !== this.origin){
373
+ return false;
374
+ }
375
+
376
+ var data;
377
+ try {
378
+ data = JSON.parse(e.data);
379
+ } catch (err){
380
+ // Not a valid response.
381
+ return false;
382
+ }
383
+
384
+ // abort if this message wasn't a player.js message
385
+ if (data.context !== playerjs.CONTEXT) {
386
+ return false;
387
+ }
388
+
389
+ // We need to determine if we are ready.
390
+ if (data.event === 'ready' && data.value && data.value.src === this.elem.src){
391
+ this.ready(data);
392
+ }
393
+
394
+ if (this.keeper.has(data.event, data.listener)){
395
+ this.keeper.execute(data.event, data.listener, data.value, this);
396
+ }
397
+ };
398
+
399
+
400
+ playerjs.Player.prototype.ready = function(data){
401
+
402
+ if (this.isReady === true){
403
+ return false;
404
+ }
405
+
406
+ // If we got a list of supported methods, we should set them.
407
+ if (data.value.events){
408
+ this.events = data.value.events;
409
+ }
410
+ if (data.value.methods){
411
+ this.methods = data.value.methods;
412
+ }
413
+
414
+ // set ready.
415
+ this.isReady = true;
416
+ this.loaded = true;
417
+
418
+ // Clear the queue
419
+ for (var i=0; i<this.queue.length; i++){
420
+ var obj = this.queue[i];
421
+
422
+ playerjs.log('Player.dequeue', obj);
423
+
424
+ if (data.event === 'ready'){
425
+ this.keeper.execute(obj.event, obj.listener, true, this);
426
+ }
427
+ this.send(obj);
428
+ }
429
+ this.queue = [];
430
+ };
431
+
432
+ playerjs.Player.prototype.on = function(event, callback, ctx){
433
+ var id = this.keeper.getUUID();
434
+
435
+ if (event === 'ready'){
436
+ // We only want to call ready once.
437
+ this.keeper.one(id, event, callback, ctx);
438
+ } else {
439
+ this.keeper.on(id, event, callback, ctx);
440
+ }
441
+
442
+ this.send({
443
+ method: 'addEventListener',
444
+ value: event,
445
+ listener: id
446
+ });
447
+
448
+ return true;
449
+ };
450
+
451
+ playerjs.Player.prototype.off = function(event, callback){
452
+
453
+ var listeners = this.keeper.off(event, callback);
454
+ playerjs.log('Player.off', listeners);
455
+
456
+ if (listeners.length > 0) {
457
+ for (var i in listeners){
458
+ this.send({
459
+ method: 'removeEventListener',
460
+ value: event,
461
+ listener: listeners[i]
462
+ });
463
+ return true;
464
+ }
465
+ }
466
+
467
+ return false;
468
+ };
469
+
470
+ // Based on what ready passed back, we can determine if the events/method are
471
+ // supported by the player.
472
+ playerjs.Player.prototype.supports = function(evtOrMethod, names){
473
+
474
+ playerjs.assert(playerjs.indexOf(['method', 'event'], evtOrMethod) > -1,
475
+ 'evtOrMethod needs to be either "event" or "method" got ' + evtOrMethod);
476
+
477
+ // Make everything an array.
478
+ names = playerjs.isArray(names) ? names : [names];
479
+
480
+ var all = evtOrMethod === 'event' ? this.events : this.methods;
481
+
482
+ for (var i=0; i < names.length; i++){
483
+ if (playerjs.indexOf(all, names[i]) === -1){
484
+ return false;
485
+ }
486
+ }
487
+
488
+ return true;
489
+ };
490
+
491
+ //create function to add to the Player prototype
492
+ function createPrototypeFunction(name) {
493
+
494
+ return function() {
495
+
496
+ var data = {
497
+ method: name
498
+ };
499
+
500
+ var args = Array.prototype.slice.call(arguments);
501
+
502
+ //for getters add the passed parameters to the arguments for the send call
503
+ if (/^get/.test(name)) {
504
+ playerjs.assert(args.length > 0, 'Get methods require a callback.');
505
+ args.unshift(data);
506
+ } else {
507
+ //for setter add the first arg to the value field
508
+ if (/^set/.test(name)) {
509
+ playerjs.assert(args.length !== 0, 'Set methods require a value.');
510
+ data.value = args[0];
511
+ }
512
+ args = [data];
513
+ }
514
+
515
+ this.send.apply(this, args);
516
+ };
517
+ }
518
+
519
+ // Loop through the methods to add them to the prototype.
520
+ for (var i = 0, l = playerjs.METHODS.all().length; i < l; i++) {
521
+ var methodName = playerjs.METHODS.all()[i];
522
+
523
+ // We don't want to overwrite existing methods.
524
+ if (!playerjs.Player.prototype.hasOwnProperty(methodName)){
525
+ playerjs.Player.prototype[methodName] = createPrototypeFunction(methodName);
526
+ }
527
+ }
528
+
529
+ // We need to catch all ready events in case the iframe is ready before the
530
+ // player is invoked.
531
+ playerjs.addEvent(window, 'message', function(e){
532
+ var data;
533
+ try {
534
+ data = JSON.parse(e.data);
535
+ } catch (err){
536
+ return false;
537
+ }
538
+
539
+ // abort if this message wasn't a player.js message
540
+ if (data.context !== playerjs.CONTEXT) {
541
+ return false;
542
+ }
543
+
544
+ // We need to determine if we are ready.
545
+ if (data.event === 'ready' && data.value && data.value.src){
546
+ playerjs.READIED.push(data.value.src);
547
+ }
548
+ });
549
+
550
+ /*
551
+ * Does all the wiring up for the backend.
552
+ *
553
+ * var receiver = new playerjs.Receiver();
554
+ * receiver.on('play', function(){ video.play() });
555
+ * receiver.on('getDuration', function(callback){ callback(video.duration) });
556
+ * receiver.emit('timeupdate', {});
557
+ */
558
+
559
+ playerjs.Receiver = function(events, methods){
560
+ this.init(events, methods);
561
+ };
562
+
563
+ playerjs.Receiver.prototype.init = function(events, methods){
564
+ var self = this;
565
+
566
+ // Deal with the ready crap.
567
+ this.isReady = false;
568
+
569
+ // Bind the window message.
570
+ this.origin = playerjs.origin(document.referrer);
571
+
572
+ //Create a holder for all the methods.
573
+ this.methods = {};
574
+
575
+ // holds all the information about what's supported
576
+ this.supported = {
577
+ events: events ? events : playerjs.EVENTS.all(),
578
+ methods: methods ? methods : playerjs.METHODS.all()
579
+ };
580
+
581
+ // Deals with the adding and removing of event listeners.
582
+ this.eventListeners = {};
583
+
584
+ // We can't send any messages.
585
+ this.reject = !(window.self !== window.top && playerjs.POST_MESSAGE);
586
+
587
+ // We aren't in an iframe, don't listen.
588
+ if (!this.reject){
589
+ playerjs.addEvent(window, 'message', function(e){
590
+ self.receive(e);
591
+ });
592
+ }
593
+ };
594
+
595
+ playerjs.Receiver.prototype.receive = function(e){
596
+ // Only want to listen to events that came from our origin.
597
+ if (e.origin !== this.origin){
598
+ return false;
599
+ }
600
+
601
+ // Browsers that support postMessage also support JSON.
602
+ var data = {};
603
+ if (playerjs.isObject(e.data)){
604
+ data = e.data;
605
+ } else {
606
+ try {
607
+ data = window.JSON.parse(e.data);
608
+ } catch (err){
609
+ playerjs.log('JSON Parse Error', err);
610
+ }
611
+ }
612
+
613
+ playerjs.log('Receiver.receive', e, data);
614
+
615
+ // Nothing for us to do.
616
+ if (!data.method){
617
+ return false;
618
+ }
619
+
620
+ // make sure the context is correct.
621
+ if (data.context !== playerjs.CONTEXT){
622
+ return false;
623
+ }
624
+
625
+ // Make sure we have a valid method.
626
+ if (playerjs.indexOf(playerjs.METHODS.all(), data.method) === -1){
627
+ this.emit('error', {
628
+ code: 2,
629
+ msg: 'Invalid Method "'+data.method+'"'
630
+ });
631
+ return false;
632
+ }
633
+
634
+ // See if we added a listener
635
+ var listener = !playerjs.isNone(data.listener) ? data.listener : null;
636
+
637
+ // Add Event Listener.
638
+ if (data.method === 'addEventListener') {
639
+ if (this.eventListeners.hasOwnProperty(data.value)) {
640
+ //If the listener is the same, i.e. null only add it once.
641
+ if (playerjs.indexOf(this.eventListeners[data.value], listener) === -1){
642
+ this.eventListeners[data.value].push(listener);
643
+ }
644
+ } else {
645
+ this.eventListeners[data.value] = [listener];
646
+ }
647
+
648
+ if (data.value === 'ready' && this.isReady){
649
+ this.ready();
650
+ }
651
+ }
652
+ // Remove the event listener.
653
+ else if (data.method === 'removeEventListener') {
654
+ if (this.eventListeners.hasOwnProperty(data.value)) {
655
+ var index = playerjs.indexOf(this.eventListeners[data.value], listener);
656
+
657
+ // if we find the element, remove it.
658
+ if (index > -1){
659
+ this.eventListeners[data.value].splice(index, 1);
660
+ }
661
+
662
+ if (this.eventListeners[data.value].length === 0){
663
+ delete this.eventListeners[data.value];
664
+ }
665
+ }
666
+ }
667
+ // Go get it.
668
+ else {
669
+ this.get(data.method, data.value, listener);
670
+ }
671
+ };
672
+
673
+ playerjs.Receiver.prototype.get = function(method, value, listener){
674
+ var self = this;
675
+
676
+ // Now lets do it.
677
+ if (!this.methods.hasOwnProperty(method)){
678
+ this.emit('error', {
679
+ code: 3,
680
+ msg: 'Method Not Supported"'+method+'"'
681
+ });
682
+ return false;
683
+ }
684
+
685
+ var func = this.methods[method];
686
+
687
+ if (method.substr(0,3) === 'get') {
688
+ var callback = function(val){
689
+ self.send(method, val, listener);
690
+ };
691
+ func.call(this, callback);
692
+ } else {
693
+ func.call(this, value);
694
+ }
695
+ };
696
+
697
+ playerjs.Receiver.prototype.on = function(event, callback){
698
+ this.methods[event] = callback;
699
+ };
700
+
701
+ playerjs.Receiver.prototype.send = function(event, value, listener){
702
+
703
+ playerjs.log('Receiver.send', event, value, listener);
704
+
705
+ if (this.reject){
706
+ // We are not in a frame, or we don't support POST_MESSAGE
707
+ playerjs.log('Receiver.send.reject', event, value, listener);
708
+ return false;
709
+ }
710
+
711
+ var data = {
712
+ context: playerjs.CONTEXT,
713
+ version: playerjs.VERSION,
714
+ event: event
715
+ };
716
+
717
+ if (!playerjs.isNone(value)){
718
+ data.value = value;
719
+ }
720
+
721
+ if (!playerjs.isNone(listener)){
722
+ data.listener = listener;
723
+ }
724
+
725
+ var msg = JSON.stringify(data);
726
+ window.parent.postMessage(msg, this.origin === "" ? '*' : this.origin);
727
+ };
728
+
729
+ playerjs.Receiver.prototype.emit = function(event, value){
730
+
731
+ if (!this.eventListeners.hasOwnProperty(event)){
732
+ return false;
733
+ }
734
+
735
+ playerjs.log('Instance.emit', event, value, this.eventListeners[event]);
736
+
737
+ for (var i=0; i < this.eventListeners[event].length; i++){
738
+ var listener = this.eventListeners[event][i];
739
+ this.send(event, value, listener);
740
+ }
741
+
742
+ return true;
743
+ };
744
+
745
+ playerjs.Receiver.prototype.ready = function(){
746
+ playerjs.log('Receiver.ready');
747
+ this.isReady = true;
748
+
749
+ var data = {
750
+ src: window.location.toString(),
751
+ events: this.supported.events,
752
+ methods: this.supported.methods
753
+ };
754
+
755
+ if (!this.emit('ready', data)){
756
+ this.send('ready', data);
757
+ }
758
+
759
+ };
760
+
761
+ playerjs.HTML5Adapter = function(video){
762
+ if (!(this instanceof playerjs.HTML5Adapter)) {
763
+ return new playerjs.HTML5Adapter(video);
764
+ }
765
+ this.init(video);
766
+ };
767
+
768
+ playerjs.HTML5Adapter.prototype.init = function(video){
769
+
770
+ playerjs.assert(video, 'playerjs.HTML5Adapter requires a video element');
771
+
772
+ // Set up the actual receiver
773
+ var receiver = this.receiver = new playerjs.Receiver();
774
+
775
+ /* EVENTS */
776
+ video.addEventListener('playing', function(){
777
+ receiver.emit('play');
778
+ });
779
+
780
+ video.addEventListener('pause', function(){
781
+ receiver.emit('pause');
782
+ });
783
+
784
+ video.addEventListener('ended', function(){
785
+ receiver.emit('ended');
786
+ });
787
+
788
+ video.addEventListener('timeupdate', function(){
789
+ receiver.emit('timeupdate', {
790
+ seconds: video.currentTime,
791
+ duration: video.duration
792
+ });
793
+ });
794
+
795
+ video.addEventListener('progress', function(){
796
+ receiver.emit('buffered', {
797
+ percent: video.buffered.length
798
+ });
799
+ });
800
+
801
+ /* Methods */
802
+ receiver.on('play', function(){
803
+ video.play();
804
+ });
805
+
806
+ receiver.on('pause', function(){
807
+ video.pause();
808
+ });
809
+
810
+ receiver.on('getPaused', function(callback){
811
+ callback(video.paused);
812
+ });
813
+
814
+ receiver.on('getCurrentTime', function(callback){
815
+ callback(video.currentTime);
816
+ });
817
+
818
+ receiver.on('setCurrentTime', function(value){
819
+ video.currentTime = value;
820
+ });
821
+
822
+ receiver.on('getDuration', function(callback){
823
+ callback(video.duration);
824
+ });
825
+
826
+ receiver.on('getVolume', function(callback){
827
+ callback(video.volume * 100);
828
+ });
829
+
830
+ receiver.on('setVolume', function(value){
831
+ video.volume = value/100;
832
+ });
833
+
834
+ receiver.on('mute', function(){
835
+ video.muted = true;
836
+ });
837
+
838
+ receiver.on('unmute', function(){
839
+ video.muted = false;
840
+ });
841
+
842
+ receiver.on('getMuted', function(callback){
843
+ callback(video.muted);
844
+ });
845
+
846
+ receiver.on('getLoop', function(callback){
847
+ callback(video.loop);
848
+ });
849
+
850
+ receiver.on('setLoop', function(value){
851
+ video.loop = value;
852
+ });
853
+ };
854
+
855
+ /* Call when the video has loaded */
856
+ playerjs.HTML5Adapter.prototype.ready = function(){
857
+ this.receiver.ready();
858
+ };
859
+
860
+ playerjs.MockAdapter = function(){
861
+ if (!(this instanceof playerjs.MockAdapter)) {
862
+ return new playerjs.MockAdapter();
863
+ }
864
+ this.init();
865
+ };
866
+
867
+ playerjs.MockAdapter.prototype.init = function(){
868
+
869
+ // Our mock video
870
+ var video = {
871
+ duration: 20,
872
+ currentTime: 0,
873
+ interval: null,
874
+ timeupdate: function(){},
875
+ volume: 100,
876
+ mute: false,
877
+ playing: false,
878
+ loop : false,
879
+ play: function(){
880
+ video.interval = setInterval(function(){
881
+ video.currentTime += 0.25;
882
+ video.timeupdate({
883
+ seconds: video.currentTime,
884
+ duration: video.duration
885
+ });
886
+ }, 250);
887
+ video.playing = true;
888
+ },
889
+ pause: function(){
890
+ clearInterval(video.interval);
891
+ video.playing = false;
892
+ }
893
+ };
894
+
895
+ // Set up the actual receiver
896
+ var receiver = this.receiver = new playerjs.Receiver();
897
+
898
+ receiver.on('play', function(){
899
+ var self = this;
900
+ video.play();
901
+ this.emit('play');
902
+ video.timeupdate = function(data){
903
+ self.emit('timeupdate', data);
904
+ };
905
+ });
906
+
907
+ receiver.on('pause', function(){
908
+ video.pause();
909
+ this.emit('pause');
910
+ });
911
+
912
+ receiver.on('getPaused', function(callback){
913
+ callback(!video.playing);
914
+ });
915
+
916
+ receiver.on('getCurrentTime', function(callback){
917
+ callback(video.currentTime);
918
+ });
919
+
920
+ receiver.on('setCurrentTime', function(value){
921
+ video.currentTime = value;
922
+ });
923
+
924
+ receiver.on('getDuration', function(callback){
925
+ callback(video.duration);
926
+ });
927
+
928
+ receiver.on('getVolume', function(callback){
929
+ callback(video.volume);
930
+ });
931
+
932
+ receiver.on('setVolume', function(value){
933
+ video.volume = value;
934
+ });
935
+
936
+ receiver.on('mute', function(){
937
+ video.mute = true;
938
+ });
939
+
940
+ receiver.on('unmute', function(){
941
+ video.mute = false;
942
+ });
943
+
944
+ receiver.on('getMuted', function(callback){
945
+ callback(video.mute);
946
+ });
947
+
948
+ receiver.on('getLoop', function(callback){
949
+ callback(video.loop);
950
+ });
951
+
952
+ receiver.on('setLoop', function(value){
953
+ video.loop = value;
954
+ });
955
+ };
956
+
957
+ /* Call when the video has loaded */
958
+ playerjs.MockAdapter.prototype.ready = function(){
959
+ this.receiver.ready();
960
+ };
961
+ playerjs.VideoJSAdapter = function(player){
962
+ if (!(this instanceof playerjs.VideoJSAdapter)) {
963
+ return new playerjs.VideoJSAdapter(player);
964
+ }
965
+ this.init(player);
966
+ };
967
+
968
+ playerjs.VideoJSAdapter.prototype.init = function(player){
969
+
970
+ playerjs.assert(player, 'playerjs.VideoJSReceiver requires a player object');
971
+
972
+ // Set up the actual receiver
973
+ var receiver = this.receiver = new playerjs.Receiver();
974
+
975
+ /* EVENTS */
976
+ player.on("pause", function(){
977
+ receiver.emit('pause');
978
+ });
979
+
980
+ player.on("play", function(){
981
+ receiver.emit('play');
982
+ });
983
+
984
+ player.on("timeupdate", function(e){
985
+ var seconds = player.currentTime(),
986
+ duration = player.duration();
987
+
988
+ if (!seconds || !duration){
989
+ return false;
990
+ }
991
+
992
+ var value = {
993
+ seconds: seconds,
994
+ duration: duration
995
+ };
996
+ receiver.emit('timeupdate', value);
997
+ });
998
+
999
+ player.on("ended", function(){
1000
+ receiver.emit('ended');
1001
+ });
1002
+
1003
+ player.on("error", function(){
1004
+ receiver.emit('error');
1005
+ });
1006
+
1007
+
1008
+ /* METHODS */
1009
+ receiver.on('play', function(){
1010
+ player.play();
1011
+ });
1012
+
1013
+ receiver.on('pause', function(){
1014
+ player.pause();
1015
+ });
1016
+
1017
+ receiver.on('getPaused', function(callback){
1018
+ callback(player.paused());
1019
+ });
1020
+
1021
+ receiver.on('getCurrentTime', function(callback){
1022
+ callback(player.currentTime());
1023
+ });
1024
+
1025
+ receiver.on('setCurrentTime', function(value){
1026
+ player.currentTime(value);
1027
+ });
1028
+
1029
+ receiver.on('getDuration', function(callback){
1030
+ callback(player.duration());
1031
+ });
1032
+
1033
+ receiver.on('getVolume', function(callback){
1034
+ callback(player.volume() * 100);
1035
+ });
1036
+
1037
+ receiver.on('setVolume', function(value){
1038
+ player.volume(value/100);
1039
+ });
1040
+
1041
+ receiver.on('mute', function(){
1042
+ player.volume(0);
1043
+ });
1044
+
1045
+ receiver.on('unmute', function(){
1046
+ player.volume(1);
1047
+ });
1048
+
1049
+ receiver.on('getMuted', function(callback){
1050
+ callback(player.volume() === 0);
1051
+ });
1052
+
1053
+ receiver.on('getLoop', function(callback){
1054
+ callback(player.loop());
1055
+ });
1056
+
1057
+ receiver.on('setLoop', function(value){
1058
+ player.loop(value);
1059
+ });
1060
+ };
1061
+
1062
+ /* Call when the video.js is ready */
1063
+ playerjs.VideoJSAdapter.prototype.ready = function(){
1064
+ this.receiver.ready();
1065
+ };
1066
+
1067
+ if (typeof define === 'function' && define.amd) {
1068
+ define(function () {
1069
+ return playerjs
1070
+ })
1071
+ } else if (typeof module === 'object' && module.exports) {
1072
+ module.exports = playerjs
1073
+ } else {
1074
+ window.playerjs = playerjs;
1075
+ }
1076
+ })(window, document);