UNPKG

38.4 kBJavaScriptView Raw
1'use strict';
2
3function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
4
5var videojs = _interopDefault(require('video.js'));
6var videojsSwf_package_json = require('videojs-swf/package.json');
7var window = _interopDefault(require('global/window'));
8
9var version$1 = "2.0.1";
10
11/**
12 * @file flash-rtmp.js
13 * @module flash-rtmp
14 */
15
16/**
17 * Add RTMP properties to the {@link Flash} Tech.
18 *
19 * @param {Flash} Flash
20 * The flash tech class.
21 *
22 * @mixin FlashRtmpDecorator
23 *
24 * @return {Flash}
25 * The flash tech with RTMP properties added.
26 */
27function FlashRtmpDecorator(Flash) {
28 Flash.streamingFormats = {
29 'rtmp/mp4': 'MP4',
30 'rtmp/flv': 'FLV'
31 };
32
33 /**
34 * Join connection and stream with an ampersand.
35 *
36 * @param {string} connection
37 * The connection string.
38 *
39 * @param {string} stream
40 * The stream string.
41 *
42 * @return {string}
43 * The connection and stream joined with an `&` character
44 */
45 Flash.streamFromParts = function (connection, stream) {
46 return connection + '&' + stream;
47 };
48
49 /**
50 * The flash parts object that contains connection and stream info.
51 *
52 * @typedef {Object} Flash~PartsObject
53 *
54 * @property {string} connection
55 * The connection string of a source, defaults to an empty string.
56 *
57 * @property {string} stream
58 * The stream string of the source, defaults to an empty string.
59 */
60
61 /**
62 * Convert a source url into a stream and connection parts.
63 *
64 * @param {string} src
65 * the source url
66 *
67 * @return {Flash~PartsObject}
68 * The parts object that contains a connection and a stream
69 */
70 Flash.streamToParts = function (src) {
71 var parts = {
72 connection: '',
73 stream: ''
74 };
75
76 if (!src) {
77 return parts;
78 }
79
80 // Look for the normal URL separator we expect, '&'.
81 // If found, we split the URL into two pieces around the
82 // first '&'.
83 var connEnd = src.search(/&(?!\w+=)/);
84 var streamBegin = void 0;
85
86 if (connEnd !== -1) {
87 streamBegin = connEnd + 1;
88 } else {
89 // If there's not a '&', we use the last '/' as the delimiter.
90 connEnd = streamBegin = src.lastIndexOf('/') + 1;
91 if (connEnd === 0) {
92 // really, there's not a '/'?
93 connEnd = streamBegin = src.length;
94 }
95 }
96
97 parts.connection = src.substring(0, connEnd);
98 parts.stream = src.substring(streamBegin, src.length);
99
100 return parts;
101 };
102
103 /**
104 * Check if the source type is a streaming type.
105 *
106 * @param {string} srcType
107 * The mime type to check.
108 *
109 * @return {boolean}
110 * - True if the source type is a streaming type.
111 * - False if the source type is not a streaming type.
112 */
113 Flash.isStreamingType = function (srcType) {
114 return srcType in Flash.streamingFormats;
115 };
116
117 // RTMP has four variations, any string starting
118 // with one of these protocols should be valid
119
120 /**
121 * Regular expression used to check if the source is an rtmp source.
122 *
123 * @property {RegExp} Flash.RTMP_RE
124 */
125 Flash.RTMP_RE = /^rtmp[set]?:\/\//i;
126
127 /**
128 * Check if the source itself is a streaming type.
129 *
130 * @param {string} src
131 * The url to the source.
132 *
133 * @return {boolean}
134 * - True if the source url indicates that the source is streaming.
135 * - False if the shource url indicates that the source url is not streaming.
136 */
137 Flash.isStreamingSrc = function (src) {
138 return Flash.RTMP_RE.test(src);
139 };
140
141 /**
142 * A source handler for RTMP urls
143 * @type {Object}
144 */
145 Flash.rtmpSourceHandler = {};
146
147 /**
148 * Check if Flash can play the given mime type.
149 *
150 * @param {string} type
151 * The mime type to check
152 *
153 * @return {string}
154 * 'maybe', or '' (empty string)
155 */
156 Flash.rtmpSourceHandler.canPlayType = function (type) {
157 if (Flash.isStreamingType(type)) {
158 return 'maybe';
159 }
160
161 return '';
162 };
163
164 /**
165 * Check if Flash can handle the source natively
166 *
167 * @param {Object} source
168 * The source object
169 *
170 * @param {Object} [options]
171 * The options passed to the tech
172 *
173 * @return {string}
174 * 'maybe', or '' (empty string)
175 */
176 Flash.rtmpSourceHandler.canHandleSource = function (source, options) {
177 var can = Flash.rtmpSourceHandler.canPlayType(source.type);
178
179 if (can) {
180 return can;
181 }
182
183 if (Flash.isStreamingSrc(source.src)) {
184 return 'maybe';
185 }
186
187 return '';
188 };
189
190 /**
191 * Pass the source to the flash object.
192 *
193 * @param {Object} source
194 * The source object
195 *
196 * @param {Flash} tech
197 * The instance of the Flash tech
198 *
199 * @param {Object} [options]
200 * The options to pass to the source
201 */
202 Flash.rtmpSourceHandler.handleSource = function (source, tech, options) {
203 var srcParts = Flash.streamToParts(source.src);
204
205 tech.setRtmpConnection(srcParts.connection);
206 tech.setRtmpStream(srcParts.stream);
207 };
208
209 // Register the native source handler
210 Flash.registerSourceHandler(Flash.rtmpSourceHandler);
211
212 return Flash;
213}
214
215var classCallCheck = function (instance, Constructor) {
216 if (!(instance instanceof Constructor)) {
217 throw new TypeError("Cannot call a class as a function");
218 }
219};
220
221
222
223
224
225
226
227
228
229
230
231var inherits = function (subClass, superClass) {
232 if (typeof superClass !== "function" && superClass !== null) {
233 throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
234 }
235
236 subClass.prototype = Object.create(superClass && superClass.prototype, {
237 constructor: {
238 value: subClass,
239 enumerable: false,
240 writable: true,
241 configurable: true
242 }
243 });
244 if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
245};
246
247
248
249
250
251
252
253
254
255
256
257var possibleConstructorReturn = function (self, call) {
258 if (!self) {
259 throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
260 }
261
262 return call && (typeof call === "object" || typeof call === "function") ? call : self;
263};
264
265/**
266 * @file flash.js
267 * VideoJS-SWF - Custom Flash Player with HTML5-ish API
268 * https://github.com/zencoder/video-js-swf
269 * Not using setupTriggers. Using global onEvent func to distribute events
270 */
271
272var Tech = videojs.getComponent('Tech');
273var Dom = videojs.dom;
274var Url = videojs.url;
275var createTimeRange = videojs.createTimeRange;
276var mergeOptions = videojs.mergeOptions;
277
278var navigator = window && window.navigator || {};
279
280/**
281 * Flash Media Controller - Wrapper for Flash Media API
282 *
283 * @mixes FlashRtmpDecorator
284 * @mixes Tech~SouceHandlerAdditions
285 * @extends Tech
286 */
287
288var Flash = function (_Tech) {
289 inherits(Flash, _Tech);
290
291 /**
292 * Create an instance of this Tech.
293 *
294 * @param {Object} [options]
295 * The key/value store of player options.
296 *
297 * @param {Component~ReadyCallback} ready
298 * Callback function to call when the `Flash` Tech is ready.
299 */
300 function Flash(options, ready) {
301 classCallCheck(this, Flash);
302
303 // Set the source when ready
304 var _this = possibleConstructorReturn(this, _Tech.call(this, options, ready));
305
306 if (options.source) {
307 _this.ready(function () {
308 this.setSource(options.source);
309 }, true);
310 }
311
312 // Having issues with Flash reloading on certain page actions
313 // (hide/resize/fullscreen) in certain browsers
314 // This allows resetting the playhead when we catch the reload
315 if (options.startTime) {
316 _this.ready(function () {
317 this.load();
318 this.play();
319 this.currentTime(options.startTime);
320 }, true);
321 }
322
323 // Add global window functions that the swf expects
324 // A 4.x workflow we weren't able to solve for in 5.0
325 // because of the need to hard code these functions
326 // into the swf for security reasons
327 window.videojs = window.videojs || {};
328 window.videojs.Flash = window.videojs.Flash || {};
329 window.videojs.Flash.onReady = Flash.onReady;
330 window.videojs.Flash.onEvent = Flash.onEvent;
331 window.videojs.Flash.onError = Flash.onError;
332
333 _this.on('seeked', function () {
334 this.lastSeekTarget_ = undefined;
335 });
336
337 return _this;
338 }
339
340 /**
341 * Create the `Flash` Tech's DOM element.
342 *
343 * @return {Element}
344 * The element that gets created.
345 */
346
347
348 Flash.prototype.createEl = function createEl() {
349 var options = this.options_;
350
351 // If video.js is hosted locally you should also set the location
352 // for the hosted swf, which should be relative to the page (not video.js)
353 // Otherwise this adds a CDN url.
354 // The CDN also auto-adds a swf URL for that specific version.
355 if (!options.swf) {
356 options.swf = '//vjs.zencdn.net/swf/' + videojsSwf_package_json.version + '/video-js.swf';
357 }
358
359 // Generate ID for swf object
360 var objId = options.techId;
361
362 // Merge default flashvars with ones passed in to init
363 var flashVars = mergeOptions({
364
365 // SWF Callback Functions
366 readyFunction: 'videojs.Flash.onReady',
367 eventProxyFunction: 'videojs.Flash.onEvent',
368 errorEventProxyFunction: 'videojs.Flash.onError',
369
370 // Player Settings
371 autoplay: options.autoplay,
372 preload: options.preload,
373 loop: options.loop,
374 muted: options.muted
375
376 }, options.flashVars);
377
378 // Merge default parames with ones passed in
379 var params = mergeOptions({
380 // Opaque is needed to overlay controls, but can affect playback performance
381 wmode: 'opaque',
382 // Using bgcolor prevents a white flash when the object is loading
383 bgcolor: '#000000'
384 }, options.params);
385
386 // Merge default attributes with ones passed in
387 var attributes = mergeOptions({
388 // Both ID and Name needed or swf to identify itself
389 id: objId,
390 name: objId,
391 'class': 'vjs-tech'
392 }, options.attributes);
393
394 this.el_ = Flash.embed(options.swf, flashVars, params, attributes);
395 this.el_.tech = this;
396
397 return this.el_;
398 };
399
400 /**
401 * Called by {@link Player#play} to play using the `Flash` `Tech`.
402 */
403
404
405 Flash.prototype.play = function play() {
406 if (this.ended()) {
407 this.setCurrentTime(0);
408 }
409 this.el_.vjs_play();
410 };
411
412 /**
413 * Called by {@link Player#pause} to pause using the `Flash` `Tech`.
414 */
415
416
417 Flash.prototype.pause = function pause() {
418 this.el_.vjs_pause();
419 };
420
421 /**
422 * A getter/setter for the `Flash` Tech's source object.
423 * > Note: Please use {@link Flash#setSource}
424 *
425 * @param {Tech~SourceObject} [src]
426 * The source object you want to set on the `Flash` techs.
427 *
428 * @return {Tech~SourceObject|undefined}
429 * - The current source object when a source is not passed in.
430 * - undefined when setting
431 *
432 * @deprecated Since version 5.
433 */
434
435
436 Flash.prototype.src = function src(_src) {
437 if (_src === undefined) {
438 return this.currentSrc();
439 }
440
441 // Setting src through `src` not `setSrc` will be deprecated
442 return this.setSrc(_src);
443 };
444
445 /**
446 * A getter/setter for the `Flash` Tech's source object.
447 *
448 * @param {Tech~SourceObject} [src]
449 * The source object you want to set on the `Flash` techs.
450 */
451
452
453 Flash.prototype.setSrc = function setSrc(src) {
454 var _this2 = this;
455
456 // Make sure source URL is absolute.
457 src = Url.getAbsoluteURL(src);
458 this.el_.vjs_src(src);
459
460 // Currently the SWF doesn't autoplay if you load a source later.
461 // e.g. Load player w/ no source, wait 2s, set src.
462 if (this.autoplay()) {
463 this.setTimeout(function () {
464 return _this2.play();
465 }, 0);
466 }
467 };
468
469 /**
470 * Indicates whether the media is currently seeking to a new position or not.
471 *
472 * @return {boolean}
473 * - True if seeking to a new position
474 * - False otherwise
475 */
476
477
478 Flash.prototype.seeking = function seeking() {
479 return this.lastSeekTarget_ !== undefined;
480 };
481
482 /**
483 * Returns the current time in seconds that the media is at in playback.
484 *
485 * @param {number} time
486 * Current playtime of the media in seconds.
487 */
488
489
490 Flash.prototype.setCurrentTime = function setCurrentTime(time) {
491 var seekable = this.seekable();
492
493 if (seekable.length) {
494 // clamp to the current seekable range
495 time = time > seekable.start(0) ? time : seekable.start(0);
496 time = time < seekable.end(seekable.length - 1) ? time : seekable.end(seekable.length - 1);
497
498 this.lastSeekTarget_ = time;
499 this.trigger('seeking');
500 this.el_.vjs_setProperty('currentTime', time);
501 _Tech.prototype.setCurrentTime.call(this);
502 }
503 };
504
505 /**
506 * Get the current playback time in seconds
507 *
508 * @return {number}
509 * The current time of playback in seconds.
510 */
511
512
513 Flash.prototype.currentTime = function currentTime() {
514 // when seeking make the reported time keep up with the requested time
515 // by reading the time we're seeking to
516 if (this.seeking()) {
517 return this.lastSeekTarget_ || 0;
518 }
519 return this.el_.vjs_getProperty('currentTime');
520 };
521
522 /**
523 * Get the current source
524 *
525 * @method currentSrc
526 * @return {Tech~SourceObject}
527 * The current source
528 */
529
530
531 Flash.prototype.currentSrc = function currentSrc() {
532 if (this.currentSource_) {
533 return this.currentSource_.src;
534 }
535 return this.el_.vjs_getProperty('currentSrc');
536 };
537
538 /**
539 * Get the total duration of the current media.
540 *
541 * @return {number}
542 8 The total duration of the current media.
543 */
544
545
546 Flash.prototype.duration = function duration() {
547 if (this.readyState() === 0) {
548 return NaN;
549 }
550 var duration = this.el_.vjs_getProperty('duration');
551
552 return duration >= 0 ? duration : Infinity;
553 };
554
555 /**
556 * Load media into Tech.
557 */
558
559
560 Flash.prototype.load = function load() {
561 this.el_.vjs_load();
562 };
563
564 /**
565 * Get the poster image that was set on the tech.
566 */
567
568
569 Flash.prototype.poster = function poster() {
570 this.el_.vjs_getProperty('poster');
571 };
572
573 /**
574 * Poster images are not handled by the Flash tech so make this is a no-op.
575 */
576
577
578 Flash.prototype.setPoster = function setPoster() {};
579
580 /**
581 * Determine the time ranges that can be seeked to in the media.
582 *
583 * @return {TimeRange}
584 * Returns the time ranges that can be seeked to.
585 */
586
587
588 Flash.prototype.seekable = function seekable() {
589 var duration = this.duration();
590
591 if (duration === 0) {
592 return createTimeRange();
593 }
594 return createTimeRange(0, duration);
595 };
596
597 /**
598 * Get and create a `TimeRange` object for buffering.
599 *
600 * @return {TimeRange}
601 * The time range object that was created.
602 */
603
604
605 Flash.prototype.buffered = function buffered() {
606 var ranges = this.el_.vjs_getProperty('buffered');
607
608 if (ranges.length === 0) {
609 return createTimeRange();
610 }
611 return createTimeRange(ranges[0][0], ranges[0][1]);
612 };
613
614 /**
615 * Get fullscreen support -
616 *
617 * Flash does not allow fullscreen through javascript
618 * so this always returns false.
619 *
620 * @return {boolean}
621 * The Flash tech does not support fullscreen, so it will always return false.
622 */
623
624
625 Flash.prototype.supportsFullScreen = function supportsFullScreen() {
626 // Flash does not allow fullscreen through javascript
627 return false;
628 };
629
630 /**
631 * Flash does not allow fullscreen through javascript
632 * so this always returns false.
633 *
634 * @return {boolean}
635 * The Flash tech does not support fullscreen, so it will always return false.
636 */
637
638
639 Flash.prototype.enterFullScreen = function enterFullScreen() {
640 return false;
641 };
642
643 /**
644 * Gets available media playback quality metrics as specified by the W3C's Media
645 * Playback Quality API.
646 *
647 * @see [Spec]{@link https://wicg.github.io/media-playback-quality}
648 *
649 * @return {Object}
650 * An object with supported media playback quality metrics
651 */
652
653
654 Flash.prototype.getVideoPlaybackQuality = function getVideoPlaybackQuality() {
655 var videoPlaybackQuality = this.el_.vjs_getProperty('getVideoPlaybackQuality');
656
657 if (window.performance && typeof window.performance.now === 'function') {
658 videoPlaybackQuality.creationTime = window.performance.now();
659 } else if (window.performance && window.performance.timing && typeof window.performance.timing.navigationStart === 'number') {
660 videoPlaybackQuality.creationTime = window.Date.now() - window.performance.timing.navigationStart;
661 }
662
663 return videoPlaybackQuality;
664 };
665
666 return Flash;
667}(Tech);
668
669// Create setters and getters for attributes
670
671
672var _readWrite = ['rtmpConnection', 'rtmpStream', 'preload', 'defaultPlaybackRate', 'playbackRate', 'autoplay', 'loop', 'controls', 'volume', 'muted', 'defaultMuted'];
673var _readOnly = ['networkState', 'readyState', 'initialTime', 'startOffsetTime', 'paused', 'ended', 'videoWidth', 'videoHeight'];
674var _api = Flash.prototype;
675
676/**
677 * Create setters for the swf on the element
678 *
679 * @param {string} attr
680 * The name of the parameter
681 *
682 * @private
683 */
684function _createSetter(attr) {
685 var attrUpper = attr.charAt(0).toUpperCase() + attr.slice(1);
686
687 _api['set' + attrUpper] = function (val) {
688 return this.el_.vjs_setProperty(attr, val);
689 };
690}
691
692/**
693 * Create petters for the swf on the element
694 *
695 * @param {string} attr
696 * The name of the parameter
697 *
698 * @private
699 */
700function _createGetter(attr) {
701 _api[attr] = function () {
702 return this.el_.vjs_getProperty(attr);
703 };
704}
705
706// Create getter and setters for all read/write attributes
707for (var i = 0; i < _readWrite.length; i++) {
708 _createGetter(_readWrite[i]);
709 _createSetter(_readWrite[i]);
710}
711
712// Create getters for read-only attributes
713for (var _i = 0; _i < _readOnly.length; _i++) {
714 _createGetter(_readOnly[_i]);
715}
716
717/** ------------------------------ Getters ------------------------------ **/
718/**
719 * Get the value of `rtmpConnection` from the swf.
720 *
721 * @method Flash#rtmpConnection
722 * @return {string}
723 * The current value of `rtmpConnection` on the swf.
724 */
725
726/**
727 * Get the value of `rtmpStream` from the swf.
728 *
729 * @method Flash#rtmpStream
730 * @return {string}
731 * The current value of `rtmpStream` on the swf.
732 */
733
734/**
735 * Get the value of `preload` from the swf. `preload` indicates
736 * what should download before the media is interacted with. It can have the following
737 * values:
738 * - none: nothing should be downloaded
739 * - metadata: poster and the first few frames of the media may be downloaded to get
740 * media dimensions and other metadata
741 * - auto: allow the media and metadata for the media to be downloaded before
742 * interaction
743 *
744 * @method Flash#preload
745 * @return {string}
746 * The value of `preload` from the swf. Will be 'none', 'metadata',
747 * or 'auto'.
748 */
749
750/**
751 * Get the value of `defaultPlaybackRate` from the swf.
752 *
753 * @method Flash#defaultPlaybackRate
754 * @return {number}
755 * The current value of `defaultPlaybackRate` on the swf.
756 */
757
758/**
759 * Get the value of `playbackRate` from the swf. `playbackRate` indicates
760 * the rate at which the media is currently playing back. Examples:
761 * - if playbackRate is set to 2, media will play twice as fast.
762 * - if playbackRate is set to 0.5, media will play half as fast.
763 *
764 * @method Flash#playbackRate
765 * @return {number}
766 * The value of `playbackRate` from the swf. A number indicating
767 * the current playback speed of the media, where 1 is normal speed.
768 */
769
770/**
771 * Get the value of `autoplay` from the swf. `autoplay` indicates
772 * that the media should start to play as soon as the page is ready.
773 *
774 * @method Flash#autoplay
775 * @return {boolean}
776 * - The value of `autoplay` from the swf.
777 * - True indicates that the media ashould start as soon as the page loads.
778 * - False indicates that the media should not start as soon as the page loads.
779 */
780
781/**
782 * Get the value of `loop` from the swf. `loop` indicates
783 * that the media should return to the start of the media and continue playing once
784 * it reaches the end.
785 *
786 * @method Flash#loop
787 * @return {boolean}
788 * - The value of `loop` from the swf.
789 * - True indicates that playback should seek back to start once
790 * the end of a media is reached.
791 * - False indicates that playback should not loop back to the start when the
792 * end of the media is reached.
793 */
794
795/**
796 * Get the value of `mediaGroup` from the swf.
797 *
798 * @method Flash#mediaGroup
799 * @return {string}
800 * The current value of `mediaGroup` on the swf.
801 */
802
803/**
804 * Get the value of `controller` from the swf.
805 *
806 * @method Flash#controller
807 * @return {string}
808 * The current value of `controller` on the swf.
809 */
810
811/**
812 * Get the value of `controls` from the swf. `controls` indicates
813 * whether the native flash controls should be shown or hidden.
814 *
815 * @method Flash#controls
816 * @return {boolean}
817 * - The value of `controls` from the swf.
818 * - True indicates that native controls should be showing.
819 * - False indicates that native controls should be hidden.
820 */
821
822/**
823 * Get the value of the `volume` from the swf. `volume` indicates the current
824 * audio level as a percentage in decimal form. This means that 1 is 100%, 0.5 is 50%, and
825 * so on.
826 *
827 * @method Flash#volume
828 * @return {number}
829 * The volume percent as a decimal. Value will be between 0-1.
830 */
831
832/**
833 * Get the value of the `muted` from the swf. `muted` indicates the current
834 * audio level should be silent.
835 *
836 * @method Flash#muted
837 * @return {boolean}
838 * - True if the audio should be set to silent
839 * - False otherwise
840 */
841
842/**
843 * Get the value of `defaultMuted` from the swf. `defaultMuted` indicates
844 * whether the media should start muted or not. Only changes the default state of the
845 * media. `muted` and `defaultMuted` can have different values. `muted` indicates the
846 * current state.
847 *
848 * @method Flash#defaultMuted
849 * @return {boolean}
850 * - The value of `defaultMuted` from the swf.
851 * - True indicates that the media should start muted.
852 * - False indicates that the media should not start muted.
853 */
854
855/**
856 * Get the value of `networkState` from the swf. `networkState` indicates
857 * the current network state. It returns an enumeration from the following list:
858 * - 0: NETWORK_EMPTY
859 * - 1: NEWORK_IDLE
860 * - 2: NETWORK_LOADING
861 * - 3: NETWORK_NO_SOURCE
862 *
863 * @method Flash#networkState
864 * @return {number}
865 * The value of `networkState` from the swf. This will be a number
866 * from the list in the description.
867 */
868
869/**
870 * Get the value of `readyState` from the swf. `readyState` indicates
871 * the current state of the media element. It returns an enumeration from the
872 * following list:
873 * - 0: HAVE_NOTHING
874 * - 1: HAVE_METADATA
875 * - 2: HAVE_CURRENT_DATA
876 * - 3: HAVE_FUTURE_DATA
877 * - 4: HAVE_ENOUGH_DATA
878 *
879 * @method Flash#readyState
880 * @return {number}
881 * The value of `readyState` from the swf. This will be a number
882 * from the list in the description.
883 */
884
885/**
886 * Get the value of `readyState` from the swf. `readyState` indicates
887 * the current state of the media element. It returns an enumeration from the
888 * following list:
889 * - 0: HAVE_NOTHING
890 * - 1: HAVE_METADATA
891 * - 2: HAVE_CURRENT_DATA
892 * - 3: HAVE_FUTURE_DATA
893 * - 4: HAVE_ENOUGH_DATA
894 *
895 * @method Flash#readyState
896 * @return {number}
897 * The value of `readyState` from the swf. This will be a number
898 * from the list in the description.
899 */
900
901/**
902 * Get the value of `initialTime` from the swf.
903 *
904 * @method Flash#initialTime
905 * @return {number}
906 * The `initialTime` proprety on the swf.
907 */
908
909/**
910 * Get the value of `startOffsetTime` from the swf.
911 *
912 * @method Flash#startOffsetTime
913 * @return {number}
914 * The `startOffsetTime` proprety on the swf.
915 */
916
917/**
918 * Get the value of `paused` from the swf. `paused` indicates whether the swf
919 * is current paused or not.
920 *
921 * @method Flash#paused
922 * @return {boolean}
923 * The value of `paused` from the swf.
924 */
925
926/**
927 * Get the value of `ended` from the swf. `ended` indicates whether
928 * the media has reached the end or not.
929 *
930 * @method Flash#ended
931 * @return {boolean}
932 * - True indicates that the media has ended.
933 * - False indicates that the media has not ended.
934 *
935 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-ended}
936 */
937
938/**
939 * Get the value of `videoWidth` from the swf. `videoWidth` indicates
940 * the current width of the media in css pixels.
941 *
942 * @method Flash#videoWidth
943 * @return {number}
944 * The value of `videoWidth` from the swf. This will be a number
945 * in css pixels.
946 */
947
948/**
949 * Get the value of `videoHeight` from the swf. `videoHeigth` indicates
950 * the current height of the media in css pixels.
951 *
952 * @method Flassh.prototype.videoHeight
953 * @return {number}
954 * The value of `videoHeight` from the swf. This will be a number
955 * in css pixels.
956 */
957/** ------------------------------ Setters ------------------------------ **/
958
959/**
960 * Set the value of `rtmpConnection` on the swf.
961 *
962 * @method Flash#setRtmpConnection
963 * @param {string} rtmpConnection
964 * New value to set the `rtmpConnection` property to.
965 */
966
967/**
968 * Set the value of `rtmpStream` on the swf.
969 *
970 * @method Flash#setRtmpStream
971 * @param {string} rtmpStream
972 * New value to set the `rtmpStream` property to.
973 */
974
975/**
976 * Set the value of `preload` on the swf. `preload` indicates
977 * what should download before the media is interacted with. It can have the following
978 * values:
979 * - none: nothing should be downloaded
980 * - metadata: poster and the first few frames of the media may be downloaded to get
981 * media dimensions and other metadata
982 * - auto: allow the media and metadata for the media to be downloaded before
983 * interaction
984 *
985 * @method Flash#setPreload
986 * @param {string} preload
987 * The value of `preload` to set on the swf. Should be 'none', 'metadata',
988 * or 'auto'.
989 */
990
991/**
992 * Set the value of `defaultPlaybackRate` on the swf.
993 *
994 * @method Flash#setDefaultPlaybackRate
995 * @param {number} defaultPlaybackRate
996 * New value to set the `defaultPlaybackRate` property to.
997 */
998
999/**
1000 * Set the value of `playbackRate` on the swf. `playbackRate` indicates
1001 * the rate at which the media is currently playing back. Examples:
1002 * - if playbackRate is set to 2, media will play twice as fast.
1003 * - if playbackRate is set to 0.5, media will play half as fast.
1004 *
1005 * @method Flash#setPlaybackRate
1006 * @param {number} playbackRate
1007 * New value of `playbackRate` on the swf. A number indicating
1008 * the current playback speed of the media, where 1 is normal speed.
1009 */
1010
1011/**
1012 * Set the value of `autoplay` on the swf. `autoplay` indicates
1013 * that the media should start to play as soon as the page is ready.
1014 *
1015 * @method Flash#setAutoplay
1016 * @param {boolean} autoplay
1017 * - The value of `autoplay` from the swf.
1018 * - True indicates that the media ashould start as soon as the page loads.
1019 * - False indicates that the media should not start as soon as the page loads.
1020 */
1021
1022/**
1023 * Set the value of `loop` on the swf. `loop` indicates
1024 * that the media should return to the start of the media and continue playing once
1025 * it reaches the end.
1026 *
1027 * @method Flash#setLoop
1028 * @param {boolean} loop
1029 * - True indicates that playback should seek back to start once
1030 * the end of a media is reached.
1031 * - False indicates that playback should not loop back to the start when the
1032 * end of the media is reached.
1033 */
1034
1035/**
1036 * Set the value of `mediaGroup` on the swf.
1037 *
1038 * @method Flash#setMediaGroup
1039 * @param {string} mediaGroup
1040 * New value of `mediaGroup` to set on the swf.
1041 */
1042
1043/**
1044 * Set the value of `controller` on the swf.
1045 *
1046 * @method Flash#setController
1047 * @param {string} controller
1048 * New value the current value of `controller` on the swf.
1049 */
1050
1051/**
1052 * Get the value of `controls` from the swf. `controls` indicates
1053 * whether the native flash controls should be shown or hidden.
1054 *
1055 * @method Flash#controls
1056 * @return {boolean}
1057 * - The value of `controls` from the swf.
1058 * - True indicates that native controls should be showing.
1059 * - False indicates that native controls should be hidden.
1060 */
1061
1062/**
1063 * Set the value of the `volume` on the swf. `volume` indicates the current
1064 * audio level as a percentage in decimal form. This means that 1 is 100%, 0.5 is 50%, and
1065 * so on.
1066 *
1067 * @method Flash#setVolume
1068 * @param {number} percentAsDecimal
1069 * The volume percent as a decimal. Value will be between 0-1.
1070 */
1071
1072/**
1073 * Set the value of the `muted` on the swf. `muted` indicates that the current
1074 * audio level should be silent.
1075 *
1076 * @method Flash#setMuted
1077 * @param {boolean} muted
1078 * - True if the audio should be set to silent
1079 * - False otherwise
1080 */
1081
1082/**
1083 * Set the value of `defaultMuted` on the swf. `defaultMuted` indicates
1084 * whether the media should start muted or not. Only changes the default state of the
1085 * media. `muted` and `defaultMuted` can have different values. `muted` indicates the
1086 * current state.
1087 *
1088 * @method Flash#setDefaultMuted
1089 * @param {boolean} defaultMuted
1090 * - True indicates that the media should start muted.
1091 * - False indicates that the media should not start muted.
1092 */
1093
1094/* Flash Support Testing -------------------------------------------------------- */
1095
1096/**
1097 * Check if the Flash tech is currently supported.
1098 *
1099 * @return {boolean}
1100 * - True if the flash tech is supported.
1101 * - False otherwise.
1102 */
1103Flash.isSupported = function () {
1104 return Flash.version()[0] >= 10;
1105 // return swfobject.hasFlashPlayerVersion('10');
1106};
1107
1108// Add Source Handler pattern functions to this tech
1109Tech.withSourceHandlers(Flash);
1110
1111/*
1112 * Native source handler for flash, simply passes the source to the swf element.
1113 *
1114 * @property {Tech~SourceObject} source
1115 * The source object
1116 *
1117 * @property {Flash} tech
1118 * The instance of the Flash tech
1119 */
1120Flash.nativeSourceHandler = {};
1121
1122/**
1123 * Check if the Flash can play the given mime type.
1124 *
1125 * @param {string} type
1126 * The mimetype to check
1127 *
1128 * @return {string}
1129 * 'maybe', or '' (empty string)
1130 */
1131Flash.nativeSourceHandler.canPlayType = function (type) {
1132 if (type in Flash.formats) {
1133 return 'maybe';
1134 }
1135
1136 return '';
1137};
1138
1139/**
1140 * Check if the media element can handle a source natively.
1141 *
1142 * @param {Tech~SourceObject} source
1143 * The source object
1144 *
1145 * @param {Object} [options]
1146 * Options to be passed to the tech.
1147 *
1148 * @return {string}
1149 * 'maybe', or '' (empty string).
1150 */
1151Flash.nativeSourceHandler.canHandleSource = function (source, options) {
1152 var type = void 0;
1153
1154 /**
1155 * Guess the mime type of a file if it does not have one
1156 *
1157 * @param {Tech~SourceObject} src
1158 * The source object to guess the mime type for
1159 *
1160 * @return {string}
1161 * The mime type that was guessed
1162 */
1163 function guessMimeType(src) {
1164 var ext = Url.getFileExtension(src);
1165
1166 if (ext) {
1167 return 'video/' + ext;
1168 }
1169 return '';
1170 }
1171
1172 if (!source.type) {
1173 type = guessMimeType(source.src);
1174 } else {
1175 // Strip code information from the type because we don't get that specific
1176 type = source.type.replace(/;.*/, '').toLowerCase();
1177 }
1178
1179 return Flash.nativeSourceHandler.canPlayType(type);
1180};
1181
1182/**
1183 * Pass the source to the swf.
1184 *
1185 * @param {Tech~SourceObject} source
1186 * The source object
1187 *
1188 * @param {Flash} tech
1189 * The instance of the Flash tech
1190 *
1191 * @param {Object} [options]
1192 * The options to pass to the source
1193 */
1194Flash.nativeSourceHandler.handleSource = function (source, tech, options) {
1195 tech.setSrc(source.src);
1196};
1197
1198/**
1199 * noop for native source handler dispose, as cleanup will happen automatically.
1200 */
1201Flash.nativeSourceHandler.dispose = function () {};
1202
1203// Register the native source handler
1204Flash.registerSourceHandler(Flash.nativeSourceHandler);
1205
1206/**
1207 * Flash supported mime types.
1208 *
1209 * @constant {Object}
1210 */
1211Flash.formats = {
1212 'video/flv': 'FLV',
1213 'video/x-flv': 'FLV',
1214 'video/mp4': 'MP4',
1215 'video/m4v': 'MP4'
1216};
1217
1218/**
1219 * Called when the the swf is "ready", and makes sure that the swf is really
1220 * ready using {@link Flash#checkReady}
1221 *
1222 * @param {Object} currSwf
1223 * The current swf object
1224 */
1225Flash.onReady = function (currSwf) {
1226 var el = Dom.$('#' + currSwf);
1227 var tech = el && el.tech;
1228
1229 // if there is no el then the tech has been disposed
1230 // and the tech element was removed from the player div
1231 if (tech && tech.el()) {
1232 // check that the flash object is really ready
1233 Flash.checkReady(tech);
1234 }
1235};
1236
1237/**
1238 * The SWF isn't always ready when it says it is. Sometimes the API functions still
1239 * need to be added to the object. If it's not ready, we set a timeout to check again
1240 * shortly.
1241 *
1242 * @param {Flash} tech
1243 * The instance of the flash tech to check.
1244 */
1245Flash.checkReady = function (tech) {
1246 // stop worrying if the tech has been disposed
1247 if (!tech.el()) {
1248 return;
1249 }
1250
1251 // check if API property exists
1252 if (tech.el().vjs_getProperty) {
1253 // tell tech it's ready
1254 tech.triggerReady();
1255 } else {
1256 // wait longer
1257 this.setTimeout(function () {
1258 Flash.checkReady(tech);
1259 }, 50);
1260 }
1261};
1262
1263/**
1264 * Trigger events from the swf on the Flash Tech.
1265 *
1266 * @param {number} swfID
1267 * The id of the swf that had the event
1268 *
1269 * @param {string} eventName
1270 * The name of the event to trigger
1271 */
1272Flash.onEvent = function (swfID, eventName) {
1273 var tech = Dom.$('#' + swfID).tech;
1274 var args = Array.prototype.slice.call(arguments, 2);
1275
1276 // dispatch Flash events asynchronously for two reasons:
1277 // - Flash swallows any exceptions generated by javascript it
1278 // invokes
1279 // - Flash is suspended until the javascript returns which may cause
1280 // playback performance issues
1281 tech.setTimeout(function () {
1282 tech.trigger(eventName, args);
1283 }, 1);
1284};
1285
1286/**
1287 * Log errors from the swf on the Flash tech.
1288 *
1289 * @param {number} swfID
1290 * The id of the swf that had an error.
1291 *
1292 * @param {string} err
1293 * The error to set on the Flash Tech.
1294 *
1295 * @return {MediaError|undefined}
1296 * - Returns a MediaError when err is 'srcnotfound'
1297 * - Returns undefined otherwise.
1298 */
1299Flash.onError = function (swfID, err) {
1300 var tech = Dom.$('#' + swfID).tech;
1301
1302 // trigger MEDIA_ERR_SRC_NOT_SUPPORTED
1303 if (err === 'srcnotfound') {
1304 return tech.error(4);
1305 }
1306
1307 // trigger a custom error
1308 tech.error('FLASH: ' + err);
1309};
1310
1311/**
1312 * Get the current version of Flash that is in use on the page.
1313 *
1314 * @return {Array}
1315 * an array of versions that are available.
1316 */
1317Flash.version = function () {
1318 var version$$1 = '0,0,0';
1319
1320 // IE
1321 try {
1322 version$$1 = new window.ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version').replace(/\D+/g, ',').match(/^,?(.+),?$/)[1];
1323
1324 // other browsers
1325 } catch (e) {
1326 try {
1327 if (navigator.mimeTypes['application/x-shockwave-flash'].enabledPlugin) {
1328 version$$1 = (navigator.plugins['Shockwave Flash 2.0'] || navigator.plugins['Shockwave Flash']).description.replace(/\D+/g, ',').match(/^,?(.+),?$/)[1];
1329 }
1330 } catch (err) {
1331 // satisfy linter
1332 }
1333 }
1334 return version$$1.split(',');
1335};
1336
1337/**
1338 * Only use for non-iframe embeds.
1339 *
1340 * @param {Object} swf
1341 * The videojs-swf object.
1342 *
1343 * @param {Object} flashVars
1344 * Names and values to use as flash option variables.
1345 *
1346 * @param {Object} params
1347 * Style parameters to set on the object.
1348 *
1349 * @param {Object} attributes
1350 * Attributes to set on the element.
1351 *
1352 * @return {Element}
1353 * The embeded Flash DOM element.
1354 */
1355Flash.embed = function (swf, flashVars, params, attributes) {
1356 var code = Flash.getEmbedCode(swf, flashVars, params, attributes);
1357
1358 // Get element by embedding code and retrieving created element
1359 var obj = Dom.createEl('div', { innerHTML: code }).childNodes[0];
1360
1361 return obj;
1362};
1363
1364/**
1365 * Only use for non-iframe embeds.
1366 *
1367 * @param {Object} swf
1368 * The videojs-swf object.
1369 *
1370 * @param {Object} flashVars
1371 * Names and values to use as flash option variables.
1372 *
1373 * @param {Object} params
1374 * Style parameters to set on the object.
1375 *
1376 * @param {Object} attributes
1377 * Attributes to set on the element.
1378 *
1379 * @return {Element}
1380 * The embeded Flash DOM element.
1381 */
1382Flash.getEmbedCode = function (swf, flashVars, params, attributes) {
1383 var objTag = '<object type="application/x-shockwave-flash" ';
1384 var flashVarsString = '';
1385 var paramsString = '';
1386 var attrsString = '';
1387
1388 // Convert flash vars to string
1389 if (flashVars) {
1390 Object.getOwnPropertyNames(flashVars).forEach(function (key) {
1391 flashVarsString += key + '=' + flashVars[key] + '&amp;';
1392 });
1393 }
1394
1395 // Add swf, flashVars, and other default params
1396 params = mergeOptions({
1397 movie: swf,
1398 flashvars: flashVarsString,
1399 // Required to talk to swf
1400 allowScriptAccess: 'always',
1401 // All should be default, but having security issues.
1402 allowNetworking: 'all'
1403 }, params);
1404
1405 // Create param tags string
1406 Object.getOwnPropertyNames(params).forEach(function (key) {
1407 paramsString += '<param name="' + key + '" value="' + params[key] + '" />';
1408 });
1409
1410 attributes = mergeOptions({
1411 // Add swf to attributes (need both for IE and Others to work)
1412 data: swf,
1413
1414 // Default to 100% width/height
1415 width: '100%',
1416 height: '100%'
1417
1418 }, attributes);
1419
1420 // Create Attributes string
1421 Object.getOwnPropertyNames(attributes).forEach(function (key) {
1422 attrsString += key + '="' + attributes[key] + '" ';
1423 });
1424
1425 return '' + objTag + attrsString + '>' + paramsString + '</object>';
1426};
1427
1428// Run Flash through the RTMP decorator
1429FlashRtmpDecorator(Flash);
1430
1431if (Tech.getTech('Flash')) {
1432 videojs.log.warn('Not using videojs-flash as it appears to already be registered');
1433 videojs.log.warn('videojs-flash should only be used with video.js@6 and above');
1434} else {
1435 videojs.registerTech('Flash', Flash);
1436}
1437
1438Flash.VERSION = version$1;
1439
1440module.exports = Flash;