mediaelement_rails 0.4.0 → 0.5.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.
- data/README.md +1 -1
- data/app/assets/images/mediaelement_rails/bigplay.svg +1 -0
- data/app/assets/images/mediaelement_rails/controls.png +0 -0
- data/app/assets/images/mediaelement_rails/controls.svg +1 -0
- data/app/assets/javascripts/mediaelement_rails/index.js +0 -1
- data/app/assets/javascripts/mediaelement_rails/mediaelement.js +426 -164
- data/app/assets/javascripts/mediaelement_rails/mediaelementplayer.js +2004 -1890
- data/app/assets/plugins/mediaelement_rails/flashmediaelement.swf +0 -0
- data/app/assets/stylesheets/mediaelement_rails/mediaelementplayer.css.erb +77 -28
- data/lib/mediaelement_rails/version.rb +1 -1
- data/mediaelement_rails.thor +2 -2
- data/test/integration/assets_test.rb +1 -2
- metadata +44 -43
@@ -6,7 +6,7 @@
|
|
6
6
|
* using jQuery and MediaElement.js (HTML5 Flash/Silverlight wrapper)
|
7
7
|
*
|
8
8
|
* Copyright 2010-2012, John Dyer (http://j.hn/)
|
9
|
-
*
|
9
|
+
* License: MIT
|
10
10
|
*
|
11
11
|
*/
|
12
12
|
if (typeof jQuery != 'undefined') {
|
@@ -14,1082 +14,1098 @@ if (typeof jQuery != 'undefined') {
|
|
14
14
|
} else if (typeof ender != 'undefined') {
|
15
15
|
mejs.$ = ender;
|
16
16
|
}
|
17
|
-
(function ($) {
|
18
|
-
|
19
|
-
// default player values
|
20
|
-
mejs.MepDefaults = {
|
21
|
-
// url to poster (to fix iOS 3.x)
|
22
|
-
poster: '',
|
23
|
-
// default if the <video width> is not specified
|
24
|
-
defaultVideoWidth: 480,
|
25
|
-
// default if the <video height> is not specified
|
26
|
-
defaultVideoHeight: 270,
|
27
|
-
// if set, overrides <video width>
|
28
|
-
videoWidth: -1,
|
29
|
-
// if set, overrides <video height>
|
30
|
-
videoHeight: -1,
|
31
|
-
// default if the user doesn't specify
|
32
|
-
defaultAudioWidth: 400,
|
33
|
-
// default if the user doesn't specify
|
34
|
-
defaultAudioHeight: 30,
|
35
|
-
|
36
|
-
// default amount to move back when back key is pressed
|
37
|
-
defaultSeekBackwardInterval: function(media) {
|
38
|
-
return (media.duration * 0.05);
|
39
|
-
},
|
40
|
-
// default amount to move forward when forward key is pressed
|
41
|
-
defaultSeekForwardInterval: function(media) {
|
42
|
-
return (media.duration * 0.05);
|
43
|
-
},
|
44
|
-
|
45
|
-
// width of audio player
|
46
|
-
audioWidth: -1,
|
47
|
-
// height of audio player
|
48
|
-
audioHeight: -1,
|
49
|
-
// initial volume when the player starts (overrided by user cookie)
|
50
|
-
startVolume: 0.8,
|
51
|
-
// useful for <audio> player loops
|
52
|
-
loop: false,
|
53
|
-
//
|
54
|
-
|
55
|
-
//
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
//
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
//
|
66
|
-
|
67
|
-
//
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
// force
|
72
|
-
|
73
|
-
//
|
74
|
-
|
75
|
-
//
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
//
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
//
|
243
|
-
|
244
|
-
|
245
|
-
//
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
} else {
|
256
|
-
|
257
|
-
//
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
(
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
(
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
t.$media.
|
297
|
-
|
298
|
-
t.
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
}
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
//
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
t.width = t
|
329
|
-
} else {
|
330
|
-
t.width = t.
|
331
|
-
}
|
332
|
-
|
333
|
-
|
334
|
-
t.
|
335
|
-
}
|
336
|
-
|
337
|
-
|
338
|
-
t.height = t
|
339
|
-
} else {
|
340
|
-
t.height = t.
|
341
|
-
}
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
// any additional controls people might add and want to hide
|
381
|
-
t.container.find('.mejs-control')
|
382
|
-
.css('visibility','visible')
|
383
|
-
.
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
t.
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
t
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
t.
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
}
|
563
|
-
});
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
t.startControlsTimer(2500);
|
585
|
-
}
|
586
|
-
}
|
587
|
-
})
|
588
|
-
.bind('
|
589
|
-
if (t.controlsEnabled) {
|
590
|
-
if (!t.
|
591
|
-
t.
|
592
|
-
}
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
t.
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
|
714
|
-
|
715
|
-
t.
|
716
|
-
|
717
|
-
|
718
|
-
|
719
|
-
|
720
|
-
|
721
|
-
|
722
|
-
|
723
|
-
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
|
739
|
-
|
740
|
-
|
741
|
-
|
742
|
-
|
743
|
-
|
744
|
-
|
745
|
-
|
746
|
-
|
747
|
-
|
748
|
-
|
749
|
-
|
750
|
-
|
751
|
-
|
752
|
-
|
753
|
-
|
754
|
-
|
755
|
-
|
756
|
-
|
757
|
-
|
758
|
-
|
759
|
-
|
760
|
-
|
761
|
-
|
762
|
-
|
763
|
-
|
764
|
-
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
-
|
769
|
-
|
770
|
-
|
771
|
-
|
772
|
-
|
773
|
-
.
|
774
|
-
|
775
|
-
|
776
|
-
|
777
|
-
|
778
|
-
|
779
|
-
|
780
|
-
|
781
|
-
|
782
|
-
|
783
|
-
|
784
|
-
.
|
785
|
-
|
786
|
-
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
|
791
|
-
|
792
|
-
|
793
|
-
|
794
|
-
|
795
|
-
|
796
|
-
|
797
|
-
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
|
808
|
-
|
809
|
-
|
810
|
-
|
811
|
-
|
812
|
-
|
813
|
-
|
814
|
-
|
815
|
-
|
816
|
-
|
817
|
-
|
818
|
-
|
819
|
-
|
820
|
-
|
821
|
-
|
822
|
-
|
823
|
-
|
824
|
-
|
825
|
-
|
826
|
-
|
827
|
-
|
828
|
-
|
829
|
-
|
830
|
-
|
831
|
-
|
832
|
-
|
833
|
-
|
834
|
-
|
835
|
-
|
836
|
-
|
837
|
-
|
838
|
-
|
839
|
-
|
840
|
-
|
841
|
-
|
842
|
-
|
843
|
-
|
844
|
-
|
845
|
-
|
846
|
-
|
847
|
-
|
848
|
-
|
849
|
-
|
850
|
-
|
851
|
-
|
852
|
-
|
853
|
-
|
854
|
-
|
855
|
-
|
856
|
-
|
857
|
-
|
858
|
-
|
859
|
-
|
860
|
-
|
861
|
-
|
862
|
-
|
863
|
-
|
864
|
-
|
865
|
-
|
866
|
-
|
867
|
-
|
868
|
-
|
869
|
-
|
870
|
-
|
871
|
-
|
872
|
-
|
873
|
-
|
874
|
-
|
875
|
-
|
876
|
-
|
877
|
-
|
878
|
-
|
879
|
-
|
880
|
-
|
881
|
-
|
882
|
-
|
883
|
-
|
884
|
-
|
885
|
-
|
886
|
-
|
887
|
-
|
888
|
-
|
889
|
-
|
890
|
-
|
891
|
-
|
892
|
-
|
893
|
-
|
894
|
-
.
|
895
|
-
|
896
|
-
|
897
|
-
|
898
|
-
|
899
|
-
|
900
|
-
|
901
|
-
|
902
|
-
|
903
|
-
|
904
|
-
|
905
|
-
|
906
|
-
|
907
|
-
|
908
|
-
|
909
|
-
|
910
|
-
|
911
|
-
|
912
|
-
|
913
|
-
|
914
|
-
|
915
|
-
|
916
|
-
|
917
|
-
|
918
|
-
|
919
|
-
|
920
|
-
|
921
|
-
|
922
|
-
|
923
|
-
|
924
|
-
|
925
|
-
|
926
|
-
|
927
|
-
|
928
|
-
|
929
|
-
|
930
|
-
|
931
|
-
|
932
|
-
|
933
|
-
|
934
|
-
|
935
|
-
|
936
|
-
|
937
|
-
|
938
|
-
|
939
|
-
}, false);
|
940
|
-
|
941
|
-
media.addEventListener('
|
942
|
-
loading.show();
|
943
|
-
controls.find('.mejs-time-buffering').show();
|
944
|
-
}, false);
|
945
|
-
|
946
|
-
|
947
|
-
|
948
|
-
|
949
|
-
|
950
|
-
|
951
|
-
|
952
|
-
|
953
|
-
|
954
|
-
|
955
|
-
}, false);
|
956
|
-
|
957
|
-
|
958
|
-
|
959
|
-
|
960
|
-
|
961
|
-
|
962
|
-
|
963
|
-
|
964
|
-
|
965
|
-
|
966
|
-
|
967
|
-
|
968
|
-
|
969
|
-
|
970
|
-
|
971
|
-
|
972
|
-
|
973
|
-
|
974
|
-
|
975
|
-
|
976
|
-
|
977
|
-
|
978
|
-
|
979
|
-
|
980
|
-
|
981
|
-
|
982
|
-
|
983
|
-
|
984
|
-
|
985
|
-
|
986
|
-
|
987
|
-
|
988
|
-
|
989
|
-
|
990
|
-
|
991
|
-
|
992
|
-
|
993
|
-
|
994
|
-
|
995
|
-
|
996
|
-
|
997
|
-
|
998
|
-
|
999
|
-
|
1000
|
-
|
1001
|
-
|
1002
|
-
|
1003
|
-
|
1004
|
-
|
1005
|
-
|
1006
|
-
|
1007
|
-
|
1008
|
-
|
1009
|
-
|
1010
|
-
|
1011
|
-
|
1012
|
-
|
1013
|
-
|
1014
|
-
|
1015
|
-
|
1016
|
-
|
1017
|
-
|
1018
|
-
|
1019
|
-
|
1020
|
-
|
1021
|
-
|
1022
|
-
|
1023
|
-
|
1024
|
-
|
1025
|
-
|
1026
|
-
|
1027
|
-
|
1028
|
-
|
1029
|
-
|
1030
|
-
|
1031
|
-
|
1032
|
-
|
1033
|
-
|
1034
|
-
|
1035
|
-
|
1036
|
-
|
1037
|
-
|
1038
|
-
|
1039
|
-
|
1040
|
-
|
1041
|
-
|
1042
|
-
|
1043
|
-
this.
|
1044
|
-
|
1045
|
-
|
1046
|
-
|
1047
|
-
|
1048
|
-
|
1049
|
-
|
1050
|
-
|
1051
|
-
|
1052
|
-
|
1053
|
-
|
1054
|
-
|
1055
|
-
|
1056
|
-
|
1057
|
-
|
1058
|
-
|
1059
|
-
|
1060
|
-
|
1061
|
-
|
1062
|
-
|
1063
|
-
|
1064
|
-
|
1065
|
-
|
1066
|
-
|
1067
|
-
|
1068
|
-
|
1069
|
-
|
1070
|
-
|
1071
|
-
|
1072
|
-
}
|
1073
|
-
|
1074
|
-
|
1075
|
-
|
1076
|
-
|
1077
|
-
|
1078
|
-
|
1079
|
-
|
1080
|
-
}
|
1081
|
-
|
1082
|
-
|
1083
|
-
|
1084
|
-
|
1085
|
-
|
1086
|
-
|
1087
|
-
|
1088
|
-
|
1089
|
-
|
1090
|
-
|
1091
|
-
|
1092
|
-
|
17
|
+
(function ($) {
|
18
|
+
|
19
|
+
// default player values
|
20
|
+
mejs.MepDefaults = {
|
21
|
+
// url to poster (to fix iOS 3.x)
|
22
|
+
poster: '',
|
23
|
+
// default if the <video width> is not specified
|
24
|
+
defaultVideoWidth: 480,
|
25
|
+
// default if the <video height> is not specified
|
26
|
+
defaultVideoHeight: 270,
|
27
|
+
// if set, overrides <video width>
|
28
|
+
videoWidth: -1,
|
29
|
+
// if set, overrides <video height>
|
30
|
+
videoHeight: -1,
|
31
|
+
// default if the user doesn't specify
|
32
|
+
defaultAudioWidth: 400,
|
33
|
+
// default if the user doesn't specify
|
34
|
+
defaultAudioHeight: 30,
|
35
|
+
|
36
|
+
// default amount to move back when back key is pressed
|
37
|
+
defaultSeekBackwardInterval: function(media) {
|
38
|
+
return (media.duration * 0.05);
|
39
|
+
},
|
40
|
+
// default amount to move forward when forward key is pressed
|
41
|
+
defaultSeekForwardInterval: function(media) {
|
42
|
+
return (media.duration * 0.05);
|
43
|
+
},
|
44
|
+
|
45
|
+
// width of audio player
|
46
|
+
audioWidth: -1,
|
47
|
+
// height of audio player
|
48
|
+
audioHeight: -1,
|
49
|
+
// initial volume when the player starts (overrided by user cookie)
|
50
|
+
startVolume: 0.8,
|
51
|
+
// useful for <audio> player loops
|
52
|
+
loop: false,
|
53
|
+
// rewind to beginning when media ends
|
54
|
+
autoRewind: true,
|
55
|
+
// resize to media dimensions
|
56
|
+
enableAutosize: true,
|
57
|
+
// forces the hour marker (##:00:00)
|
58
|
+
alwaysShowHours: false,
|
59
|
+
|
60
|
+
// show framecount in timecode (##:00:00:00)
|
61
|
+
showTimecodeFrameCount: false,
|
62
|
+
// used when showTimecodeFrameCount is set to true
|
63
|
+
framesPerSecond: 25,
|
64
|
+
|
65
|
+
// automatically calculate the width of the progress bar based on the sizes of other elements
|
66
|
+
autosizeProgress : true,
|
67
|
+
// Hide controls when playing and mouse is not over the video
|
68
|
+
alwaysShowControls: false,
|
69
|
+
// Enable click video element to toggle play/pause
|
70
|
+
clickToPlayPause: true,
|
71
|
+
// force iPad's native controls
|
72
|
+
iPadUseNativeControls: false,
|
73
|
+
// force iPhone's native controls
|
74
|
+
iPhoneUseNativeControls: false,
|
75
|
+
// force Android's native controls
|
76
|
+
AndroidUseNativeControls: false,
|
77
|
+
// features to show
|
78
|
+
features: ['playpause','current','progress','duration','tracks','volume','fullscreen'],
|
79
|
+
// only for dynamic
|
80
|
+
isVideo: true,
|
81
|
+
|
82
|
+
// turns keyboard support on and off for this instance
|
83
|
+
enableKeyboard: true,
|
84
|
+
|
85
|
+
// whenthis player starts, it will pause other players
|
86
|
+
pauseOtherPlayers: true,
|
87
|
+
|
88
|
+
// array of keyboard actions such as play pause
|
89
|
+
keyActions: [
|
90
|
+
{
|
91
|
+
keys: [
|
92
|
+
32, // SPACE
|
93
|
+
179 // GOOGLE play/pause button
|
94
|
+
],
|
95
|
+
action: function(player, media) {
|
96
|
+
if (media.paused || media.ended) {
|
97
|
+
media.play();
|
98
|
+
} else {
|
99
|
+
media.pause();
|
100
|
+
}
|
101
|
+
}
|
102
|
+
},
|
103
|
+
{
|
104
|
+
keys: [38], // UP
|
105
|
+
action: function(player, media) {
|
106
|
+
var newVolume = Math.min(media.volume + 0.1, 1);
|
107
|
+
media.setVolume(newVolume);
|
108
|
+
}
|
109
|
+
},
|
110
|
+
{
|
111
|
+
keys: [40], // DOWN
|
112
|
+
action: function(player, media) {
|
113
|
+
var newVolume = Math.max(media.volume - 0.1, 0);
|
114
|
+
media.setVolume(newVolume);
|
115
|
+
}
|
116
|
+
},
|
117
|
+
{
|
118
|
+
keys: [
|
119
|
+
37, // LEFT
|
120
|
+
227 // Google TV rewind
|
121
|
+
],
|
122
|
+
action: function(player, media) {
|
123
|
+
if (!isNaN(media.duration) && media.duration > 0) {
|
124
|
+
if (player.isVideo) {
|
125
|
+
player.showControls();
|
126
|
+
player.startControlsTimer();
|
127
|
+
}
|
128
|
+
|
129
|
+
// 5%
|
130
|
+
var newTime = Math.max(media.currentTime - player.options.defaultSeekBackwardInterval(media), 0);
|
131
|
+
media.setCurrentTime(newTime);
|
132
|
+
}
|
133
|
+
}
|
134
|
+
},
|
135
|
+
{
|
136
|
+
keys: [
|
137
|
+
39, // RIGHT
|
138
|
+
228 // Google TV forward
|
139
|
+
],
|
140
|
+
action: function(player, media) {
|
141
|
+
if (!isNaN(media.duration) && media.duration > 0) {
|
142
|
+
if (player.isVideo) {
|
143
|
+
player.showControls();
|
144
|
+
player.startControlsTimer();
|
145
|
+
}
|
146
|
+
|
147
|
+
// 5%
|
148
|
+
var newTime = Math.min(media.currentTime + player.options.defaultSeekForwardInterval(media), media.duration);
|
149
|
+
media.setCurrentTime(newTime);
|
150
|
+
}
|
151
|
+
}
|
152
|
+
},
|
153
|
+
{
|
154
|
+
keys: [70], // f
|
155
|
+
action: function(player, media) {
|
156
|
+
if (typeof player.enterFullScreen != 'undefined') {
|
157
|
+
if (player.isFullScreen) {
|
158
|
+
player.exitFullScreen();
|
159
|
+
} else {
|
160
|
+
player.enterFullScreen();
|
161
|
+
}
|
162
|
+
}
|
163
|
+
}
|
164
|
+
}
|
165
|
+
]
|
166
|
+
};
|
167
|
+
|
168
|
+
mejs.mepIndex = 0;
|
169
|
+
|
170
|
+
mejs.players = [];
|
171
|
+
|
172
|
+
// wraps a MediaElement object in player controls
|
173
|
+
mejs.MediaElementPlayer = function(node, o) {
|
174
|
+
// enforce object, even without "new" (via John Resig)
|
175
|
+
if ( !(this instanceof mejs.MediaElementPlayer) ) {
|
176
|
+
return new mejs.MediaElementPlayer(node, o);
|
177
|
+
}
|
178
|
+
|
179
|
+
var t = this;
|
180
|
+
|
181
|
+
// these will be reset after the MediaElement.success fires
|
182
|
+
t.$media = t.$node = $(node);
|
183
|
+
t.node = t.media = t.$media[0];
|
184
|
+
|
185
|
+
// check for existing player
|
186
|
+
if (typeof t.node.player != 'undefined') {
|
187
|
+
return t.node.player;
|
188
|
+
} else {
|
189
|
+
// attach player to DOM node for reference
|
190
|
+
t.node.player = t;
|
191
|
+
}
|
192
|
+
|
193
|
+
|
194
|
+
// try to get options from data-mejsoptions
|
195
|
+
if (typeof o == 'undefined') {
|
196
|
+
o = t.$node.data('mejsoptions');
|
197
|
+
}
|
198
|
+
|
199
|
+
// extend default options
|
200
|
+
t.options = $.extend({},mejs.MepDefaults,o);
|
201
|
+
|
202
|
+
// add to player array (for focus events)
|
203
|
+
mejs.players.push(t);
|
204
|
+
|
205
|
+
// start up
|
206
|
+
t.init();
|
207
|
+
|
208
|
+
return t;
|
209
|
+
};
|
210
|
+
|
211
|
+
// actual player
|
212
|
+
mejs.MediaElementPlayer.prototype = {
|
213
|
+
|
214
|
+
hasFocus: false,
|
215
|
+
|
216
|
+
controlsAreVisible: true,
|
217
|
+
|
218
|
+
init: function() {
|
219
|
+
|
220
|
+
var
|
221
|
+
t = this,
|
222
|
+
mf = mejs.MediaFeatures,
|
223
|
+
// options for MediaElement (shim)
|
224
|
+
meOptions = $.extend(true, {}, t.options, {
|
225
|
+
success: function(media, domNode) { t.meReady(media, domNode); },
|
226
|
+
error: function(e) { t.handleError(e);}
|
227
|
+
}),
|
228
|
+
tagName = t.media.tagName.toLowerCase();
|
229
|
+
|
230
|
+
t.isDynamic = (tagName !== 'audio' && tagName !== 'video');
|
231
|
+
|
232
|
+
if (t.isDynamic) {
|
233
|
+
// get video from src or href?
|
234
|
+
t.isVideo = t.options.isVideo;
|
235
|
+
} else {
|
236
|
+
t.isVideo = (tagName !== 'audio' && t.options.isVideo);
|
237
|
+
}
|
238
|
+
|
239
|
+
// use native controls in iPad, iPhone, and Android
|
240
|
+
if ((mf.isiPad && t.options.iPadUseNativeControls) || (mf.isiPhone && t.options.iPhoneUseNativeControls)) {
|
241
|
+
|
242
|
+
// add controls and stop
|
243
|
+
t.$media.attr('controls', 'controls');
|
244
|
+
|
245
|
+
// attempt to fix iOS 3 bug
|
246
|
+
//t.$media.removeAttr('poster');
|
247
|
+
// no Issue found on iOS3 -ttroxell
|
248
|
+
|
249
|
+
// override Apple's autoplay override for iPads
|
250
|
+
if (mf.isiPad && t.media.getAttribute('autoplay') !== null) {
|
251
|
+
t.media.load();
|
252
|
+
t.media.play();
|
253
|
+
}
|
254
|
+
|
255
|
+
} else if (mf.isAndroid && t.AndroidUseNativeControls) {
|
256
|
+
|
257
|
+
// leave default player
|
258
|
+
|
259
|
+
} else {
|
260
|
+
|
261
|
+
// DESKTOP: use MediaElementPlayer controls
|
262
|
+
|
263
|
+
// remove native controls
|
264
|
+
t.$media.removeAttr('controls');
|
265
|
+
|
266
|
+
// unique ID
|
267
|
+
t.id = 'mep_' + mejs.mepIndex++;
|
268
|
+
|
269
|
+
// build container
|
270
|
+
t.container =
|
271
|
+
$('<div id="' + t.id + '" class="mejs-container ' + (mejs.MediaFeatures.svg ? 'svg' : 'no-svg') + '">'+
|
272
|
+
'<div class="mejs-inner">'+
|
273
|
+
'<div class="mejs-mediaelement"></div>'+
|
274
|
+
'<div class="mejs-layers"></div>'+
|
275
|
+
'<div class="mejs-controls"></div>'+
|
276
|
+
'<div class="mejs-clear"></div>'+
|
277
|
+
'</div>' +
|
278
|
+
'</div>')
|
279
|
+
.addClass(t.$media[0].className)
|
280
|
+
.insertBefore(t.$media);
|
281
|
+
|
282
|
+
// add classes for user and content
|
283
|
+
t.container.addClass(
|
284
|
+
(mf.isAndroid ? 'mejs-android ' : '') +
|
285
|
+
(mf.isiOS ? 'mejs-ios ' : '') +
|
286
|
+
(mf.isiPad ? 'mejs-ipad ' : '') +
|
287
|
+
(mf.isiPhone ? 'mejs-iphone ' : '') +
|
288
|
+
(t.isVideo ? 'mejs-video ' : 'mejs-audio ')
|
289
|
+
);
|
290
|
+
|
291
|
+
|
292
|
+
// move the <video/video> tag into the right spot
|
293
|
+
if (mf.isiOS) {
|
294
|
+
|
295
|
+
// sadly, you can't move nodes in iOS, so we have to destroy and recreate it!
|
296
|
+
var $newMedia = t.$media.clone();
|
297
|
+
|
298
|
+
t.container.find('.mejs-mediaelement').append($newMedia);
|
299
|
+
|
300
|
+
t.$media.remove();
|
301
|
+
t.$node = t.$media = $newMedia;
|
302
|
+
t.node = t.media = $newMedia[0]
|
303
|
+
|
304
|
+
} else {
|
305
|
+
|
306
|
+
// normal way of moving it into place (doesn't work on iOS)
|
307
|
+
t.container.find('.mejs-mediaelement').append(t.$media);
|
308
|
+
}
|
309
|
+
|
310
|
+
// find parts
|
311
|
+
t.controls = t.container.find('.mejs-controls');
|
312
|
+
t.layers = t.container.find('.mejs-layers');
|
313
|
+
|
314
|
+
// determine the size
|
315
|
+
|
316
|
+
/* size priority:
|
317
|
+
(1) videoWidth (forced),
|
318
|
+
(2) style="width;height;"
|
319
|
+
(3) width attribute,
|
320
|
+
(4) defaultVideoWidth (for unspecified cases)
|
321
|
+
*/
|
322
|
+
|
323
|
+
var tagType = (t.isVideo ? 'video' : 'audio'),
|
324
|
+
capsTagName = tagType.substring(0,1).toUpperCase() + tagType.substring(1);
|
325
|
+
|
326
|
+
|
327
|
+
if (t.options[tagType + 'Width'] > 0 || t.options[tagType + 'Width'].toString().indexOf('%') > -1) {
|
328
|
+
t.width = t.options[tagType + 'Width'];
|
329
|
+
} else if (t.media.style.width !== '' && t.media.style.width !== null) {
|
330
|
+
t.width = t.media.style.width;
|
331
|
+
} else if (t.media.getAttribute('width') !== null) {
|
332
|
+
t.width = t.$media.attr('width');
|
333
|
+
} else {
|
334
|
+
t.width = t.options['default' + capsTagName + 'Width'];
|
335
|
+
}
|
336
|
+
|
337
|
+
if (t.options[tagType + 'Height'] > 0 || t.options[tagType + 'Height'].toString().indexOf('%') > -1) {
|
338
|
+
t.height = t.options[tagType + 'Height'];
|
339
|
+
} else if (t.media.style.height !== '' && t.media.style.height !== null) {
|
340
|
+
t.height = t.media.style.height;
|
341
|
+
} else if (t.$media[0].getAttribute('height') !== null) {
|
342
|
+
t.height = t.$media.attr('height');
|
343
|
+
} else {
|
344
|
+
t.height = t.options['default' + capsTagName + 'Height'];
|
345
|
+
}
|
346
|
+
|
347
|
+
// set the size, while we wait for the plugins to load below
|
348
|
+
t.setPlayerSize(t.width, t.height);
|
349
|
+
|
350
|
+
// create MediaElementShim
|
351
|
+
meOptions.pluginWidth = t.height;
|
352
|
+
meOptions.pluginHeight = t.width;
|
353
|
+
}
|
354
|
+
|
355
|
+
|
356
|
+
|
357
|
+
// create MediaElement shim
|
358
|
+
mejs.MediaElement(t.$media[0], meOptions);
|
359
|
+
|
360
|
+
// controls are shown when loaded
|
361
|
+
t.container.trigger('controlsshown');
|
362
|
+
},
|
363
|
+
|
364
|
+
showControls: function(doAnimation) {
|
365
|
+
var t = this;
|
366
|
+
|
367
|
+
doAnimation = typeof doAnimation == 'undefined' || doAnimation;
|
368
|
+
|
369
|
+
if (t.controlsAreVisible)
|
370
|
+
return;
|
371
|
+
|
372
|
+
if (doAnimation) {
|
373
|
+
t.controls
|
374
|
+
.css('visibility','visible')
|
375
|
+
.stop(true, true).fadeIn(200, function() {
|
376
|
+
t.controlsAreVisible = true;
|
377
|
+
t.container.trigger('controlsshown');
|
378
|
+
});
|
379
|
+
|
380
|
+
// any additional controls people might add and want to hide
|
381
|
+
t.container.find('.mejs-control')
|
382
|
+
.css('visibility','visible')
|
383
|
+
.stop(true, true).fadeIn(200, function() {t.controlsAreVisible = true;});
|
384
|
+
|
385
|
+
} else {
|
386
|
+
t.controls
|
387
|
+
.css('visibility','visible')
|
388
|
+
.css('display','block');
|
389
|
+
|
390
|
+
// any additional controls people might add and want to hide
|
391
|
+
t.container.find('.mejs-control')
|
392
|
+
.css('visibility','visible')
|
393
|
+
.css('display','block');
|
394
|
+
|
395
|
+
t.controlsAreVisible = true;
|
396
|
+
t.container.trigger('controlsshown');
|
397
|
+
}
|
398
|
+
|
399
|
+
t.setControlsSize();
|
400
|
+
|
401
|
+
},
|
402
|
+
|
403
|
+
hideControls: function(doAnimation) {
|
404
|
+
var t = this;
|
405
|
+
|
406
|
+
doAnimation = typeof doAnimation == 'undefined' || doAnimation;
|
407
|
+
|
408
|
+
if (!t.controlsAreVisible)
|
409
|
+
return;
|
410
|
+
|
411
|
+
if (doAnimation) {
|
412
|
+
// fade out main controls
|
413
|
+
t.controls.stop(true, true).fadeOut(200, function() {
|
414
|
+
$(this)
|
415
|
+
.css('visibility','hidden')
|
416
|
+
.css('display','block');
|
417
|
+
|
418
|
+
t.controlsAreVisible = false;
|
419
|
+
t.container.trigger('controlshidden');
|
420
|
+
});
|
421
|
+
|
422
|
+
// any additional controls people might add and want to hide
|
423
|
+
t.container.find('.mejs-control').stop(true, true).fadeOut(200, function() {
|
424
|
+
$(this)
|
425
|
+
.css('visibility','hidden')
|
426
|
+
.css('display','block');
|
427
|
+
});
|
428
|
+
} else {
|
429
|
+
|
430
|
+
// hide main controls
|
431
|
+
t.controls
|
432
|
+
.css('visibility','hidden')
|
433
|
+
.css('display','block');
|
434
|
+
|
435
|
+
// hide others
|
436
|
+
t.container.find('.mejs-control')
|
437
|
+
.css('visibility','hidden')
|
438
|
+
.css('display','block');
|
439
|
+
|
440
|
+
t.controlsAreVisible = false;
|
441
|
+
t.container.trigger('controlshidden');
|
442
|
+
}
|
443
|
+
},
|
444
|
+
|
445
|
+
controlsTimer: null,
|
446
|
+
|
447
|
+
startControlsTimer: function(timeout) {
|
448
|
+
|
449
|
+
var t = this;
|
450
|
+
|
451
|
+
timeout = typeof timeout != 'undefined' ? timeout : 1500;
|
452
|
+
|
453
|
+
t.killControlsTimer('start');
|
454
|
+
|
455
|
+
t.controlsTimer = setTimeout(function() {
|
456
|
+
//console.log('timer fired');
|
457
|
+
t.hideControls();
|
458
|
+
t.killControlsTimer('hide');
|
459
|
+
}, timeout);
|
460
|
+
},
|
461
|
+
|
462
|
+
killControlsTimer: function(src) {
|
463
|
+
|
464
|
+
var t = this;
|
465
|
+
|
466
|
+
if (t.controlsTimer !== null) {
|
467
|
+
clearTimeout(t.controlsTimer);
|
468
|
+
delete t.controlsTimer;
|
469
|
+
t.controlsTimer = null;
|
470
|
+
}
|
471
|
+
},
|
472
|
+
|
473
|
+
controlsEnabled: true,
|
474
|
+
|
475
|
+
disableControls: function() {
|
476
|
+
var t= this;
|
477
|
+
|
478
|
+
t.killControlsTimer();
|
479
|
+
t.hideControls(false);
|
480
|
+
this.controlsEnabled = false;
|
481
|
+
},
|
482
|
+
|
483
|
+
enableControls: function() {
|
484
|
+
var t= this;
|
485
|
+
|
486
|
+
t.showControls(false);
|
487
|
+
|
488
|
+
t.controlsEnabled = true;
|
489
|
+
},
|
490
|
+
|
491
|
+
|
492
|
+
// Sets up all controls and events
|
493
|
+
meReady: function(media, domNode) {
|
494
|
+
|
495
|
+
|
496
|
+
var t = this,
|
497
|
+
mf = mejs.MediaFeatures,
|
498
|
+
autoplayAttr = domNode.getAttribute('autoplay'),
|
499
|
+
autoplay = !(typeof autoplayAttr == 'undefined' || autoplayAttr === null || autoplayAttr === 'false'),
|
500
|
+
featureIndex,
|
501
|
+
feature;
|
502
|
+
|
503
|
+
// make sure it can't create itself again if a plugin reloads
|
504
|
+
if (t.created)
|
505
|
+
return;
|
506
|
+
else
|
507
|
+
t.created = true;
|
508
|
+
|
509
|
+
t.media = media;
|
510
|
+
t.domNode = domNode;
|
511
|
+
|
512
|
+
if (!(mf.isAndroid && t.options.AndroidUseNativeControls) && !(mf.isiPad && t.options.iPadUseNativeControls) && !(mf.isiPhone && t.options.iPhoneUseNativeControls)) {
|
513
|
+
|
514
|
+
// two built in features
|
515
|
+
t.buildposter(t, t.controls, t.layers, t.media);
|
516
|
+
t.buildkeyboard(t, t.controls, t.layers, t.media);
|
517
|
+
t.buildoverlays(t, t.controls, t.layers, t.media);
|
518
|
+
|
519
|
+
// grab for use by features
|
520
|
+
t.findTracks();
|
521
|
+
|
522
|
+
// add user-defined features/controls
|
523
|
+
for (featureIndex in t.options.features) {
|
524
|
+
feature = t.options.features[featureIndex];
|
525
|
+
if (t['build' + feature]) {
|
526
|
+
try {
|
527
|
+
t['build' + feature](t, t.controls, t.layers, t.media);
|
528
|
+
} catch (e) {
|
529
|
+
// TODO: report control error
|
530
|
+
//throw e;
|
531
|
+
//console.log('error building ' + feature);
|
532
|
+
//console.log(e);
|
533
|
+
}
|
534
|
+
}
|
535
|
+
}
|
536
|
+
|
537
|
+
t.container.trigger('controlsready');
|
538
|
+
|
539
|
+
// reset all layers and controls
|
540
|
+
t.setPlayerSize(t.width, t.height);
|
541
|
+
t.setControlsSize();
|
542
|
+
|
543
|
+
|
544
|
+
// controls fade
|
545
|
+
if (t.isVideo) {
|
546
|
+
|
547
|
+
if (mejs.MediaFeatures.hasTouch) {
|
548
|
+
|
549
|
+
// for touch devices (iOS, Android)
|
550
|
+
// show/hide without animation on touch
|
551
|
+
|
552
|
+
t.$media.bind('touchstart', function() {
|
553
|
+
|
554
|
+
|
555
|
+
// toggle controls
|
556
|
+
if (t.controlsAreVisible) {
|
557
|
+
t.hideControls(false);
|
558
|
+
} else {
|
559
|
+
if (t.controlsEnabled) {
|
560
|
+
t.showControls(false);
|
561
|
+
}
|
562
|
+
}
|
563
|
+
});
|
564
|
+
|
565
|
+
} else {
|
566
|
+
// click to play/pause
|
567
|
+
t.media.addEventListener('click', function() {
|
568
|
+
if (t.options.clickToPlayPause) {
|
569
|
+
if (t.media.paused) {
|
570
|
+
t.media.play();
|
571
|
+
} else {
|
572
|
+
t.media.pause();
|
573
|
+
}
|
574
|
+
}
|
575
|
+
});
|
576
|
+
|
577
|
+
// show/hide controls
|
578
|
+
t.container
|
579
|
+
.bind('mouseenter mouseover', function () {
|
580
|
+
if (t.controlsEnabled) {
|
581
|
+
if (!t.options.alwaysShowControls) {
|
582
|
+
t.killControlsTimer('enter');
|
583
|
+
t.showControls();
|
584
|
+
t.startControlsTimer(2500);
|
585
|
+
}
|
586
|
+
}
|
587
|
+
})
|
588
|
+
.bind('mousemove', function() {
|
589
|
+
if (t.controlsEnabled) {
|
590
|
+
if (!t.controlsAreVisible) {
|
591
|
+
t.showControls();
|
592
|
+
}
|
593
|
+
//t.killControlsTimer('move');
|
594
|
+
if (!t.options.alwaysShowControls) {
|
595
|
+
t.startControlsTimer(2500);
|
596
|
+
}
|
597
|
+
}
|
598
|
+
})
|
599
|
+
.bind('mouseleave', function () {
|
600
|
+
if (t.controlsEnabled) {
|
601
|
+
if (!t.media.paused && !t.options.alwaysShowControls) {
|
602
|
+
t.startControlsTimer(1000);
|
603
|
+
}
|
604
|
+
}
|
605
|
+
});
|
606
|
+
}
|
607
|
+
|
608
|
+
// check for autoplay
|
609
|
+
if (autoplay && !t.options.alwaysShowControls) {
|
610
|
+
t.hideControls();
|
611
|
+
}
|
612
|
+
|
613
|
+
// resizer
|
614
|
+
if (t.options.enableAutosize) {
|
615
|
+
t.media.addEventListener('loadedmetadata', function(e) {
|
616
|
+
// if the <video height> was not set and the options.videoHeight was not set
|
617
|
+
// then resize to the real dimensions
|
618
|
+
if (t.options.videoHeight <= 0 && t.domNode.getAttribute('height') === null && !isNaN(e.target.videoHeight)) {
|
619
|
+
t.setPlayerSize(e.target.videoWidth, e.target.videoHeight);
|
620
|
+
t.setControlsSize();
|
621
|
+
t.media.setVideoSize(e.target.videoWidth, e.target.videoHeight);
|
622
|
+
}
|
623
|
+
}, false);
|
624
|
+
}
|
625
|
+
}
|
626
|
+
|
627
|
+
// EVENTS
|
628
|
+
|
629
|
+
// FOCUS: when a video starts playing, it takes focus from other players (possibily pausing them)
|
630
|
+
media.addEventListener('play', function() {
|
631
|
+
|
632
|
+
// go through all other players
|
633
|
+
for (var i=0, il=mejs.players.length; i<il; i++) {
|
634
|
+
var p = mejs.players[i];
|
635
|
+
if (p.id != t.id && t.options.pauseOtherPlayers && !p.paused && !p.ended) {
|
636
|
+
p.pause();
|
637
|
+
}
|
638
|
+
p.hasFocus = false;
|
639
|
+
}
|
640
|
+
|
641
|
+
t.hasFocus = true;
|
642
|
+
},false);
|
643
|
+
|
644
|
+
|
645
|
+
// ended for all
|
646
|
+
t.media.addEventListener('ended', function (e) {
|
647
|
+
if(t.options.autoRewind) {
|
648
|
+
try{
|
649
|
+
t.media.setCurrentTime(0);
|
650
|
+
} catch (exp) {
|
651
|
+
|
652
|
+
}
|
653
|
+
}
|
654
|
+
t.media.pause();
|
655
|
+
|
656
|
+
if (t.setProgressRail)
|
657
|
+
t.setProgressRail();
|
658
|
+
if (t.setCurrentRail)
|
659
|
+
t.setCurrentRail();
|
660
|
+
|
661
|
+
if (t.options.loop) {
|
662
|
+
t.media.play();
|
663
|
+
} else if (!t.options.alwaysShowControls && t.controlsEnabled) {
|
664
|
+
t.showControls();
|
665
|
+
}
|
666
|
+
}, false);
|
667
|
+
|
668
|
+
// resize on the first play
|
669
|
+
t.media.addEventListener('loadedmetadata', function(e) {
|
670
|
+
if (t.updateDuration) {
|
671
|
+
t.updateDuration();
|
672
|
+
}
|
673
|
+
if (t.updateCurrent) {
|
674
|
+
t.updateCurrent();
|
675
|
+
}
|
676
|
+
|
677
|
+
if (!t.isFullScreen) {
|
678
|
+
t.setPlayerSize(t.width, t.height);
|
679
|
+
t.setControlsSize();
|
680
|
+
}
|
681
|
+
}, false);
|
682
|
+
|
683
|
+
|
684
|
+
// webkit has trouble doing this without a delay
|
685
|
+
setTimeout(function () {
|
686
|
+
t.setPlayerSize(t.width, t.height);
|
687
|
+
t.setControlsSize();
|
688
|
+
}, 50);
|
689
|
+
|
690
|
+
// adjust controls whenever window sizes (used to be in fullscreen only)
|
691
|
+
$(window).resize(function() {
|
692
|
+
|
693
|
+
// don't resize for fullscreen mode
|
694
|
+
if ( !(t.isFullScreen || (mejs.MediaFeatures.hasTrueNativeFullScreen && document.webkitIsFullScreen)) ) {
|
695
|
+
t.setPlayerSize(t.width, t.height);
|
696
|
+
}
|
697
|
+
|
698
|
+
// always adjust controls
|
699
|
+
t.setControlsSize();
|
700
|
+
});
|
701
|
+
|
702
|
+
// TEMP: needs to be moved somewhere else
|
703
|
+
if (t.media.pluginType == 'youtube') {
|
704
|
+
t.container.find('.mejs-overlay-play').hide();
|
705
|
+
}
|
706
|
+
}
|
707
|
+
|
708
|
+
// force autoplay for HTML5
|
709
|
+
if (autoplay && media.pluginType == 'native') {
|
710
|
+
media.load();
|
711
|
+
media.play();
|
712
|
+
}
|
713
|
+
|
714
|
+
|
715
|
+
if (t.options.success) {
|
716
|
+
|
717
|
+
if (typeof t.options.success == 'string') {
|
718
|
+
window[t.options.success](t.media, t.domNode, t);
|
719
|
+
} else {
|
720
|
+
t.options.success(t.media, t.domNode, t);
|
721
|
+
}
|
722
|
+
}
|
723
|
+
},
|
724
|
+
|
725
|
+
handleError: function(e) {
|
726
|
+
var t = this;
|
727
|
+
|
728
|
+
t.controls.hide();
|
729
|
+
|
730
|
+
// Tell user that the file cannot be played
|
731
|
+
if (t.options.error) {
|
732
|
+
t.options.error(e);
|
733
|
+
}
|
734
|
+
},
|
735
|
+
|
736
|
+
setPlayerSize: function(width,height) {
|
737
|
+
var t = this;
|
738
|
+
|
739
|
+
if (typeof width != 'undefined')
|
740
|
+
t.width = width;
|
741
|
+
|
742
|
+
if (typeof height != 'undefined')
|
743
|
+
t.height = height;
|
744
|
+
|
745
|
+
// detect 100% mode - use currentStyle for IE since css() doesn't return percentages
|
746
|
+
if (t.height.toString().indexOf('%') > 0 || t.$node.css('max-width') === '100%' || (t.$node[0].currentStyle && t.$node[0].currentStyle.maxWidth === '100%')) {
|
747
|
+
|
748
|
+
// do we have the native dimensions yet?
|
749
|
+
var
|
750
|
+
nativeWidth = t.isVideo ? ((t.media.videoWidth && t.media.videoWidth > 0) ? t.media.videoWidth : t.options.defaultVideoWidth) : t.options.defaultAudioWidth,
|
751
|
+
nativeHeight = t.isVideo ? ((t.media.videoHeight && t.media.videoHeight > 0) ? t.media.videoHeight : t.options.defaultVideoHeight) : t.options.defaultAudioHeight,
|
752
|
+
parentWidth = t.container.parent().closest(':visible').width(),
|
753
|
+
newHeight = t.isVideo || !t.options.autosizeProgress ? parseInt(parentWidth * nativeHeight/nativeWidth, 10) : nativeHeight;
|
754
|
+
|
755
|
+
if (t.container.parent()[0].tagName.toLowerCase() === 'body') { // && t.container.siblings().count == 0) {
|
756
|
+
parentWidth = $(window).width();
|
757
|
+
newHeight = $(window).height();
|
758
|
+
}
|
759
|
+
|
760
|
+
if ( newHeight != 0 && parentWidth != 0 ) {
|
761
|
+
// set outer container size
|
762
|
+
t.container
|
763
|
+
.width(parentWidth)
|
764
|
+
.height(newHeight);
|
765
|
+
|
766
|
+
// set native <video> or <audio>
|
767
|
+
t.$media
|
768
|
+
.width('100%')
|
769
|
+
.height('100%');
|
770
|
+
|
771
|
+
// set shims
|
772
|
+
t.container.find('object, embed, iframe')
|
773
|
+
.width('100%')
|
774
|
+
.height('100%');
|
775
|
+
|
776
|
+
// if shim is ready, send the size to the embeded plugin
|
777
|
+
if (t.isVideo) {
|
778
|
+
if (t.media.setVideoSize) {
|
779
|
+
t.media.setVideoSize(parentWidth, newHeight);
|
780
|
+
}
|
781
|
+
}
|
782
|
+
|
783
|
+
// set the layers
|
784
|
+
t.layers.children('.mejs-layer')
|
785
|
+
.width('100%')
|
786
|
+
.height('100%');
|
787
|
+
}
|
788
|
+
|
789
|
+
|
790
|
+
} else {
|
791
|
+
|
792
|
+
t.container
|
793
|
+
.width(t.width)
|
794
|
+
.height(t.height);
|
795
|
+
|
796
|
+
t.layers.children('.mejs-layer')
|
797
|
+
.width(t.width)
|
798
|
+
.height(t.height);
|
799
|
+
|
800
|
+
}
|
801
|
+
},
|
802
|
+
|
803
|
+
setControlsSize: function() {
|
804
|
+
var t = this,
|
805
|
+
usedWidth = 0,
|
806
|
+
railWidth = 0,
|
807
|
+
rail = t.controls.find('.mejs-time-rail'),
|
808
|
+
total = t.controls.find('.mejs-time-total'),
|
809
|
+
current = t.controls.find('.mejs-time-current'),
|
810
|
+
loaded = t.controls.find('.mejs-time-loaded'),
|
811
|
+
others = rail.siblings();
|
812
|
+
|
813
|
+
|
814
|
+
// allow the size to come from custom CSS
|
815
|
+
if (t.options && !t.options.autosizeProgress) {
|
816
|
+
// Also, frontends devs can be more flexible
|
817
|
+
// due the opportunity of absolute positioning.
|
818
|
+
railWidth = parseInt(rail.css('width'));
|
819
|
+
}
|
820
|
+
|
821
|
+
// attempt to autosize
|
822
|
+
if (railWidth === 0 || !railWidth) {
|
823
|
+
|
824
|
+
// find the size of all the other controls besides the rail
|
825
|
+
others.each(function() {
|
826
|
+
if ($(this).css('position') != 'absolute') {
|
827
|
+
usedWidth += $(this).outerWidth(true);
|
828
|
+
}
|
829
|
+
});
|
830
|
+
|
831
|
+
// fit the rail into the remaining space
|
832
|
+
railWidth = t.controls.width() - usedWidth - (rail.outerWidth(true) - rail.width());
|
833
|
+
}
|
834
|
+
|
835
|
+
// outer area
|
836
|
+
rail.width(railWidth);
|
837
|
+
// dark space
|
838
|
+
total.width(railWidth - (total.outerWidth(true) - total.width()));
|
839
|
+
|
840
|
+
if (t.setProgressRail)
|
841
|
+
t.setProgressRail();
|
842
|
+
if (t.setCurrentRail)
|
843
|
+
t.setCurrentRail();
|
844
|
+
},
|
845
|
+
|
846
|
+
|
847
|
+
buildposter: function(player, controls, layers, media) {
|
848
|
+
var t = this,
|
849
|
+
poster =
|
850
|
+
$('<div class="mejs-poster mejs-layer">' +
|
851
|
+
'</div>')
|
852
|
+
.appendTo(layers),
|
853
|
+
posterUrl = player.$media.attr('poster');
|
854
|
+
|
855
|
+
// prioriy goes to option (this is useful if you need to support iOS 3.x (iOS completely fails with poster)
|
856
|
+
if (player.options.poster !== '') {
|
857
|
+
posterUrl = player.options.poster;
|
858
|
+
}
|
859
|
+
|
860
|
+
// second, try the real poster
|
861
|
+
if (posterUrl !== '' && posterUrl != null) {
|
862
|
+
t.setPoster(posterUrl);
|
863
|
+
} else {
|
864
|
+
poster.hide();
|
865
|
+
}
|
866
|
+
|
867
|
+
media.addEventListener('play',function() {
|
868
|
+
poster.hide();
|
869
|
+
}, false);
|
870
|
+
},
|
871
|
+
|
872
|
+
setPoster: function(url) {
|
873
|
+
var t = this,
|
874
|
+
posterDiv = t.container.find('.mejs-poster'),
|
875
|
+
posterImg = posterDiv.find('img');
|
876
|
+
|
877
|
+
if (posterImg.length == 0) {
|
878
|
+
posterImg = $('<img width="100%" height="100%" />').appendTo(posterDiv);
|
879
|
+
}
|
880
|
+
|
881
|
+
posterImg.attr('src', url);
|
882
|
+
},
|
883
|
+
|
884
|
+
buildoverlays: function(player, controls, layers, media) {
|
885
|
+
var t = this;
|
886
|
+
if (!player.isVideo)
|
887
|
+
return;
|
888
|
+
|
889
|
+
var
|
890
|
+
loading =
|
891
|
+
$('<div class="mejs-overlay mejs-layer">'+
|
892
|
+
'<div class="mejs-overlay-loading"><span></span></div>'+
|
893
|
+
'</div>')
|
894
|
+
.hide() // start out hidden
|
895
|
+
.appendTo(layers),
|
896
|
+
error =
|
897
|
+
$('<div class="mejs-overlay mejs-layer">'+
|
898
|
+
'<div class="mejs-overlay-error"></div>'+
|
899
|
+
'</div>')
|
900
|
+
.hide() // start out hidden
|
901
|
+
.appendTo(layers),
|
902
|
+
// this needs to come last so it's on top
|
903
|
+
bigPlay =
|
904
|
+
$('<div class="mejs-overlay mejs-layer mejs-overlay-play">'+
|
905
|
+
'<div class="mejs-overlay-button"></div>'+
|
906
|
+
'</div>')
|
907
|
+
.appendTo(layers)
|
908
|
+
.click(function() {
|
909
|
+
if (t.options.clickToPlayPause) {
|
910
|
+
if (media.paused) {
|
911
|
+
media.play();
|
912
|
+
} else {
|
913
|
+
media.pause();
|
914
|
+
}
|
915
|
+
}
|
916
|
+
});
|
917
|
+
|
918
|
+
/*
|
919
|
+
if (mejs.MediaFeatures.isiOS || mejs.MediaFeatures.isAndroid) {
|
920
|
+
bigPlay.remove();
|
921
|
+
loading.remove();
|
922
|
+
}
|
923
|
+
*/
|
924
|
+
|
925
|
+
|
926
|
+
// show/hide big play button
|
927
|
+
media.addEventListener('play',function() {
|
928
|
+
bigPlay.hide();
|
929
|
+
loading.hide();
|
930
|
+
controls.find('.mejs-time-buffering').hide();
|
931
|
+
error.hide();
|
932
|
+
}, false);
|
933
|
+
|
934
|
+
media.addEventListener('playing', function() {
|
935
|
+
bigPlay.hide();
|
936
|
+
loading.hide();
|
937
|
+
controls.find('.mejs-time-buffering').hide();
|
938
|
+
error.hide();
|
939
|
+
}, false);
|
940
|
+
|
941
|
+
media.addEventListener('seeking', function() {
|
942
|
+
loading.show();
|
943
|
+
controls.find('.mejs-time-buffering').show();
|
944
|
+
}, false);
|
945
|
+
|
946
|
+
media.addEventListener('seeked', function() {
|
947
|
+
loading.hide();
|
948
|
+
controls.find('.mejs-time-buffering').hide();
|
949
|
+
}, false);
|
950
|
+
|
951
|
+
media.addEventListener('pause',function() {
|
952
|
+
if (!mejs.MediaFeatures.isiPhone) {
|
953
|
+
bigPlay.show();
|
954
|
+
}
|
955
|
+
}, false);
|
956
|
+
|
957
|
+
media.addEventListener('waiting', function() {
|
958
|
+
loading.show();
|
959
|
+
controls.find('.mejs-time-buffering').show();
|
960
|
+
}, false);
|
961
|
+
|
962
|
+
|
963
|
+
// show/hide loading
|
964
|
+
media.addEventListener('loadeddata',function() {
|
965
|
+
// for some reason Chrome is firing this event
|
966
|
+
//if (mejs.MediaFeatures.isChrome && media.getAttribute && media.getAttribute('preload') === 'none')
|
967
|
+
// return;
|
968
|
+
|
969
|
+
loading.show();
|
970
|
+
controls.find('.mejs-time-buffering').show();
|
971
|
+
}, false);
|
972
|
+
media.addEventListener('canplay',function() {
|
973
|
+
loading.hide();
|
974
|
+
controls.find('.mejs-time-buffering').hide();
|
975
|
+
}, false);
|
976
|
+
|
977
|
+
// error handling
|
978
|
+
media.addEventListener('error',function() {
|
979
|
+
loading.hide();
|
980
|
+
controls.find('.mejs-time-buffering').hide();
|
981
|
+
error.show();
|
982
|
+
error.find('mejs-overlay-error').html("Error loading this resource");
|
983
|
+
}, false);
|
984
|
+
},
|
985
|
+
|
986
|
+
buildkeyboard: function(player, controls, layers, media) {
|
987
|
+
|
988
|
+
var t = this;
|
989
|
+
|
990
|
+
// listen for key presses
|
991
|
+
$(document).keydown(function(e) {
|
992
|
+
|
993
|
+
if (player.hasFocus && player.options.enableKeyboard) {
|
994
|
+
|
995
|
+
// find a matching key
|
996
|
+
for (var i=0, il=player.options.keyActions.length; i<il; i++) {
|
997
|
+
var keyAction = player.options.keyActions[i];
|
998
|
+
|
999
|
+
for (var j=0, jl=keyAction.keys.length; j<jl; j++) {
|
1000
|
+
if (e.keyCode == keyAction.keys[j]) {
|
1001
|
+
e.preventDefault();
|
1002
|
+
keyAction.action(player, media, e.keyCode);
|
1003
|
+
return false;
|
1004
|
+
}
|
1005
|
+
}
|
1006
|
+
}
|
1007
|
+
}
|
1008
|
+
|
1009
|
+
return true;
|
1010
|
+
});
|
1011
|
+
|
1012
|
+
// check if someone clicked outside a player region, then kill its focus
|
1013
|
+
$(document).click(function(event) {
|
1014
|
+
if ($(event.target).closest('.mejs-container').length == 0) {
|
1015
|
+
player.hasFocus = false;
|
1016
|
+
}
|
1017
|
+
});
|
1018
|
+
|
1019
|
+
},
|
1020
|
+
|
1021
|
+
findTracks: function() {
|
1022
|
+
var t = this,
|
1023
|
+
tracktags = t.$media.find('track');
|
1024
|
+
|
1025
|
+
// store for use by plugins
|
1026
|
+
t.tracks = [];
|
1027
|
+
tracktags.each(function(index, track) {
|
1028
|
+
|
1029
|
+
track = $(track);
|
1030
|
+
|
1031
|
+
t.tracks.push({
|
1032
|
+
srclang: track.attr('srclang').toLowerCase(),
|
1033
|
+
src: track.attr('src'),
|
1034
|
+
kind: track.attr('kind'),
|
1035
|
+
label: track.attr('label') || '',
|
1036
|
+
entries: [],
|
1037
|
+
isLoaded: false
|
1038
|
+
});
|
1039
|
+
});
|
1040
|
+
},
|
1041
|
+
changeSkin: function(className) {
|
1042
|
+
this.container[0].className = 'mejs-container ' + className;
|
1043
|
+
this.setPlayerSize(this.width, this.height);
|
1044
|
+
this.setControlsSize();
|
1045
|
+
},
|
1046
|
+
play: function() {
|
1047
|
+
this.media.play();
|
1048
|
+
},
|
1049
|
+
pause: function() {
|
1050
|
+
this.media.pause();
|
1051
|
+
},
|
1052
|
+
load: function() {
|
1053
|
+
this.media.load();
|
1054
|
+
},
|
1055
|
+
setMuted: function(muted) {
|
1056
|
+
this.media.setMuted(muted);
|
1057
|
+
},
|
1058
|
+
setCurrentTime: function(time) {
|
1059
|
+
this.media.setCurrentTime(time);
|
1060
|
+
},
|
1061
|
+
getCurrentTime: function() {
|
1062
|
+
return this.media.currentTime;
|
1063
|
+
},
|
1064
|
+
setVolume: function(volume) {
|
1065
|
+
this.media.setVolume(volume);
|
1066
|
+
},
|
1067
|
+
getVolume: function() {
|
1068
|
+
return this.media.volume;
|
1069
|
+
},
|
1070
|
+
setSrc: function(src) {
|
1071
|
+
this.media.setSrc(src);
|
1072
|
+
},
|
1073
|
+
remove: function() {
|
1074
|
+
var t = this;
|
1075
|
+
|
1076
|
+
if (t.media.pluginType === 'flash') {
|
1077
|
+
t.media.remove();
|
1078
|
+
} else if (t.media.pluginType === 'native') {
|
1079
|
+
t.$media.prop('controls', true);
|
1080
|
+
}
|
1081
|
+
|
1082
|
+
// grab video and put it back in place
|
1083
|
+
if (!t.isDynamic) {
|
1084
|
+
t.$node.insertBefore(t.container)
|
1085
|
+
}
|
1086
|
+
|
1087
|
+
t.container.remove();
|
1088
|
+
}
|
1089
|
+
};
|
1090
|
+
|
1091
|
+
// turn into jQuery plugin
|
1092
|
+
if (typeof jQuery != 'undefined') {
|
1093
|
+
jQuery.fn.mediaelementplayer = function (options) {
|
1094
|
+
return this.each(function () {
|
1095
|
+
new mejs.MediaElementPlayer(this, options);
|
1096
|
+
});
|
1097
|
+
};
|
1098
|
+
}
|
1099
|
+
|
1100
|
+
$(document).ready(function() {
|
1101
|
+
// auto enable using JSON attribute
|
1102
|
+
$('.mejs-player').mediaelementplayer();
|
1103
|
+
});
|
1104
|
+
|
1105
|
+
// push out to window
|
1106
|
+
window.MediaElementPlayer = mejs.MediaElementPlayer;
|
1107
|
+
|
1108
|
+
})(mejs.$);
|
1093
1109
|
|
1094
1110
|
(function($) {
|
1095
1111
|
|
@@ -1157,7 +1173,8 @@ if (typeof jQuery != 'undefined') {
|
|
1157
1173
|
media.pause();
|
1158
1174
|
}
|
1159
1175
|
if (media.currentTime > 0) {
|
1160
|
-
media.setCurrentTime(0);
|
1176
|
+
media.setCurrentTime(0);
|
1177
|
+
media.pause();
|
1161
1178
|
controls.find('.mejs-time-current').width('0px');
|
1162
1179
|
controls.find('.mejs-time-handle').css('left', '0px');
|
1163
1180
|
controls.find('.mejs-time-float-current').html( mejs.Utility.secondsToTimeCode(0) );
|
@@ -1201,18 +1218,25 @@ if (typeof jQuery != 'undefined') {
|
|
1201
1218
|
// mouse position relative to the object
|
1202
1219
|
var x = e.pageX,
|
1203
1220
|
offset = total.offset(),
|
1204
|
-
width = total.outerWidth(),
|
1221
|
+
width = total.outerWidth(true),
|
1205
1222
|
percentage = 0,
|
1206
1223
|
newTime = 0,
|
1207
|
-
pos =
|
1224
|
+
pos = 0;
|
1208
1225
|
|
1209
1226
|
|
1210
|
-
if (
|
1211
|
-
|
1227
|
+
if (media.duration) {
|
1228
|
+
if (x < offset.left) {
|
1229
|
+
x = offset.left;
|
1230
|
+
} else if (x > width + offset.left) {
|
1231
|
+
x = width + offset.left;
|
1232
|
+
}
|
1233
|
+
|
1234
|
+
pos = x - offset.left;
|
1235
|
+
percentage = (pos / width);
|
1212
1236
|
newTime = (percentage <= 0.02) ? 0 : percentage * media.duration;
|
1213
1237
|
|
1214
1238
|
// seek to where the mouse is
|
1215
|
-
if (mouseIsDown) {
|
1239
|
+
if (mouseIsDown && newTime !== media.currentTime) {
|
1216
1240
|
media.setCurrentTime(newTime);
|
1217
1241
|
}
|
1218
1242
|
|
@@ -1336,86 +1360,90 @@ if (typeof jQuery != 'undefined') {
|
|
1336
1360
|
}
|
1337
1361
|
});
|
1338
1362
|
})(mejs.$);
|
1339
|
-
|
1340
|
-
|
1341
|
-
|
1342
|
-
|
1343
|
-
|
1344
|
-
|
1345
|
-
|
1346
|
-
|
1347
|
-
|
1348
|
-
|
1349
|
-
|
1350
|
-
|
1351
|
-
|
1352
|
-
|
1353
|
-
|
1354
|
-
|
1355
|
-
+ (player.options.
|
1356
|
-
'</
|
1357
|
-
|
1358
|
-
|
1359
|
-
|
1360
|
-
|
1361
|
-
|
1362
|
-
|
1363
|
-
|
1364
|
-
|
1365
|
-
|
1366
|
-
|
1367
|
-
|
1368
|
-
|
1369
|
-
|
1370
|
-
|
1371
|
-
|
1372
|
-
|
1373
|
-
|
1374
|
-
|
1375
|
-
|
1376
|
-
|
1377
|
-
|
1378
|
-
|
1379
|
-
|
1380
|
-
|
1381
|
-
|
1382
|
-
|
1383
|
-
|
1384
|
-
|
1385
|
-
|
1386
|
-
|
1387
|
-
|
1388
|
-
|
1389
|
-
|
1390
|
-
|
1391
|
-
|
1392
|
-
|
1393
|
-
|
1394
|
-
|
1395
|
-
|
1396
|
-
|
1397
|
-
|
1398
|
-
|
1399
|
-
|
1400
|
-
|
1401
|
-
|
1402
|
-
|
1403
|
-
|
1404
|
-
|
1405
|
-
|
1406
|
-
|
1407
|
-
|
1408
|
-
|
1409
|
-
|
1410
|
-
|
1411
|
-
|
1412
|
-
|
1413
|
-
|
1414
|
-
|
1415
|
-
|
1416
|
-
|
1417
|
-
|
1418
|
-
|
1363
|
+
|
1364
|
+
(function($) {
|
1365
|
+
|
1366
|
+
// options
|
1367
|
+
$.extend(mejs.MepDefaults, {
|
1368
|
+
duration: -1,
|
1369
|
+
timeAndDurationSeparator: ' <span> | </span> '
|
1370
|
+
});
|
1371
|
+
|
1372
|
+
|
1373
|
+
// current and duration 00:00 / 00:00
|
1374
|
+
$.extend(MediaElementPlayer.prototype, {
|
1375
|
+
buildcurrent: function(player, controls, layers, media) {
|
1376
|
+
var t = this;
|
1377
|
+
|
1378
|
+
$('<div class="mejs-time">'+
|
1379
|
+
'<span class="mejs-currenttime">' + (player.options.alwaysShowHours ? '00:' : '')
|
1380
|
+
+ (player.options.showTimecodeFrameCount? '00:00:00':'00:00')+ '</span>'+
|
1381
|
+
'</div>')
|
1382
|
+
.appendTo(controls);
|
1383
|
+
|
1384
|
+
t.currenttime = t.controls.find('.mejs-currenttime');
|
1385
|
+
|
1386
|
+
media.addEventListener('timeupdate',function() {
|
1387
|
+
player.updateCurrent();
|
1388
|
+
}, false);
|
1389
|
+
},
|
1390
|
+
|
1391
|
+
|
1392
|
+
buildduration: function(player, controls, layers, media) {
|
1393
|
+
var t = this;
|
1394
|
+
|
1395
|
+
if (controls.children().last().find('.mejs-currenttime').length > 0) {
|
1396
|
+
$(t.options.timeAndDurationSeparator +
|
1397
|
+
'<span class="mejs-duration">' +
|
1398
|
+
(t.options.duration > 0 ?
|
1399
|
+
mejs.Utility.secondsToTimeCode(t.options.duration, t.options.alwaysShowHours || t.media.duration > 3600, t.options.showTimecodeFrameCount, t.options.framesPerSecond || 25) :
|
1400
|
+
((player.options.alwaysShowHours ? '00:' : '') + (player.options.showTimecodeFrameCount? '00:00:00':'00:00'))
|
1401
|
+
) +
|
1402
|
+
'</span>')
|
1403
|
+
.appendTo(controls.find('.mejs-time'));
|
1404
|
+
} else {
|
1405
|
+
|
1406
|
+
// add class to current time
|
1407
|
+
controls.find('.mejs-currenttime').parent().addClass('mejs-currenttime-container');
|
1408
|
+
|
1409
|
+
$('<div class="mejs-time mejs-duration-container">'+
|
1410
|
+
'<span class="mejs-duration">' +
|
1411
|
+
(t.options.duration > 0 ?
|
1412
|
+
mejs.Utility.secondsToTimeCode(t.options.duration, t.options.alwaysShowHours || t.media.duration > 3600, t.options.showTimecodeFrameCount, t.options.framesPerSecond || 25) :
|
1413
|
+
((player.options.alwaysShowHours ? '00:' : '') + (player.options.showTimecodeFrameCount? '00:00:00':'00:00'))
|
1414
|
+
) +
|
1415
|
+
'</span>' +
|
1416
|
+
'</div>')
|
1417
|
+
.appendTo(controls);
|
1418
|
+
}
|
1419
|
+
|
1420
|
+
t.durationD = t.controls.find('.mejs-duration');
|
1421
|
+
|
1422
|
+
media.addEventListener('timeupdate',function() {
|
1423
|
+
player.updateDuration();
|
1424
|
+
}, false);
|
1425
|
+
},
|
1426
|
+
|
1427
|
+
updateCurrent: function() {
|
1428
|
+
var t = this;
|
1429
|
+
|
1430
|
+
if (t.currenttime) {
|
1431
|
+
t.currenttime.html(mejs.Utility.secondsToTimeCode(t.media.currentTime, t.options.alwaysShowHours || t.media.duration > 3600, t.options.showTimecodeFrameCount, t.options.framesPerSecond || 25));
|
1432
|
+
}
|
1433
|
+
},
|
1434
|
+
|
1435
|
+
updateDuration: function() {
|
1436
|
+
var t = this;
|
1437
|
+
|
1438
|
+
//Toggle the long video class if the video is longer than an hour.
|
1439
|
+
t.container.toggleClass("mejs-long-video", t.media.duration > 3600);
|
1440
|
+
|
1441
|
+
if (t.media.duration && t.durationD) {
|
1442
|
+
t.durationD.html(mejs.Utility.secondsToTimeCode(t.media.duration, t.options.alwaysShowHours, t.options.showTimecodeFrameCount, t.options.framesPerSecond || 25));
|
1443
|
+
}
|
1444
|
+
}
|
1445
|
+
});
|
1446
|
+
|
1419
1447
|
})(mejs.$);
|
1420
1448
|
(function($) {
|
1421
1449
|
|
@@ -1467,7 +1495,7 @@ if (typeof jQuery != 'undefined') {
|
|
1467
1495
|
|
1468
1496
|
positionVolumeHandle = function(volume, secondTry) {
|
1469
1497
|
|
1470
|
-
if (!volumeSlider.is(':visible') && typeof secondTry
|
1498
|
+
if (!volumeSlider.is(':visible') && typeof secondTry == 'undefined') {
|
1471
1499
|
volumeSlider.show();
|
1472
1500
|
positionVolumeHandle(volume, true);
|
1473
1501
|
volumeSlider.hide()
|
@@ -1500,7 +1528,7 @@ if (typeof jQuery != 'undefined') {
|
|
1500
1528
|
newTop = totalHeight - (totalHeight * volume);
|
1501
1529
|
|
1502
1530
|
// handle
|
1503
|
-
volumeHandle.css('top', totalPosition.top + newTop - (volumeHandle.height() / 2));
|
1531
|
+
volumeHandle.css('top', Math.round(totalPosition.top + newTop - (volumeHandle.height() / 2)));
|
1504
1532
|
|
1505
1533
|
// show the current visibility
|
1506
1534
|
volumeCurrent.height(totalHeight - newTop );
|
@@ -1518,10 +1546,10 @@ if (typeof jQuery != 'undefined') {
|
|
1518
1546
|
newLeft = totalWidth * volume;
|
1519
1547
|
|
1520
1548
|
// handle
|
1521
|
-
volumeHandle.css('left', totalPosition.left + newLeft - (volumeHandle.width() / 2));
|
1549
|
+
volumeHandle.css('left', Math.round(totalPosition.left + newLeft - (volumeHandle.width() / 2)));
|
1522
1550
|
|
1523
1551
|
// rezize the current part of the volume bar
|
1524
|
-
volumeCurrent.width( newLeft );
|
1552
|
+
volumeCurrent.width( Math.round(newLeft) );
|
1525
1553
|
}
|
1526
1554
|
},
|
1527
1555
|
handleVolumeMove = function(e) {
|
@@ -1597,485 +1625,485 @@ if (typeof jQuery != 'undefined') {
|
|
1597
1625
|
mouseIsDown = false;
|
1598
1626
|
$(document).unbind('.vol');
|
1599
1627
|
|
1600
|
-
if (!mouseIsOver && mode == 'vertical') {
|
1601
|
-
volumeSlider.hide();
|
1628
|
+
if (!mouseIsOver && mode == 'vertical') {
|
1629
|
+
volumeSlider.hide();
|
1630
|
+
}
|
1631
|
+
});
|
1632
|
+
mouseIsDown = true;
|
1633
|
+
|
1634
|
+
return false;
|
1635
|
+
});
|
1636
|
+
|
1637
|
+
|
1638
|
+
// MUTE button
|
1639
|
+
mute.find('button').click(function() {
|
1640
|
+
media.setMuted( !media.muted );
|
1641
|
+
});
|
1642
|
+
|
1643
|
+
// listen for volume change events from other sources
|
1644
|
+
media.addEventListener('volumechange', function(e) {
|
1645
|
+
if (!mouseIsDown) {
|
1646
|
+
if (media.muted) {
|
1647
|
+
positionVolumeHandle(0);
|
1648
|
+
mute.removeClass('mejs-mute').addClass('mejs-unmute');
|
1649
|
+
} else {
|
1650
|
+
positionVolumeHandle(media.volume);
|
1651
|
+
mute.removeClass('mejs-unmute').addClass('mejs-mute');
|
1652
|
+
}
|
1653
|
+
}
|
1654
|
+
}, false);
|
1655
|
+
|
1656
|
+
if (t.container.is(':visible')) {
|
1657
|
+
// set initial volume
|
1658
|
+
positionVolumeHandle(player.options.startVolume);
|
1659
|
+
|
1660
|
+
// shim gets the startvolume as a parameter, but we have to set it on the native <video> and <audio> elements
|
1661
|
+
if (media.pluginType === 'native') {
|
1662
|
+
media.setVolume(player.options.startVolume);
|
1663
|
+
}
|
1664
|
+
}
|
1665
|
+
}
|
1666
|
+
});
|
1667
|
+
|
1668
|
+
})(mejs.$);
|
1669
|
+
|
1670
|
+
(function($) {
|
1671
|
+
|
1672
|
+
$.extend(mejs.MepDefaults, {
|
1673
|
+
usePluginFullScreen: true,
|
1674
|
+
newWindowCallback: function() { return '';},
|
1675
|
+
fullscreenText: mejs.i18n.t('Fullscreen')
|
1676
|
+
});
|
1677
|
+
|
1678
|
+
$.extend(MediaElementPlayer.prototype, {
|
1679
|
+
|
1680
|
+
isFullScreen: false,
|
1681
|
+
|
1682
|
+
isNativeFullScreen: false,
|
1683
|
+
|
1684
|
+
docStyleOverflow: null,
|
1685
|
+
|
1686
|
+
isInIframe: false,
|
1687
|
+
|
1688
|
+
buildfullscreen: function(player, controls, layers, media) {
|
1689
|
+
|
1690
|
+
if (!player.isVideo)
|
1691
|
+
return;
|
1692
|
+
|
1693
|
+
player.isInIframe = (window.location != window.parent.location);
|
1694
|
+
|
1695
|
+
// native events
|
1696
|
+
if (mejs.MediaFeatures.hasTrueNativeFullScreen) {
|
1697
|
+
|
1698
|
+
// chrome doesn't alays fire this in an iframe
|
1699
|
+
var target = null;
|
1700
|
+
|
1701
|
+
if (mejs.MediaFeatures.hasMozNativeFullScreen) {
|
1702
|
+
target = $(document);
|
1703
|
+
} else {
|
1704
|
+
target = player.container;
|
1705
|
+
}
|
1706
|
+
|
1707
|
+
target.bind(mejs.MediaFeatures.fullScreenEventName, function(e) {
|
1708
|
+
|
1709
|
+
if (mejs.MediaFeatures.isFullScreen()) {
|
1710
|
+
player.isNativeFullScreen = true;
|
1711
|
+
// reset the controls once we are fully in full screen
|
1712
|
+
player.setControlsSize();
|
1713
|
+
} else {
|
1714
|
+
player.isNativeFullScreen = false;
|
1715
|
+
// when a user presses ESC
|
1716
|
+
// make sure to put the player back into place
|
1717
|
+
player.exitFullScreen();
|
1718
|
+
}
|
1719
|
+
});
|
1720
|
+
}
|
1721
|
+
|
1722
|
+
var t = this,
|
1723
|
+
normalHeight = 0,
|
1724
|
+
normalWidth = 0,
|
1725
|
+
container = player.container,
|
1726
|
+
fullscreenBtn =
|
1727
|
+
$('<div class="mejs-button mejs-fullscreen-button">' +
|
1728
|
+
'<button type="button" aria-controls="' + t.id + '" title="' + t.options.fullscreenText + '"></button>' +
|
1729
|
+
'</div>')
|
1730
|
+
.appendTo(controls);
|
1731
|
+
|
1732
|
+
if (t.media.pluginType === 'native' || (!t.options.usePluginFullScreen && !mejs.MediaFeatures.isFirefox)) {
|
1733
|
+
|
1734
|
+
fullscreenBtn.click(function() {
|
1735
|
+
var isFullScreen = (mejs.MediaFeatures.hasTrueNativeFullScreen && mejs.MediaFeatures.isFullScreen()) || player.isFullScreen;
|
1736
|
+
|
1737
|
+
if (isFullScreen) {
|
1738
|
+
player.exitFullScreen();
|
1739
|
+
} else {
|
1740
|
+
player.enterFullScreen();
|
1741
|
+
}
|
1742
|
+
});
|
1743
|
+
|
1744
|
+
} else {
|
1745
|
+
|
1746
|
+
var hideTimeout = null,
|
1747
|
+
supportsPointerEvents = (function() {
|
1748
|
+
// TAKEN FROM MODERNIZR
|
1749
|
+
var element = document.createElement('x'),
|
1750
|
+
documentElement = document.documentElement,
|
1751
|
+
getComputedStyle = window.getComputedStyle,
|
1752
|
+
supports;
|
1753
|
+
if(!('pointerEvents' in element.style)){
|
1754
|
+
return false;
|
1755
|
+
}
|
1756
|
+
element.style.pointerEvents = 'auto';
|
1757
|
+
element.style.pointerEvents = 'x';
|
1758
|
+
documentElement.appendChild(element);
|
1759
|
+
supports = getComputedStyle &&
|
1760
|
+
getComputedStyle(element, '').pointerEvents === 'auto';
|
1761
|
+
documentElement.removeChild(element);
|
1762
|
+
return !!supports;
|
1763
|
+
})();
|
1764
|
+
|
1765
|
+
//console.log('supportsPointerEvents', supportsPointerEvents);
|
1766
|
+
|
1767
|
+
if (supportsPointerEvents && !mejs.MediaFeatures.isOpera) { // opera doesn't allow this :(
|
1768
|
+
|
1769
|
+
// allows clicking through the fullscreen button and controls down directly to Flash
|
1770
|
+
|
1771
|
+
/*
|
1772
|
+
When a user puts his mouse over the fullscreen button, the controls are disabled
|
1773
|
+
So we put a div over the video and another one on iether side of the fullscreen button
|
1774
|
+
that caputre mouse movement
|
1775
|
+
and restore the controls once the mouse moves outside of the fullscreen button
|
1776
|
+
*/
|
1777
|
+
|
1778
|
+
var fullscreenIsDisabled = false,
|
1779
|
+
restoreControls = function() {
|
1780
|
+
if (fullscreenIsDisabled) {
|
1781
|
+
// hide the hovers
|
1782
|
+
videoHoverDiv.hide();
|
1783
|
+
controlsLeftHoverDiv.hide();
|
1784
|
+
controlsRightHoverDiv.hide();
|
1785
|
+
|
1786
|
+
// restore the control bar
|
1787
|
+
fullscreenBtn.css('pointer-events', '');
|
1788
|
+
t.controls.css('pointer-events', '');
|
1789
|
+
|
1790
|
+
// store for later
|
1791
|
+
fullscreenIsDisabled = false;
|
1792
|
+
}
|
1793
|
+
},
|
1794
|
+
videoHoverDiv = $('<div class="mejs-fullscreen-hover" />').appendTo(t.container).mouseover(restoreControls),
|
1795
|
+
controlsLeftHoverDiv = $('<div class="mejs-fullscreen-hover" />').appendTo(t.container).mouseover(restoreControls),
|
1796
|
+
controlsRightHoverDiv = $('<div class="mejs-fullscreen-hover" />').appendTo(t.container).mouseover(restoreControls),
|
1797
|
+
positionHoverDivs = function() {
|
1798
|
+
var style = {position: 'absolute', top: 0, left: 0}; //, backgroundColor: '#f00'};
|
1799
|
+
videoHoverDiv.css(style);
|
1800
|
+
controlsLeftHoverDiv.css(style);
|
1801
|
+
controlsRightHoverDiv.css(style);
|
1802
|
+
|
1803
|
+
// over video, but not controls
|
1804
|
+
videoHoverDiv
|
1805
|
+
.width( t.container.width() )
|
1806
|
+
.height( t.container.height() - t.controls.height() );
|
1807
|
+
|
1808
|
+
// over controls, but not the fullscreen button
|
1809
|
+
var fullScreenBtnOffset = fullscreenBtn.offset().left - t.container.offset().left;
|
1810
|
+
fullScreenBtnWidth = fullscreenBtn.outerWidth(true);
|
1811
|
+
|
1812
|
+
controlsLeftHoverDiv
|
1813
|
+
.width( fullScreenBtnOffset )
|
1814
|
+
.height( t.controls.height() )
|
1815
|
+
.css({top: t.container.height() - t.controls.height()});
|
1816
|
+
|
1817
|
+
// after the fullscreen button
|
1818
|
+
controlsRightHoverDiv
|
1819
|
+
.width( t.container.width() - fullScreenBtnOffset - fullScreenBtnWidth )
|
1820
|
+
.height( t.controls.height() )
|
1821
|
+
.css({top: t.container.height() - t.controls.height(),
|
1822
|
+
left: fullScreenBtnOffset + fullScreenBtnWidth});
|
1823
|
+
};
|
1824
|
+
|
1825
|
+
$(document).resize(function() {
|
1826
|
+
positionHoverDivs();
|
1827
|
+
});
|
1828
|
+
|
1829
|
+
// on hover, kill the fullscreen button's HTML handling, allowing clicks down to Flash
|
1830
|
+
fullscreenBtn
|
1831
|
+
.mouseover(function() {
|
1832
|
+
|
1833
|
+
if (!t.isFullScreen) {
|
1834
|
+
|
1835
|
+
var buttonPos = fullscreenBtn.offset(),
|
1836
|
+
containerPos = player.container.offset();
|
1837
|
+
|
1838
|
+
// move the button in Flash into place
|
1839
|
+
media.positionFullscreenButton(buttonPos.left - containerPos.left, buttonPos.top - containerPos.top, false);
|
1840
|
+
|
1841
|
+
// allows click through
|
1842
|
+
fullscreenBtn.css('pointer-events', 'none');
|
1843
|
+
t.controls.css('pointer-events', 'none');
|
1844
|
+
|
1845
|
+
// show the divs that will restore things
|
1846
|
+
videoHoverDiv.show();
|
1847
|
+
controlsRightHoverDiv.show();
|
1848
|
+
controlsLeftHoverDiv.show();
|
1849
|
+
positionHoverDivs();
|
1850
|
+
|
1851
|
+
fullscreenIsDisabled = true;
|
1852
|
+
}
|
1853
|
+
|
1854
|
+
});
|
1855
|
+
|
1856
|
+
// restore controls anytime the user enters or leaves fullscreen
|
1857
|
+
media.addEventListener('fullscreenchange', function(e) {
|
1858
|
+
restoreControls();
|
1859
|
+
});
|
1860
|
+
|
1861
|
+
|
1862
|
+
// the mouseout event doesn't work on the fullscren button, because we already killed the pointer-events
|
1863
|
+
// so we use the document.mousemove event to restore controls when the mouse moves outside the fullscreen button
|
1864
|
+
/*
|
1865
|
+
$(document).mousemove(function(e) {
|
1866
|
+
|
1867
|
+
// if the mouse is anywhere but the fullsceen button, then restore it all
|
1868
|
+
if (fullscreenIsDisabled) {
|
1869
|
+
|
1870
|
+
var fullscreenBtnPos = fullscreenBtn.offset();
|
1871
|
+
|
1872
|
+
|
1873
|
+
if (e.pageY < fullscreenBtnPos.top || e.pageY > fullscreenBtnPos.top + fullscreenBtn.outerHeight(true) ||
|
1874
|
+
e.pageX < fullscreenBtnPos.left || e.pageX > fullscreenBtnPos.left + fullscreenBtn.outerWidth(true)
|
1875
|
+
) {
|
1876
|
+
|
1877
|
+
fullscreenBtn.css('pointer-events', '');
|
1878
|
+
t.controls.css('pointer-events', '');
|
1879
|
+
|
1880
|
+
fullscreenIsDisabled = false;
|
1881
|
+
}
|
1602
1882
|
}
|
1603
1883
|
});
|
1604
|
-
|
1605
|
-
|
1606
|
-
return false;
|
1607
|
-
});
|
1884
|
+
*/
|
1608
1885
|
|
1609
1886
|
|
1610
|
-
|
1611
|
-
|
1612
|
-
|
1887
|
+
} else {
|
1888
|
+
|
1889
|
+
// the hover state will show the fullscreen button in Flash to hover up and click
|
1890
|
+
|
1891
|
+
fullscreenBtn
|
1892
|
+
.mouseover(function() {
|
1893
|
+
|
1894
|
+
if (hideTimeout !== null) {
|
1895
|
+
clearTimeout(hideTimeout);
|
1896
|
+
delete hideTimeout;
|
1897
|
+
}
|
1898
|
+
|
1899
|
+
var buttonPos = fullscreenBtn.offset(),
|
1900
|
+
containerPos = player.container.offset();
|
1901
|
+
|
1902
|
+
media.positionFullscreenButton(buttonPos.left - containerPos.left, buttonPos.top - containerPos.top, true);
|
1903
|
+
|
1904
|
+
})
|
1905
|
+
.mouseout(function() {
|
1906
|
+
|
1907
|
+
if (hideTimeout !== null) {
|
1908
|
+
clearTimeout(hideTimeout);
|
1909
|
+
delete hideTimeout;
|
1910
|
+
}
|
1911
|
+
|
1912
|
+
hideTimeout = setTimeout(function() {
|
1913
|
+
media.hideFullscreenButton();
|
1914
|
+
}, 1500);
|
1915
|
+
|
1916
|
+
|
1917
|
+
});
|
1918
|
+
}
|
1919
|
+
}
|
1920
|
+
|
1921
|
+
player.fullscreenBtn = fullscreenBtn;
|
1922
|
+
|
1923
|
+
$(document).bind('keydown',function (e) {
|
1924
|
+
if (((mejs.MediaFeatures.hasTrueNativeFullScreen && mejs.MediaFeatures.isFullScreen()) || t.isFullScreen) && e.keyCode == 27) {
|
1925
|
+
player.exitFullScreen();
|
1926
|
+
}
|
1613
1927
|
});
|
1614
1928
|
|
1615
|
-
|
1616
|
-
|
1617
|
-
|
1618
|
-
|
1619
|
-
|
1620
|
-
|
1621
|
-
|
1622
|
-
|
1623
|
-
|
1929
|
+
},
|
1930
|
+
enterFullScreen: function() {
|
1931
|
+
|
1932
|
+
var t = this;
|
1933
|
+
|
1934
|
+
// firefox+flash can't adjust plugin sizes without resetting :(
|
1935
|
+
if (t.media.pluginType !== 'native' && (mejs.MediaFeatures.isFirefox || t.options.usePluginFullScreen)) {
|
1936
|
+
//t.media.setFullscreen(true);
|
1937
|
+
//player.isFullScreen = true;
|
1938
|
+
return;
|
1939
|
+
}
|
1940
|
+
|
1941
|
+
// store overflow
|
1942
|
+
docStyleOverflow = document.documentElement.style.overflow;
|
1943
|
+
// set it to not show scroll bars so 100% will work
|
1944
|
+
document.documentElement.style.overflow = 'hidden';
|
1945
|
+
|
1946
|
+
// store sizing
|
1947
|
+
normalHeight = t.container.height();
|
1948
|
+
normalWidth = t.container.width();
|
1949
|
+
|
1950
|
+
// attempt to do true fullscreen (Safari 5.1 and Firefox Nightly only for now)
|
1951
|
+
if (t.media.pluginType === 'native') {
|
1952
|
+
if (mejs.MediaFeatures.hasTrueNativeFullScreen) {
|
1953
|
+
|
1954
|
+
mejs.MediaFeatures.requestFullScreen(t.container[0]);
|
1955
|
+
//return;
|
1956
|
+
|
1957
|
+
if (t.isInIframe) {
|
1958
|
+
// sometimes exiting from fullscreen doesn't work
|
1959
|
+
// notably in Chrome <iframe>. Fixed in version 17
|
1960
|
+
setTimeout(function checkFullscreen() {
|
1961
|
+
|
1962
|
+
if (t.isNativeFullScreen) {
|
1963
|
+
|
1964
|
+
// check if the video is suddenly not really fullscreen
|
1965
|
+
if ($(window).width() !== screen.width) {
|
1966
|
+
// manually exit
|
1967
|
+
t.exitFullScreen();
|
1968
|
+
} else {
|
1969
|
+
// test again
|
1970
|
+
setTimeout(checkFullscreen, 500);
|
1971
|
+
}
|
1972
|
+
}
|
1973
|
+
|
1974
|
+
|
1975
|
+
}, 500);
|
1624
1976
|
}
|
1977
|
+
|
1978
|
+
} else if (mejs.MediaFeatures.hasSemiNativeFullScreen) {
|
1979
|
+
t.media.webkitEnterFullscreen();
|
1980
|
+
return;
|
1625
1981
|
}
|
1626
|
-
}
|
1982
|
+
}
|
1627
1983
|
|
1628
|
-
|
1629
|
-
|
1630
|
-
|
1631
|
-
|
1632
|
-
|
1633
|
-
if (
|
1634
|
-
|
1984
|
+
// check for iframe launch
|
1985
|
+
if (t.isInIframe) {
|
1986
|
+
var url = t.options.newWindowCallback(this);
|
1987
|
+
|
1988
|
+
|
1989
|
+
if (url !== '') {
|
1990
|
+
|
1991
|
+
// launch immediately
|
1992
|
+
if (!mejs.MediaFeatures.hasTrueNativeFullScreen) {
|
1993
|
+
t.pause();
|
1994
|
+
window.open(url, t.id, 'top=0,left=0,width=' + screen.availWidth + ',height=' + screen.availHeight + ',resizable=yes,scrollbars=no,status=no,toolbar=no');
|
1995
|
+
return;
|
1996
|
+
} else {
|
1997
|
+
setTimeout(function() {
|
1998
|
+
if (!t.isNativeFullScreen) {
|
1999
|
+
t.pause();
|
2000
|
+
window.open(url, t.id, 'top=0,left=0,width=' + screen.availWidth + ',height=' + screen.availHeight + ',resizable=yes,scrollbars=no,status=no,toolbar=no');
|
2001
|
+
}
|
2002
|
+
}, 250);
|
2003
|
+
}
|
1635
2004
|
}
|
2005
|
+
|
2006
|
+
}
|
2007
|
+
|
2008
|
+
// full window code
|
2009
|
+
|
2010
|
+
|
2011
|
+
|
2012
|
+
// make full size
|
2013
|
+
t.container
|
2014
|
+
.addClass('mejs-container-fullscreen')
|
2015
|
+
.width('100%')
|
2016
|
+
.height('100%');
|
2017
|
+
//.css({position: 'fixed', left: 0, top: 0, right: 0, bottom: 0, overflow: 'hidden', width: '100%', height: '100%', 'z-index': 1000});
|
2018
|
+
|
2019
|
+
// Only needed for safari 5.1 native full screen, can cause display issues elsewhere
|
2020
|
+
// Actually, it seems to be needed for IE8, too
|
2021
|
+
//if (mejs.MediaFeatures.hasTrueNativeFullScreen) {
|
2022
|
+
setTimeout(function() {
|
2023
|
+
t.container.css({width: '100%', height: '100%'});
|
2024
|
+
t.setControlsSize();
|
2025
|
+
}, 500);
|
2026
|
+
//}
|
2027
|
+
|
2028
|
+
if (t.pluginType === 'native') {
|
2029
|
+
t.$media
|
2030
|
+
.width('100%')
|
2031
|
+
.height('100%');
|
2032
|
+
} else {
|
2033
|
+
t.container.find('object, embed, iframe')
|
2034
|
+
.width('100%')
|
2035
|
+
.height('100%');
|
2036
|
+
|
2037
|
+
//if (!mejs.MediaFeatures.hasTrueNativeFullScreen) {
|
2038
|
+
t.media.setVideoSize($(window).width(),$(window).height());
|
2039
|
+
//}
|
2040
|
+
}
|
2041
|
+
|
2042
|
+
t.layers.children('div')
|
2043
|
+
.width('100%')
|
2044
|
+
.height('100%');
|
2045
|
+
|
2046
|
+
if (t.fullscreenBtn) {
|
2047
|
+
t.fullscreenBtn
|
2048
|
+
.removeClass('mejs-fullscreen')
|
2049
|
+
.addClass('mejs-unfullscreen');
|
2050
|
+
}
|
2051
|
+
|
2052
|
+
t.setControlsSize();
|
2053
|
+
t.isFullScreen = true;
|
2054
|
+
},
|
2055
|
+
|
2056
|
+
exitFullScreen: function() {
|
2057
|
+
|
2058
|
+
var t = this;
|
2059
|
+
|
2060
|
+
// firefox can't adjust plugins
|
2061
|
+
if (t.media.pluginType !== 'native' && mejs.MediaFeatures.isFirefox) {
|
2062
|
+
t.media.setFullscreen(false);
|
2063
|
+
//player.isFullScreen = false;
|
2064
|
+
return;
|
2065
|
+
}
|
2066
|
+
|
2067
|
+
// come outo of native fullscreen
|
2068
|
+
if (mejs.MediaFeatures.hasTrueNativeFullScreen && (mejs.MediaFeatures.isFullScreen() || t.isFullScreen)) {
|
2069
|
+
mejs.MediaFeatures.cancelFullScreen();
|
2070
|
+
}
|
2071
|
+
|
2072
|
+
// restore scroll bars to document
|
2073
|
+
document.documentElement.style.overflow = docStyleOverflow;
|
2074
|
+
|
2075
|
+
t.container
|
2076
|
+
.removeClass('mejs-container-fullscreen')
|
2077
|
+
.width(normalWidth)
|
2078
|
+
.height(normalHeight);
|
2079
|
+
//.css({position: '', left: '', top: '', right: '', bottom: '', overflow: 'inherit', width: normalWidth + 'px', height: normalHeight + 'px', 'z-index': 1});
|
2080
|
+
|
2081
|
+
if (t.pluginType === 'native') {
|
2082
|
+
t.$media
|
2083
|
+
.width(normalWidth)
|
2084
|
+
.height(normalHeight);
|
2085
|
+
} else {
|
2086
|
+
t.container.find('object embed')
|
2087
|
+
.width(normalWidth)
|
2088
|
+
.height(normalHeight);
|
2089
|
+
|
2090
|
+
t.media.setVideoSize(normalWidth, normalHeight);
|
1636
2091
|
}
|
2092
|
+
|
2093
|
+
t.layers.children('div')
|
2094
|
+
.width(normalWidth)
|
2095
|
+
.height(normalHeight);
|
2096
|
+
|
2097
|
+
t.fullscreenBtn
|
2098
|
+
.removeClass('mejs-unfullscreen')
|
2099
|
+
.addClass('mejs-fullscreen');
|
2100
|
+
|
2101
|
+
t.setControlsSize();
|
2102
|
+
t.isFullScreen = false;
|
1637
2103
|
}
|
1638
2104
|
});
|
1639
|
-
|
1640
|
-
})(mejs.$);
|
1641
2105
|
|
1642
|
-
(
|
1643
|
-
|
1644
|
-
$.extend(mejs.MepDefaults, {
|
1645
|
-
usePluginFullScreen: true,
|
1646
|
-
newWindowCallback: function() { return '';},
|
1647
|
-
fullscreenText: 'Fullscreen'
|
1648
|
-
});
|
1649
|
-
|
1650
|
-
$.extend(MediaElementPlayer.prototype, {
|
1651
|
-
|
1652
|
-
isFullScreen: false,
|
1653
|
-
|
1654
|
-
isNativeFullScreen: false,
|
1655
|
-
|
1656
|
-
docStyleOverflow: null,
|
1657
|
-
|
1658
|
-
isInIframe: false,
|
1659
|
-
|
1660
|
-
buildfullscreen: function(player, controls, layers, media) {
|
1661
|
-
|
1662
|
-
if (!player.isVideo)
|
1663
|
-
return;
|
1664
|
-
|
1665
|
-
player.isInIframe = (window.location != window.parent.location);
|
1666
|
-
|
1667
|
-
// native events
|
1668
|
-
if (mejs.MediaFeatures.hasTrueNativeFullScreen) {
|
1669
|
-
|
1670
|
-
// chrome doesn't alays fire this in an iframe
|
1671
|
-
var target = null;
|
1672
|
-
|
1673
|
-
if (mejs.MediaFeatures.hasMozNativeFullScreen) {
|
1674
|
-
target = $(document);
|
1675
|
-
} else {
|
1676
|
-
target = player.container;
|
1677
|
-
}
|
1678
|
-
|
1679
|
-
target.bind(mejs.MediaFeatures.fullScreenEventName, function(e) {
|
1680
|
-
|
1681
|
-
if (mejs.MediaFeatures.isFullScreen()) {
|
1682
|
-
player.isNativeFullScreen = true;
|
1683
|
-
// reset the controls once we are fully in full screen
|
1684
|
-
player.setControlsSize();
|
1685
|
-
} else {
|
1686
|
-
player.isNativeFullScreen = false;
|
1687
|
-
// when a user presses ESC
|
1688
|
-
// make sure to put the player back into place
|
1689
|
-
player.exitFullScreen();
|
1690
|
-
}
|
1691
|
-
});
|
1692
|
-
}
|
1693
|
-
|
1694
|
-
var t = this,
|
1695
|
-
normalHeight = 0,
|
1696
|
-
normalWidth = 0,
|
1697
|
-
container = player.container,
|
1698
|
-
fullscreenBtn =
|
1699
|
-
$('<div class="mejs-button mejs-fullscreen-button">' +
|
1700
|
-
'<button type="button" aria-controls="' + t.id + '" title="' + t.options.fullscreenText + '"></button>' +
|
1701
|
-
'</div>')
|
1702
|
-
.appendTo(controls);
|
1703
|
-
|
1704
|
-
if (t.media.pluginType === 'native' || (!t.options.usePluginFullScreen && !mejs.MediaFeatures.isFirefox)) {
|
1705
|
-
|
1706
|
-
fullscreenBtn.click(function() {
|
1707
|
-
var isFullScreen = (mejs.MediaFeatures.hasTrueNativeFullScreen && mejs.MediaFeatures.isFullScreen()) || player.isFullScreen;
|
1708
|
-
|
1709
|
-
if (isFullScreen) {
|
1710
|
-
player.exitFullScreen();
|
1711
|
-
} else {
|
1712
|
-
player.enterFullScreen();
|
1713
|
-
}
|
1714
|
-
});
|
1715
|
-
|
1716
|
-
} else {
|
1717
|
-
|
1718
|
-
var hideTimeout = null,
|
1719
|
-
supportsPointerEvents = (function() {
|
1720
|
-
// TAKEN FROM MODERNIZR
|
1721
|
-
var element = document.createElement('x'),
|
1722
|
-
documentElement = document.documentElement,
|
1723
|
-
getComputedStyle = window.getComputedStyle,
|
1724
|
-
supports;
|
1725
|
-
if(!('pointerEvents' in element.style)){
|
1726
|
-
return false;
|
1727
|
-
}
|
1728
|
-
element.style.pointerEvents = 'auto';
|
1729
|
-
element.style.pointerEvents = 'x';
|
1730
|
-
documentElement.appendChild(element);
|
1731
|
-
supports = getComputedStyle &&
|
1732
|
-
getComputedStyle(element, '').pointerEvents === 'auto';
|
1733
|
-
documentElement.removeChild(element);
|
1734
|
-
return !!supports;
|
1735
|
-
})();
|
1736
|
-
|
1737
|
-
//console.log('supportsPointerEvents', supportsPointerEvents);
|
1738
|
-
|
1739
|
-
if (supportsPointerEvents && !mejs.MediaFeatures.isOpera) { // opera doesn't allow this :(
|
1740
|
-
|
1741
|
-
// allows clicking through the fullscreen button and controls down directly to Flash
|
1742
|
-
|
1743
|
-
/*
|
1744
|
-
When a user puts his mouse over the fullscreen button, the controls are disabled
|
1745
|
-
So we put a div over the video and another one on iether side of the fullscreen button
|
1746
|
-
that caputre mouse movement
|
1747
|
-
and restore the controls once the mouse moves outside of the fullscreen button
|
1748
|
-
*/
|
1749
|
-
|
1750
|
-
var fullscreenIsDisabled = false,
|
1751
|
-
restoreControls = function() {
|
1752
|
-
if (fullscreenIsDisabled) {
|
1753
|
-
// hide the hovers
|
1754
|
-
videoHoverDiv.hide();
|
1755
|
-
controlsLeftHoverDiv.hide();
|
1756
|
-
controlsRightHoverDiv.hide();
|
1757
|
-
|
1758
|
-
// restore the control bar
|
1759
|
-
fullscreenBtn.css('pointer-events', '');
|
1760
|
-
t.controls.css('pointer-events', '');
|
1761
|
-
|
1762
|
-
// store for later
|
1763
|
-
fullscreenIsDisabled = false;
|
1764
|
-
}
|
1765
|
-
},
|
1766
|
-
videoHoverDiv = $('<div class="mejs-fullscreen-hover" />').appendTo(t.container).mouseover(restoreControls),
|
1767
|
-
controlsLeftHoverDiv = $('<div class="mejs-fullscreen-hover" />').appendTo(t.container).mouseover(restoreControls),
|
1768
|
-
controlsRightHoverDiv = $('<div class="mejs-fullscreen-hover" />').appendTo(t.container).mouseover(restoreControls),
|
1769
|
-
positionHoverDivs = function() {
|
1770
|
-
var style = {position: 'absolute', top: 0, left: 0}; //, backgroundColor: '#f00'};
|
1771
|
-
videoHoverDiv.css(style);
|
1772
|
-
controlsLeftHoverDiv.css(style);
|
1773
|
-
controlsRightHoverDiv.css(style);
|
1774
|
-
|
1775
|
-
// over video, but not controls
|
1776
|
-
videoHoverDiv
|
1777
|
-
.width( t.container.width() )
|
1778
|
-
.height( t.container.height() - t.controls.height() );
|
1779
|
-
|
1780
|
-
// over controls, but not the fullscreen button
|
1781
|
-
var fullScreenBtnOffset = fullscreenBtn.offset().left - t.container.offset().left;
|
1782
|
-
fullScreenBtnWidth = fullscreenBtn.outerWidth(true);
|
1783
|
-
|
1784
|
-
controlsLeftHoverDiv
|
1785
|
-
.width( fullScreenBtnOffset )
|
1786
|
-
.height( t.controls.height() )
|
1787
|
-
.css({top: t.container.height() - t.controls.height()});
|
1788
|
-
|
1789
|
-
// after the fullscreen button
|
1790
|
-
controlsRightHoverDiv
|
1791
|
-
.width( t.container.width() - fullScreenBtnOffset - fullScreenBtnWidth )
|
1792
|
-
.height( t.controls.height() )
|
1793
|
-
.css({top: t.container.height() - t.controls.height(),
|
1794
|
-
left: fullScreenBtnOffset + fullScreenBtnWidth});
|
1795
|
-
};
|
1796
|
-
|
1797
|
-
$(document).resize(function() {
|
1798
|
-
positionHoverDivs();
|
1799
|
-
});
|
1800
|
-
|
1801
|
-
// on hover, kill the fullscreen button's HTML handling, allowing clicks down to Flash
|
1802
|
-
fullscreenBtn
|
1803
|
-
.mouseover(function() {
|
1804
|
-
|
1805
|
-
if (!t.isFullScreen) {
|
1806
|
-
|
1807
|
-
var buttonPos = fullscreenBtn.offset(),
|
1808
|
-
containerPos = player.container.offset();
|
1809
|
-
|
1810
|
-
// move the button in Flash into place
|
1811
|
-
media.positionFullscreenButton(buttonPos.left - containerPos.left, buttonPos.top - containerPos.top, false);
|
1812
|
-
|
1813
|
-
// allows click through
|
1814
|
-
fullscreenBtn.css('pointer-events', 'none');
|
1815
|
-
t.controls.css('pointer-events', 'none');
|
1816
|
-
|
1817
|
-
// show the divs that will restore things
|
1818
|
-
videoHoverDiv.show();
|
1819
|
-
controlsRightHoverDiv.show();
|
1820
|
-
controlsLeftHoverDiv.show();
|
1821
|
-
positionHoverDivs();
|
1822
|
-
|
1823
|
-
fullscreenIsDisabled = true;
|
1824
|
-
}
|
1825
|
-
|
1826
|
-
});
|
1827
|
-
|
1828
|
-
// restore controls anytime the user enters or leaves fullscreen
|
1829
|
-
media.addEventListener('fullscreenchange', function(e) {
|
1830
|
-
restoreControls();
|
1831
|
-
});
|
1832
|
-
|
1833
|
-
|
1834
|
-
// the mouseout event doesn't work on the fullscren button, because we already killed the pointer-events
|
1835
|
-
// so we use the document.mousemove event to restore controls when the mouse moves outside the fullscreen button
|
1836
|
-
/*
|
1837
|
-
$(document).mousemove(function(e) {
|
1838
|
-
|
1839
|
-
// if the mouse is anywhere but the fullsceen button, then restore it all
|
1840
|
-
if (fullscreenIsDisabled) {
|
1841
|
-
|
1842
|
-
var fullscreenBtnPos = fullscreenBtn.offset();
|
1843
|
-
|
1844
|
-
|
1845
|
-
if (e.pageY < fullscreenBtnPos.top || e.pageY > fullscreenBtnPos.top + fullscreenBtn.outerHeight(true) ||
|
1846
|
-
e.pageX < fullscreenBtnPos.left || e.pageX > fullscreenBtnPos.left + fullscreenBtn.outerWidth(true)
|
1847
|
-
) {
|
1848
|
-
|
1849
|
-
fullscreenBtn.css('pointer-events', '');
|
1850
|
-
t.controls.css('pointer-events', '');
|
1851
|
-
|
1852
|
-
fullscreenIsDisabled = false;
|
1853
|
-
}
|
1854
|
-
}
|
1855
|
-
});
|
1856
|
-
*/
|
1857
|
-
|
1858
|
-
|
1859
|
-
} else {
|
1860
|
-
|
1861
|
-
// the hover state will show the fullscreen button in Flash to hover up and click
|
1862
|
-
|
1863
|
-
fullscreenBtn
|
1864
|
-
.mouseover(function() {
|
1865
|
-
|
1866
|
-
if (hideTimeout !== null) {
|
1867
|
-
clearTimeout(hideTimeout);
|
1868
|
-
delete hideTimeout;
|
1869
|
-
}
|
1870
|
-
|
1871
|
-
var buttonPos = fullscreenBtn.offset(),
|
1872
|
-
containerPos = player.container.offset();
|
1873
|
-
|
1874
|
-
media.positionFullscreenButton(buttonPos.left - containerPos.left, buttonPos.top - containerPos.top, true);
|
1875
|
-
|
1876
|
-
})
|
1877
|
-
.mouseout(function() {
|
1878
|
-
|
1879
|
-
if (hideTimeout !== null) {
|
1880
|
-
clearTimeout(hideTimeout);
|
1881
|
-
delete hideTimeout;
|
1882
|
-
}
|
1883
|
-
|
1884
|
-
hideTimeout = setTimeout(function() {
|
1885
|
-
media.hideFullscreenButton();
|
1886
|
-
}, 1500);
|
1887
|
-
|
1888
|
-
|
1889
|
-
});
|
1890
|
-
}
|
1891
|
-
}
|
1892
|
-
|
1893
|
-
player.fullscreenBtn = fullscreenBtn;
|
1894
|
-
|
1895
|
-
$(document).bind('keydown',function (e) {
|
1896
|
-
if (((mejs.MediaFeatures.hasTrueNativeFullScreen && mejs.MediaFeatures.isFullScreen()) || t.isFullScreen) && e.keyCode == 27) {
|
1897
|
-
player.exitFullScreen();
|
1898
|
-
}
|
1899
|
-
});
|
1900
|
-
|
1901
|
-
},
|
1902
|
-
enterFullScreen: function() {
|
1903
|
-
|
1904
|
-
var t = this;
|
1905
|
-
|
1906
|
-
// firefox+flash can't adjust plugin sizes without resetting :(
|
1907
|
-
if (t.media.pluginType !== 'native' && (mejs.MediaFeatures.isFirefox || t.options.usePluginFullScreen)) {
|
1908
|
-
//t.media.setFullscreen(true);
|
1909
|
-
//player.isFullScreen = true;
|
1910
|
-
return;
|
1911
|
-
}
|
1912
|
-
|
1913
|
-
// store overflow
|
1914
|
-
docStyleOverflow = document.documentElement.style.overflow;
|
1915
|
-
// set it to not show scroll bars so 100% will work
|
1916
|
-
document.documentElement.style.overflow = 'hidden';
|
1917
|
-
|
1918
|
-
// store sizing
|
1919
|
-
normalHeight = t.container.height();
|
1920
|
-
normalWidth = t.container.width();
|
1921
|
-
|
1922
|
-
// attempt to do true fullscreen (Safari 5.1 and Firefox Nightly only for now)
|
1923
|
-
if (t.media.pluginType === 'native') {
|
1924
|
-
if (mejs.MediaFeatures.hasTrueNativeFullScreen) {
|
1925
|
-
|
1926
|
-
mejs.MediaFeatures.requestFullScreen(t.container[0]);
|
1927
|
-
//return;
|
1928
|
-
|
1929
|
-
if (t.isInIframe) {
|
1930
|
-
// sometimes exiting from fullscreen doesn't work
|
1931
|
-
// notably in Chrome <iframe>. Fixed in version 17
|
1932
|
-
setTimeout(function checkFullscreen() {
|
1933
|
-
|
1934
|
-
if (t.isNativeFullScreen) {
|
1935
|
-
|
1936
|
-
// check if the video is suddenly not really fullscreen
|
1937
|
-
if ($(window).width() !== screen.width) {
|
1938
|
-
// manually exit
|
1939
|
-
t.exitFullScreen();
|
1940
|
-
} else {
|
1941
|
-
// test again
|
1942
|
-
setTimeout(checkFullscreen, 500);
|
1943
|
-
}
|
1944
|
-
}
|
1945
|
-
|
1946
|
-
|
1947
|
-
}, 500);
|
1948
|
-
}
|
1949
|
-
|
1950
|
-
} else if (mejs.MediaFeatures.hasSemiNativeFullScreen) {
|
1951
|
-
t.media.webkitEnterFullscreen();
|
1952
|
-
return;
|
1953
|
-
}
|
1954
|
-
}
|
1955
|
-
|
1956
|
-
// check for iframe launch
|
1957
|
-
if (t.isInIframe) {
|
1958
|
-
var url = t.options.newWindowCallback(this);
|
1959
|
-
|
1960
|
-
|
1961
|
-
if (url !== '') {
|
1962
|
-
|
1963
|
-
// launch immediately
|
1964
|
-
if (!mejs.MediaFeatures.hasTrueNativeFullScreen) {
|
1965
|
-
t.pause();
|
1966
|
-
window.open(url, t.id, 'top=0,left=0,width=' + screen.availWidth + ',height=' + screen.availHeight + ',resizable=yes,scrollbars=no,status=no,toolbar=no');
|
1967
|
-
return;
|
1968
|
-
} else {
|
1969
|
-
setTimeout(function() {
|
1970
|
-
if (!t.isNativeFullScreen) {
|
1971
|
-
t.pause();
|
1972
|
-
window.open(url, t.id, 'top=0,left=0,width=' + screen.availWidth + ',height=' + screen.availHeight + ',resizable=yes,scrollbars=no,status=no,toolbar=no');
|
1973
|
-
}
|
1974
|
-
}, 250);
|
1975
|
-
}
|
1976
|
-
}
|
1977
|
-
|
1978
|
-
}
|
1979
|
-
|
1980
|
-
// full window code
|
1981
|
-
|
1982
|
-
|
1983
|
-
|
1984
|
-
// make full size
|
1985
|
-
t.container
|
1986
|
-
.addClass('mejs-container-fullscreen')
|
1987
|
-
.width('100%')
|
1988
|
-
.height('100%');
|
1989
|
-
//.css({position: 'fixed', left: 0, top: 0, right: 0, bottom: 0, overflow: 'hidden', width: '100%', height: '100%', 'z-index': 1000});
|
1990
|
-
|
1991
|
-
// Only needed for safari 5.1 native full screen, can cause display issues elsewhere
|
1992
|
-
// Actually, it seems to be needed for IE8, too
|
1993
|
-
//if (mejs.MediaFeatures.hasTrueNativeFullScreen) {
|
1994
|
-
setTimeout(function() {
|
1995
|
-
t.container.css({width: '100%', height: '100%'});
|
1996
|
-
t.setControlsSize();
|
1997
|
-
}, 500);
|
1998
|
-
//}
|
1999
|
-
|
2000
|
-
if (t.pluginType === 'native') {
|
2001
|
-
t.$media
|
2002
|
-
.width('100%')
|
2003
|
-
.height('100%');
|
2004
|
-
} else {
|
2005
|
-
t.container.find('object, embed, iframe')
|
2006
|
-
.width('100%')
|
2007
|
-
.height('100%');
|
2008
|
-
|
2009
|
-
//if (!mejs.MediaFeatures.hasTrueNativeFullScreen) {
|
2010
|
-
t.media.setVideoSize($(window).width(),$(window).height());
|
2011
|
-
//}
|
2012
|
-
}
|
2013
|
-
|
2014
|
-
t.layers.children('div')
|
2015
|
-
.width('100%')
|
2016
|
-
.height('100%');
|
2017
|
-
|
2018
|
-
if (t.fullscreenBtn) {
|
2019
|
-
t.fullscreenBtn
|
2020
|
-
.removeClass('mejs-fullscreen')
|
2021
|
-
.addClass('mejs-unfullscreen');
|
2022
|
-
}
|
2023
|
-
|
2024
|
-
t.setControlsSize();
|
2025
|
-
t.isFullScreen = true;
|
2026
|
-
},
|
2027
|
-
|
2028
|
-
exitFullScreen: function() {
|
2029
|
-
|
2030
|
-
var t = this;
|
2031
|
-
|
2032
|
-
// firefox can't adjust plugins
|
2033
|
-
if (t.media.pluginType !== 'native' && mejs.MediaFeatures.isFirefox) {
|
2034
|
-
t.media.setFullscreen(false);
|
2035
|
-
//player.isFullScreen = false;
|
2036
|
-
return;
|
2037
|
-
}
|
2038
|
-
|
2039
|
-
// come outo of native fullscreen
|
2040
|
-
if (mejs.MediaFeatures.hasTrueNativeFullScreen && (mejs.MediaFeatures.isFullScreen() || t.isFullScreen)) {
|
2041
|
-
mejs.MediaFeatures.cancelFullScreen();
|
2042
|
-
}
|
2043
|
-
|
2044
|
-
// restore scroll bars to document
|
2045
|
-
document.documentElement.style.overflow = docStyleOverflow;
|
2046
|
-
|
2047
|
-
t.container
|
2048
|
-
.removeClass('mejs-container-fullscreen')
|
2049
|
-
.width(normalWidth)
|
2050
|
-
.height(normalHeight);
|
2051
|
-
//.css({position: '', left: '', top: '', right: '', bottom: '', overflow: 'inherit', width: normalWidth + 'px', height: normalHeight + 'px', 'z-index': 1});
|
2052
|
-
|
2053
|
-
if (t.pluginType === 'native') {
|
2054
|
-
t.$media
|
2055
|
-
.width(normalWidth)
|
2056
|
-
.height(normalHeight);
|
2057
|
-
} else {
|
2058
|
-
t.container.find('object embed')
|
2059
|
-
.width(normalWidth)
|
2060
|
-
.height(normalHeight);
|
2061
|
-
|
2062
|
-
t.media.setVideoSize(normalWidth, normalHeight);
|
2063
|
-
}
|
2064
|
-
|
2065
|
-
t.layers.children('div')
|
2066
|
-
.width(normalWidth)
|
2067
|
-
.height(normalHeight);
|
2068
|
-
|
2069
|
-
t.fullscreenBtn
|
2070
|
-
.removeClass('mejs-unfullscreen')
|
2071
|
-
.addClass('mejs-fullscreen');
|
2072
|
-
|
2073
|
-
t.setControlsSize();
|
2074
|
-
t.isFullScreen = false;
|
2075
|
-
}
|
2076
|
-
});
|
2077
|
-
|
2078
|
-
})(mejs.$);
|
2106
|
+
})(mejs.$);
|
2079
2107
|
|
2080
2108
|
(function($) {
|
2081
2109
|
|
@@ -2152,12 +2180,12 @@ if (typeof jQuery != 'undefined') {
|
|
2152
2180
|
if (!player.options.alwaysShowControls) {
|
2153
2181
|
// move with controls
|
2154
2182
|
player.container
|
2155
|
-
.bind('
|
2183
|
+
.bind('controlsshown', function () {
|
2156
2184
|
// push captions above controls
|
2157
2185
|
player.container.find('.mejs-captions-position').addClass('mejs-captions-position-hover');
|
2158
2186
|
|
2159
2187
|
})
|
2160
|
-
.bind('
|
2188
|
+
.bind('controlshidden', function () {
|
2161
2189
|
if (!media.paused) {
|
2162
2190
|
// move back to normal place
|
2163
2191
|
player.container.find('.mejs-captions-position').removeClass('mejs-captions-position-hover');
|
@@ -2243,35 +2271,33 @@ if (typeof jQuery != 'undefined') {
|
|
2243
2271
|
|
2244
2272
|
};
|
2245
2273
|
|
2246
|
-
if (track.isTranslation) {
|
2247
|
-
|
2248
|
-
// translate the first track
|
2249
|
-
mejs.TrackFormatParser.translateTrackText(t.tracks[0].entries, t.tracks[0].srclang, track.srclang, t.options.googleApiKey, function(newOne) {
|
2250
2274
|
|
2251
|
-
|
2252
|
-
|
2275
|
+
$.ajax({
|
2276
|
+
url: track.src,
|
2277
|
+
dataType: "text",
|
2278
|
+
success: function(d) {
|
2253
2279
|
|
2280
|
+
// parse the loaded file
|
2281
|
+
if (typeof d == "string" && (/<tt\s+xml/ig).exec(d)) {
|
2282
|
+
track.entries = mejs.TrackFormatParser.dfxp.parse(d);
|
2283
|
+
} else {
|
2284
|
+
track.entries = mejs.TrackFormatParser.webvvt.parse(d);
|
2285
|
+
}
|
2286
|
+
|
2254
2287
|
after();
|
2255
|
-
});
|
2256
|
-
|
2257
|
-
} else {
|
2258
|
-
$.ajax({
|
2259
|
-
url: track.src,
|
2260
|
-
success: function(d) {
|
2261
|
-
|
2262
|
-
// parse the loaded file
|
2263
|
-
track.entries = mejs.TrackFormatParser.parse(d);
|
2264
|
-
after();
|
2265
2288
|
|
2266
|
-
|
2267
|
-
|
2268
|
-
|
2269
|
-
|
2270
|
-
|
2271
|
-
|
2289
|
+
if (track.kind == 'chapters') {
|
2290
|
+
t.media.addEventListener('play', function(e) {
|
2291
|
+
if (t.media.duration > 0) {
|
2292
|
+
t.displayChapters(track);
|
2293
|
+
}
|
2294
|
+
}, false);
|
2272
2295
|
}
|
2273
|
-
}
|
2274
|
-
|
2296
|
+
},
|
2297
|
+
error: function() {
|
2298
|
+
t.loadNextTrack();
|
2299
|
+
}
|
2300
|
+
});
|
2275
2301
|
},
|
2276
2302
|
|
2277
2303
|
enableTrackButton: function(lang, label) {
|
@@ -2489,53 +2515,106 @@ if (typeof jQuery != 'undefined') {
|
|
2489
2515
|
Adapted from: http://www.delphiki.com/html5/playr
|
2490
2516
|
*/
|
2491
2517
|
mejs.TrackFormatParser = {
|
2492
|
-
|
2493
|
-
|
2494
|
-
|
2495
|
-
|
2496
|
-
|
2497
|
-
|
2498
|
-
|
2499
|
-
|
2500
|
-
|
2501
|
-
|
2502
|
-
|
2503
|
-
|
2504
|
-
lines
|
2505
|
-
|
2506
|
-
|
2507
|
-
|
2508
|
-
|
2509
|
-
for(; i<lines.length; i++) {
|
2510
|
-
// check for the line number
|
2511
|
-
if (this.pattern_identifier.exec(lines[i])){
|
2512
|
-
// skip to the next line where the start --> end time code should be
|
2513
|
-
i++;
|
2514
|
-
timecode = this.pattern_timecode.exec(lines[i]);
|
2515
|
-
|
2516
|
-
if (timecode && i<lines.length){
|
2518
|
+
webvvt: {
|
2519
|
+
// match start "chapter-" (or anythingelse)
|
2520
|
+
pattern_identifier: /^([a-zA-z]+-)?[0-9]+$/,
|
2521
|
+
pattern_timecode: /^([0-9]{2}:[0-9]{2}:[0-9]{2}([,.][0-9]{1,3})?) --\> ([0-9]{2}:[0-9]{2}:[0-9]{2}([,.][0-9]{3})?)(.*)$/,
|
2522
|
+
|
2523
|
+
parse: function(trackText) {
|
2524
|
+
var
|
2525
|
+
i = 0,
|
2526
|
+
lines = mejs.TrackFormatParser.split2(trackText, /\r?\n/),
|
2527
|
+
entries = {text:[], times:[]},
|
2528
|
+
timecode,
|
2529
|
+
text;
|
2530
|
+
for(; i<lines.length; i++) {
|
2531
|
+
// check for the line number
|
2532
|
+
if (this.pattern_identifier.exec(lines[i])){
|
2533
|
+
// skip to the next line where the start --> end time code should be
|
2517
2534
|
i++;
|
2518
|
-
|
2519
|
-
|
2520
|
-
i
|
2521
|
-
while(lines[i] !== '' && i<lines.length){
|
2522
|
-
text = text + '\n' + lines[i];
|
2535
|
+
timecode = this.pattern_timecode.exec(lines[i]);
|
2536
|
+
|
2537
|
+
if (timecode && i<lines.length){
|
2523
2538
|
i++;
|
2539
|
+
// grab all the (possibly multi-line) text that follows
|
2540
|
+
text = lines[i];
|
2541
|
+
i++;
|
2542
|
+
while(lines[i] !== '' && i<lines.length){
|
2543
|
+
text = text + '\n' + lines[i];
|
2544
|
+
i++;
|
2545
|
+
}
|
2546
|
+
text = $.trim(text).replace(/(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig, "<a href='$1' target='_blank'>$1</a>");
|
2547
|
+
// Text is in a different array so I can use .join
|
2548
|
+
entries.text.push(text);
|
2549
|
+
entries.times.push(
|
2550
|
+
{
|
2551
|
+
start: (mejs.Utility.convertSMPTEtoSeconds(timecode[1]) == 0) ? 0.200 : mejs.Utility.convertSMPTEtoSeconds(timecode[1]),
|
2552
|
+
stop: mejs.Utility.convertSMPTEtoSeconds(timecode[3]),
|
2553
|
+
settings: timecode[5]
|
2554
|
+
});
|
2524
2555
|
}
|
2525
|
-
|
2526
|
-
// Text is in a different array so I can use .join
|
2527
|
-
entries.text.push(text);
|
2528
|
-
entries.times.push(
|
2529
|
-
{
|
2530
|
-
start: mejs.Utility.timeCodeToSeconds(timecode[1]),
|
2531
|
-
stop: mejs.Utility.timeCodeToSeconds(timecode[3]),
|
2532
|
-
settings: timecode[5]
|
2533
|
-
});
|
2534
2556
|
}
|
2535
2557
|
}
|
2558
|
+
return entries;
|
2536
2559
|
}
|
2560
|
+
},
|
2561
|
+
// Thanks to Justin Capella: https://github.com/johndyer/mediaelement/pull/420
|
2562
|
+
dfxp: {
|
2563
|
+
parse: function(trackText) {
|
2564
|
+
trackText = $(trackText).filter("tt");
|
2565
|
+
var
|
2566
|
+
i = 0,
|
2567
|
+
container = trackText.children("div").eq(0),
|
2568
|
+
lines = container.find("p"),
|
2569
|
+
styleNode = trackText.find("#" + container.attr("style")),
|
2570
|
+
styles,
|
2571
|
+
begin,
|
2572
|
+
end,
|
2573
|
+
text,
|
2574
|
+
entries = {text:[], times:[]};
|
2575
|
+
|
2576
|
+
|
2577
|
+
if (styleNode.length) {
|
2578
|
+
var attributes = styleNode.removeAttr("id").get(0).attributes;
|
2579
|
+
if (attributes.length) {
|
2580
|
+
styles = {};
|
2581
|
+
for (i = 0; i < attributes.length; i++) {
|
2582
|
+
styles[attributes[i].name.split(":")[1]] = attributes[i].value;
|
2583
|
+
}
|
2584
|
+
}
|
2585
|
+
}
|
2537
2586
|
|
2538
|
-
|
2587
|
+
for(i = 0; i<lines.length; i++) {
|
2588
|
+
var style;
|
2589
|
+
var _temp_times = {
|
2590
|
+
start: null,
|
2591
|
+
stop: null,
|
2592
|
+
style: null
|
2593
|
+
};
|
2594
|
+
if (lines.eq(i).attr("begin")) _temp_times.start = mejs.Utility.convertSMPTEtoSeconds(lines.eq(i).attr("begin"));
|
2595
|
+
if (!_temp_times.start && lines.eq(i-1).attr("end")) _temp_times.start = mejs.Utility.convertSMPTEtoSeconds(lines.eq(i-1).attr("end"));
|
2596
|
+
if (lines.eq(i).attr("end")) _temp_times.stop = mejs.Utility.convertSMPTEtoSeconds(lines.eq(i).attr("end"));
|
2597
|
+
if (!_temp_times.stop && lines.eq(i+1).attr("begin")) _temp_times.stop = mejs.Utility.convertSMPTEtoSeconds(lines.eq(i+1).attr("begin"));
|
2598
|
+
if (styles) {
|
2599
|
+
style = "";
|
2600
|
+
for (var _style in styles) {
|
2601
|
+
style += _style + ":" + styles[_style] + ";";
|
2602
|
+
}
|
2603
|
+
}
|
2604
|
+
if (style) _temp_times.style = style;
|
2605
|
+
if (_temp_times.start == 0) _temp_times.start = 0.200;
|
2606
|
+
entries.times.push(_temp_times);
|
2607
|
+
text = $.trim(lines.eq(i).html()).replace(/(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig, "<a href='$1' target='_blank'>$1</a>");
|
2608
|
+
entries.text.push(text);
|
2609
|
+
if (entries.times.start == 0) entries.times.start = 2;
|
2610
|
+
}
|
2611
|
+
return entries;
|
2612
|
+
}
|
2613
|
+
},
|
2614
|
+
split2: function (text, regex) {
|
2615
|
+
// normal version for compliant browsers
|
2616
|
+
// see below for IE fix
|
2617
|
+
return text.split(regex);
|
2539
2618
|
}
|
2540
2619
|
};
|
2541
2620
|
|
@@ -2562,196 +2641,231 @@ if (typeof jQuery != 'undefined') {
|
|
2562
2641
|
|
2563
2642
|
})(mejs.$);
|
2564
2643
|
|
2565
|
-
/*
|
2566
|
-
* ContextMenu Plugin
|
2567
|
-
*
|
2568
|
-
*
|
2569
|
-
*/
|
2570
|
-
|
2571
|
-
(function($) {
|
2572
|
-
|
2573
|
-
$.extend(mejs.MepDefaults,
|
2574
|
-
{ 'contextMenuItems': [
|
2575
|
-
// demo of a fullscreen option
|
2576
|
-
{
|
2577
|
-
render: function(player) {
|
2578
|
-
|
2579
|
-
// check for fullscreen plugin
|
2580
|
-
if (typeof player.enterFullScreen == 'undefined')
|
2581
|
-
return null;
|
2582
|
-
|
2583
|
-
if (player.isFullScreen) {
|
2584
|
-
return "Turn off Fullscreen";
|
2585
|
-
} else {
|
2586
|
-
return "Go Fullscreen";
|
2587
|
-
}
|
2588
|
-
},
|
2589
|
-
click: function(player) {
|
2590
|
-
if (player.isFullScreen) {
|
2591
|
-
player.exitFullScreen();
|
2592
|
-
} else {
|
2593
|
-
player.enterFullScreen();
|
2594
|
-
}
|
2595
|
-
}
|
2596
|
-
}
|
2597
|
-
,
|
2598
|
-
// demo of a mute/unmute button
|
2599
|
-
{
|
2600
|
-
render: function(player) {
|
2601
|
-
if (player.media.muted) {
|
2602
|
-
return "Unmute";
|
2603
|
-
} else {
|
2604
|
-
return "Mute";
|
2605
|
-
}
|
2606
|
-
},
|
2607
|
-
click: function(player) {
|
2608
|
-
if (player.media.muted) {
|
2609
|
-
player.setMuted(false);
|
2610
|
-
} else {
|
2611
|
-
player.setMuted(true);
|
2612
|
-
}
|
2613
|
-
}
|
2614
|
-
},
|
2615
|
-
// separator
|
2616
|
-
{
|
2617
|
-
isSeparator: true
|
2618
|
-
}
|
2619
|
-
,
|
2620
|
-
// demo of simple download video
|
2621
|
-
{
|
2622
|
-
render: function(player) {
|
2623
|
-
return "Download Video";
|
2624
|
-
},
|
2625
|
-
click: function(player) {
|
2626
|
-
window.location.href = player.media.currentSrc;
|
2627
|
-
}
|
2628
|
-
}
|
2629
|
-
]}
|
2630
|
-
);
|
2631
|
-
|
2632
|
-
|
2633
|
-
$.extend(MediaElementPlayer.prototype, {
|
2634
|
-
buildcontextmenu: function(player, controls, layers, media) {
|
2635
|
-
|
2636
|
-
// create context menu
|
2637
|
-
player.contextMenu = $('<div class="mejs-contextmenu"></div>')
|
2638
|
-
.appendTo($('body'))
|
2639
|
-
.hide();
|
2640
|
-
|
2641
|
-
// create events for showing context menu
|
2642
|
-
player.container.bind('contextmenu', function(e) {
|
2643
|
-
if (player.isContextMenuEnabled) {
|
2644
|
-
e.preventDefault();
|
2645
|
-
player.renderContextMenu(e.clientX-1, e.clientY-1);
|
2646
|
-
return false;
|
2647
|
-
}
|
2648
|
-
});
|
2649
|
-
player.container.bind('click', function() {
|
2650
|
-
player.contextMenu.hide();
|
2651
|
-
});
|
2652
|
-
player.contextMenu.bind('mouseleave', function() {
|
2653
|
-
|
2654
|
-
//console.log('context hover out');
|
2655
|
-
player.startContextMenuTimer();
|
2656
|
-
|
2657
|
-
});
|
2658
|
-
},
|
2659
|
-
|
2660
|
-
isContextMenuEnabled: true,
|
2661
|
-
enableContextMenu: function() {
|
2662
|
-
this.isContextMenuEnabled = true;
|
2663
|
-
},
|
2664
|
-
disableContextMenu: function() {
|
2665
|
-
this.isContextMenuEnabled = false;
|
2666
|
-
},
|
2667
|
-
|
2668
|
-
contextMenuTimeout: null,
|
2669
|
-
startContextMenuTimer: function() {
|
2670
|
-
//console.log('startContextMenuTimer');
|
2671
|
-
|
2672
|
-
var t = this;
|
2673
|
-
|
2674
|
-
t.killContextMenuTimer();
|
2675
|
-
|
2676
|
-
t.contextMenuTimer = setTimeout(function() {
|
2677
|
-
t.hideContextMenu();
|
2678
|
-
t.killContextMenuTimer();
|
2679
|
-
}, 750);
|
2680
|
-
},
|
2681
|
-
killContextMenuTimer: function() {
|
2682
|
-
var timer = this.contextMenuTimer;
|
2683
|
-
|
2684
|
-
//console.log('killContextMenuTimer', timer);
|
2685
|
-
|
2686
|
-
if (timer != null) {
|
2687
|
-
clearTimeout(timer);
|
2688
|
-
delete timer;
|
2689
|
-
timer = null;
|
2690
|
-
}
|
2691
|
-
},
|
2692
|
-
|
2693
|
-
hideContextMenu: function() {
|
2694
|
-
this.contextMenu.hide();
|
2695
|
-
},
|
2696
|
-
|
2697
|
-
renderContextMenu: function(x,y) {
|
2698
|
-
|
2699
|
-
// alway re-render the items so that things like "turn fullscreen on" and "turn fullscreen off" are always written correctly
|
2700
|
-
var t = this,
|
2701
|
-
html = '',
|
2702
|
-
items = t.options.contextMenuItems;
|
2703
|
-
|
2704
|
-
for (var i=0, il=items.length; i<il; i++) {
|
2705
|
-
|
2706
|
-
if (items[i].isSeparator) {
|
2707
|
-
html += '<div class="mejs-contextmenu-separator"></div>';
|
2708
|
-
} else {
|
2709
|
-
|
2710
|
-
var rendered = items[i].render(t);
|
2711
|
-
|
2712
|
-
// render can return null if the item doesn't need to be used at the moment
|
2713
|
-
if (rendered != null) {
|
2714
|
-
html += '<div class="mejs-contextmenu-item" data-itemindex="' + i + '" id="element-' + (Math.random()*1000000) + '">' + rendered + '</div>';
|
2715
|
-
}
|
2716
|
-
}
|
2717
|
-
}
|
2718
|
-
|
2719
|
-
// position and show the context menu
|
2720
|
-
t.contextMenu
|
2721
|
-
.empty()
|
2722
|
-
.append($(html))
|
2723
|
-
.css({top:y, left:x})
|
2724
|
-
.show();
|
2725
|
-
|
2726
|
-
// bind events
|
2727
|
-
t.contextMenu.find('.mejs-contextmenu-item').each(function() {
|
2728
|
-
|
2729
|
-
// which one is this?
|
2730
|
-
var $dom = $(this),
|
2731
|
-
itemIndex = parseInt( $dom.data('itemindex'), 10 ),
|
2732
|
-
item = t.options.contextMenuItems[itemIndex];
|
2733
|
-
|
2734
|
-
// bind extra functionality?
|
2735
|
-
if (typeof item.show != 'undefined')
|
2736
|
-
item.show( $dom , t);
|
2737
|
-
|
2738
|
-
// bind click action
|
2739
|
-
$dom.click(function() {
|
2740
|
-
// perform click action
|
2741
|
-
if (typeof item.click != 'undefined')
|
2742
|
-
item.click(t);
|
2743
|
-
|
2744
|
-
// close
|
2745
|
-
t.contextMenu.hide();
|
2746
|
-
});
|
2747
|
-
});
|
2748
|
-
|
2749
|
-
// stop the controls from hiding
|
2750
|
-
setTimeout(function() {
|
2751
|
-
t.killControlsTimer('rev3');
|
2752
|
-
}, 100);
|
2753
|
-
|
2754
|
-
}
|
2755
|
-
});
|
2756
|
-
|
2644
|
+
/*
|
2645
|
+
* ContextMenu Plugin
|
2646
|
+
*
|
2647
|
+
*
|
2648
|
+
*/
|
2649
|
+
|
2650
|
+
(function($) {
|
2651
|
+
|
2652
|
+
$.extend(mejs.MepDefaults,
|
2653
|
+
{ 'contextMenuItems': [
|
2654
|
+
// demo of a fullscreen option
|
2655
|
+
{
|
2656
|
+
render: function(player) {
|
2657
|
+
|
2658
|
+
// check for fullscreen plugin
|
2659
|
+
if (typeof player.enterFullScreen == 'undefined')
|
2660
|
+
return null;
|
2661
|
+
|
2662
|
+
if (player.isFullScreen) {
|
2663
|
+
return "Turn off Fullscreen";
|
2664
|
+
} else {
|
2665
|
+
return "Go Fullscreen";
|
2666
|
+
}
|
2667
|
+
},
|
2668
|
+
click: function(player) {
|
2669
|
+
if (player.isFullScreen) {
|
2670
|
+
player.exitFullScreen();
|
2671
|
+
} else {
|
2672
|
+
player.enterFullScreen();
|
2673
|
+
}
|
2674
|
+
}
|
2675
|
+
}
|
2676
|
+
,
|
2677
|
+
// demo of a mute/unmute button
|
2678
|
+
{
|
2679
|
+
render: function(player) {
|
2680
|
+
if (player.media.muted) {
|
2681
|
+
return "Unmute";
|
2682
|
+
} else {
|
2683
|
+
return "Mute";
|
2684
|
+
}
|
2685
|
+
},
|
2686
|
+
click: function(player) {
|
2687
|
+
if (player.media.muted) {
|
2688
|
+
player.setMuted(false);
|
2689
|
+
} else {
|
2690
|
+
player.setMuted(true);
|
2691
|
+
}
|
2692
|
+
}
|
2693
|
+
},
|
2694
|
+
// separator
|
2695
|
+
{
|
2696
|
+
isSeparator: true
|
2697
|
+
}
|
2698
|
+
,
|
2699
|
+
// demo of simple download video
|
2700
|
+
{
|
2701
|
+
render: function(player) {
|
2702
|
+
return "Download Video";
|
2703
|
+
},
|
2704
|
+
click: function(player) {
|
2705
|
+
window.location.href = player.media.currentSrc;
|
2706
|
+
}
|
2707
|
+
}
|
2708
|
+
]}
|
2709
|
+
);
|
2710
|
+
|
2711
|
+
|
2712
|
+
$.extend(MediaElementPlayer.prototype, {
|
2713
|
+
buildcontextmenu: function(player, controls, layers, media) {
|
2714
|
+
|
2715
|
+
// create context menu
|
2716
|
+
player.contextMenu = $('<div class="mejs-contextmenu"></div>')
|
2717
|
+
.appendTo($('body'))
|
2718
|
+
.hide();
|
2719
|
+
|
2720
|
+
// create events for showing context menu
|
2721
|
+
player.container.bind('contextmenu', function(e) {
|
2722
|
+
if (player.isContextMenuEnabled) {
|
2723
|
+
e.preventDefault();
|
2724
|
+
player.renderContextMenu(e.clientX-1, e.clientY-1);
|
2725
|
+
return false;
|
2726
|
+
}
|
2727
|
+
});
|
2728
|
+
player.container.bind('click', function() {
|
2729
|
+
player.contextMenu.hide();
|
2730
|
+
});
|
2731
|
+
player.contextMenu.bind('mouseleave', function() {
|
2732
|
+
|
2733
|
+
//console.log('context hover out');
|
2734
|
+
player.startContextMenuTimer();
|
2735
|
+
|
2736
|
+
});
|
2737
|
+
},
|
2738
|
+
|
2739
|
+
isContextMenuEnabled: true,
|
2740
|
+
enableContextMenu: function() {
|
2741
|
+
this.isContextMenuEnabled = true;
|
2742
|
+
},
|
2743
|
+
disableContextMenu: function() {
|
2744
|
+
this.isContextMenuEnabled = false;
|
2745
|
+
},
|
2746
|
+
|
2747
|
+
contextMenuTimeout: null,
|
2748
|
+
startContextMenuTimer: function() {
|
2749
|
+
//console.log('startContextMenuTimer');
|
2750
|
+
|
2751
|
+
var t = this;
|
2752
|
+
|
2753
|
+
t.killContextMenuTimer();
|
2754
|
+
|
2755
|
+
t.contextMenuTimer = setTimeout(function() {
|
2756
|
+
t.hideContextMenu();
|
2757
|
+
t.killContextMenuTimer();
|
2758
|
+
}, 750);
|
2759
|
+
},
|
2760
|
+
killContextMenuTimer: function() {
|
2761
|
+
var timer = this.contextMenuTimer;
|
2762
|
+
|
2763
|
+
//console.log('killContextMenuTimer', timer);
|
2764
|
+
|
2765
|
+
if (timer != null) {
|
2766
|
+
clearTimeout(timer);
|
2767
|
+
delete timer;
|
2768
|
+
timer = null;
|
2769
|
+
}
|
2770
|
+
},
|
2771
|
+
|
2772
|
+
hideContextMenu: function() {
|
2773
|
+
this.contextMenu.hide();
|
2774
|
+
},
|
2775
|
+
|
2776
|
+
renderContextMenu: function(x,y) {
|
2777
|
+
|
2778
|
+
// alway re-render the items so that things like "turn fullscreen on" and "turn fullscreen off" are always written correctly
|
2779
|
+
var t = this,
|
2780
|
+
html = '',
|
2781
|
+
items = t.options.contextMenuItems;
|
2782
|
+
|
2783
|
+
for (var i=0, il=items.length; i<il; i++) {
|
2784
|
+
|
2785
|
+
if (items[i].isSeparator) {
|
2786
|
+
html += '<div class="mejs-contextmenu-separator"></div>';
|
2787
|
+
} else {
|
2788
|
+
|
2789
|
+
var rendered = items[i].render(t);
|
2790
|
+
|
2791
|
+
// render can return null if the item doesn't need to be used at the moment
|
2792
|
+
if (rendered != null) {
|
2793
|
+
html += '<div class="mejs-contextmenu-item" data-itemindex="' + i + '" id="element-' + (Math.random()*1000000) + '">' + rendered + '</div>';
|
2794
|
+
}
|
2795
|
+
}
|
2796
|
+
}
|
2797
|
+
|
2798
|
+
// position and show the context menu
|
2799
|
+
t.contextMenu
|
2800
|
+
.empty()
|
2801
|
+
.append($(html))
|
2802
|
+
.css({top:y, left:x})
|
2803
|
+
.show();
|
2804
|
+
|
2805
|
+
// bind events
|
2806
|
+
t.contextMenu.find('.mejs-contextmenu-item').each(function() {
|
2807
|
+
|
2808
|
+
// which one is this?
|
2809
|
+
var $dom = $(this),
|
2810
|
+
itemIndex = parseInt( $dom.data('itemindex'), 10 ),
|
2811
|
+
item = t.options.contextMenuItems[itemIndex];
|
2812
|
+
|
2813
|
+
// bind extra functionality?
|
2814
|
+
if (typeof item.show != 'undefined')
|
2815
|
+
item.show( $dom , t);
|
2816
|
+
|
2817
|
+
// bind click action
|
2818
|
+
$dom.click(function() {
|
2819
|
+
// perform click action
|
2820
|
+
if (typeof item.click != 'undefined')
|
2821
|
+
item.click(t);
|
2822
|
+
|
2823
|
+
// close
|
2824
|
+
t.contextMenu.hide();
|
2825
|
+
});
|
2826
|
+
});
|
2827
|
+
|
2828
|
+
// stop the controls from hiding
|
2829
|
+
setTimeout(function() {
|
2830
|
+
t.killControlsTimer('rev3');
|
2831
|
+
}, 100);
|
2832
|
+
|
2833
|
+
}
|
2834
|
+
});
|
2835
|
+
|
2836
|
+
})(mejs.$);
|
2837
|
+
/**
|
2838
|
+
* Postroll plugin
|
2839
|
+
*/
|
2840
|
+
(function($) {
|
2841
|
+
|
2842
|
+
$.extend(mejs.MepDefaults, {
|
2843
|
+
postrollCloseText: mejs.i18n.t('Close')
|
2844
|
+
});
|
2845
|
+
|
2846
|
+
// Postroll
|
2847
|
+
$.extend(MediaElementPlayer.prototype, {
|
2848
|
+
buildpostroll: function(player, controls, layers, media) {
|
2849
|
+
var
|
2850
|
+
t = this,
|
2851
|
+
postrollLink = t.container.find('link[rel="postroll"]').attr('href');
|
2852
|
+
|
2853
|
+
if (typeof postrollLink !== 'undefined') {
|
2854
|
+
player.postroll =
|
2855
|
+
$('<div class="mejs-postroll-layer mejs-layer"><a class="mejs-postroll-close" onclick="$(this).parent().hide();return false;">' + t.options.postrollCloseText + '</a><div class="mejs-postroll-layer-content"></div></div>').prependTo(layers).hide();
|
2856
|
+
|
2857
|
+
t.media.addEventListener('ended', function (e) {
|
2858
|
+
$.ajax({
|
2859
|
+
dataType: 'html',
|
2860
|
+
url: postrollLink,
|
2861
|
+
success: function (data, textStatus) {
|
2862
|
+
layers.find('.mejs-postroll-layer-content').html(data);
|
2863
|
+
}
|
2864
|
+
});
|
2865
|
+
player.postroll.show();
|
2866
|
+
}, false);
|
2867
|
+
}
|
2868
|
+
}
|
2869
|
+
});
|
2870
|
+
|
2757
2871
|
})(mejs.$);
|