videojs-flash.cjs.js 38 KB

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