1
0
Fork 0
mirror of https://github.com/DanielnetoDotCom/YouPHPTube synced 2025-10-03 01:39:24 +02:00

Moving to node_modules folder to make easier to upgrade

trying to move from Bootstrap 3 to Bootstrap 5
This commit is contained in:
Daniel 2021-10-26 14:52:45 -03:00
parent 047e363a16
commit d4d042e041
8460 changed files with 1355889 additions and 547977 deletions

287
node_modules/videojs-ima/CHANGELOG.md generated vendored Normal file
View file

@ -0,0 +1,287 @@
<a name="1.11.0"></a>
# [1.11.0](https://github.com/googleads/videojs-ima/compare/v1.10.1...v1.11.0) (2021-05-07)
<a name="1.10.1"></a>
## [1.10.1](https://github.com/googleads/videojs-ima/compare/v1.10.0...v1.10.1) (2021-03-31)
<a name="1.10.0"></a>
# [1.10.0](https://github.com/googleads/videojs-ima/compare/v1.9.1...v1.10.0) (2021-03-23)
<a name="1.9.1"></a>
## [1.9.1](https://github.com/googleads/videojs-ima/compare/v1.9.0...v1.9.1) (2021-01-13)
<a name="1.9.0"></a>
# [1.9.0](https://github.com/googleads/videojs-ima/compare/v1.8.3...v1.9.0) (2020-11-18)
<a name="1.8.3"></a>
## [1.8.3](https://github.com/googleads/videojs-ima/compare/v1.8.2...v1.8.3) (2020-10-14)
<a name="1.8.2"></a>
## [1.8.2](https://github.com/googleads/videojs-ima/compare/v1.8.1...v1.8.2) (2020-10-14)
<a name="1.8.1"></a>
## [1.8.1](https://github.com/googleads/videojs-ima/compare/v1.8.0...v1.8.1) (2020-08-05)
### Bug Fixes
* updates urls in README ([63043a0](https://github.com/googleads/videojs-ima/commit/63043a0))
<a name="1.8.0"></a>
# [1.8.0](https://github.com/googleads/videojs-ima/compare/v1.7.5...v1.8.0) (2020-03-03)
<a name="1.7.5"></a>
## [1.7.5](https://github.com/googleads/videojs-ima/compare/v1.7.4...v1.7.5) (2020-02-24)
<a name="1.7.4"></a>
## [1.7.4](https://github.com/googleads/videojs-ima/compare/v1.7.3...v1.7.4) (2019-12-12)
<a name="1.7.3"></a>
## [1.7.3](https://github.com/googleads/videojs-ima/compare/v1.7.0...v1.7.3) (2019-12-12)
<a name="1.7.0"></a>
# [1.7.0](https://github.com/googleads/videojs-ima/compare/v1.6.3...v1.7.0) (2019-10-04)
### Features
* adds IMA events ([229b771](https://github.com/googleads/videojs-ima/commit/229b771))
### Bug Fixes
* fixes bug with multiple contentEndedListeners being registered ([2208d86](https://github.com/googleads/videojs-ima/commit/2208d86))
<a name="1.6.3"></a>
## [1.6.3](https://github.com/googleads/videojs-ima/compare/v1.6.2...v1.6.3) (2019-09-30)
### Features
* adds a request mode for ad requests ([278556b](https://github.com/googleads/videojs-ima/commit/278556b))
<a name="1.6.2"></a>
## [1.6.2](https://github.com/googleads/videojs-ima/compare/v1.6.1...v1.6.2) (2019-09-11)
### Bug Fixes
* fixed error in videojs.ima.min.js ([3d4e995](https://github.com/googleads/videojs-ima/commit/3d4e995))
<a name="1.6.1"></a>
## [1.6.1](https://github.com/googleads/videojs-ima/compare/v1.6.0...v1.6.1) (2019-09-10)
### Bug Fixes
* changed to parseFloat ([2b854a4](https://github.com/googleads/videojs-ima/commit/2b854a4))
* fixed small errors in Readme update ([18186f9](https://github.com/googleads/videojs-ima/commit/18186f9))
* removed second param from parseFloat ([4b5eef9](https://github.com/googleads/videojs-ima/commit/4b5eef9))
<a name="1.6.0"></a>
# [1.6.0](https://github.com/googleads/videojs-ima/compare/v1.5.2...v1.6.0) (2019-06-26)
### Features
* Allow for an adsRequest object to be passed to the plugin. This allows us to support additional adRequest properties. Fixes [#653](https://github.com/googleads/videojs-ima/issues/653). ([9e0463a](https://github.com/googleads/videojs-ima/commit/9e0463a))
### Bug Fixes
* fix via npm audit, take two ([#771](https://github.com/googleads/videojs-ima/issues/771)) ([e0d59f5](https://github.com/googleads/videojs-ima/commit/e0d59f5))
* fixes security issue with packages as per npm audit fix ([6daa9d5](https://github.com/googleads/videojs-ima/commit/6daa9d5))
* issue with initialization of adDisplayContainer ([d711072](https://github.com/googleads/videojs-ima/commit/d711072))
* update package.json for supporting video.js 7.x ([dbc87e6](https://github.com/googleads/videojs-ima/commit/dbc87e6))
* update packages to latest versions ([#749](https://github.com/googleads/videojs-ima/issues/749)) ([6f94112](https://github.com/googleads/videojs-ima/commit/6f94112))
### Code Refactoring
* Remove playOnLoad from setContentWith(AdTag|AdsResponse|adsRequest). This stopped working with the refactor, and due to how the player and contrib-ads handle autoplay, is no longer supported. Fixes [#524](https://github.com/googleads/videojs-ima/issues/524). ([c36dedf](https://github.com/googleads/videojs-ima/commit/c36dedf))
* Remove playOnLoad from setContentWith(AdTag|AdsResponse|adsRequest). This stopped working with the refactor, and due to how the player and contrib-ads handle autoplay, is no longer supported. Fixes [#524](https://github.com/googleads/videojs-ima/issues/524)." ([722930a](https://github.com/googleads/videojs-ima/commit/722930a))
### Tests
* change test content video URL ([#766](https://github.com/googleads/videojs-ima/issues/766)) ([e64564b](https://github.com/googleads/videojs-ima/commit/e64564b))
<a name="1.5.2"></a>
## [1.5.2](https://github.com/googleads/videojs-ima/compare/v1.5.1...v1.5.2) (2018-07-25)
### Features
* adds ad log, fixes [#698](https://github.com/googleads/videojs-ima/issues/698) ([#704](https://github.com/googleads/videojs-ima/issues/704)) ([3b16758](https://github.com/googleads/videojs-ima/commit/3b16758))
* Allow for an adsRequest object to be passed to the plugin. This… ([#656](https://github.com/googleads/videojs-ima/issues/656)) ([80aba35](https://github.com/googleads/videojs-ima/commit/80aba35)), closes [#653](https://github.com/googleads/videojs-ima/issues/653)
### Bug Fixes
* Added type to content source ([#680](https://github.com/googleads/videojs-ima/issues/680)) ([d8cb13d](https://github.com/googleads/videojs-ima/commit/d8cb13d))
### Tests
* Re-disable flaky browserstack tests. ([#669](https://github.com/googleads/videojs-ima/issues/669)) ([69659b8](https://github.com/googleads/videojs-ima/commit/69659b8))
* Re-enable browserstack tests, 2nd attempt. ([#657](https://github.com/googleads/videojs-ima/issues/657)) ([02b9852](https://github.com/googleads/videojs-ima/commit/02b9852))
* timeouts are now 60000 ms ([#672](https://github.com/googleads/videojs-ima/issues/672)). Re-enable bs tests. ([fc81aae](https://github.com/googleads/videojs-ima/commit/fc81aae))
<a name="1.5.1"></a>
## [1.5.1](https://github.com/googleads/videojs-ima/compare/v1.5.0...v1.5.1) (2018-06-11)
### Bug Fixes
* Quick fix issues in 1.5.0. Re-adds missing css file and adds a null check around adDisplayContainer.initialize(). ([#648](https://github.com/googleads/videojs-ima/issues/648)) ([0c763c3](https://github.com/googleads/videojs-ima/commit/0c763c3))
<a name="1.5.0"></a>
# [1.5.0](https://github.com/googleads/videojs-ima/compare/v1.4.0...v1.5.0) (2018-06-11)
### Features
* Added scss file. Fixes [#636](https://github.com/googleads/videojs-ima/issues/636). ([#637](https://github.com/googleads/videojs-ima/issues/637)) ([5e622a7](https://github.com/googleads/videojs-ima/commit/5e622a7))
* expose vastLoadTimeout ([#644](https://github.com/googleads/videojs-ima/issues/644)) ([8222570](https://github.com/googleads/videojs-ima/commit/8222570))
### Bug Fixes
* Call startLinearAdMode on post-rolls. Fixes an issue where contrib-ads thought we were timing out on all post-rolls.\Fixes [#620](https://github.com/googleads/videojs-ima/issues/620). ([#631](https://github.com/googleads/videojs-ima/issues/631)) ([6088f86](https://github.com/googleads/videojs-ima/commit/6088f86))
* removed incorrect comment ([#624](https://github.com/googleads/videojs-ima/issues/624)) ([30734c6](https://github.com/googleads/videojs-ima/commit/30734c6))
* Use getComputedStyle but fall back to boundingClientRect ([#623](https://github.com/googleads/videojs-ima/issues/623)) ([a017044](https://github.com/googleads/videojs-ima/commit/a017044))
* Wait until PlayerWrapper ready before invoking SdkImpl.initAdObjects ([#638](https://github.com/googleads/videojs-ima/issues/638)) ([fd409d6](https://github.com/googleads/videojs-ima/commit/fd409d6))
* **wrapper:** Resets contentComplete correctly ([#641](https://github.com/googleads/videojs-ima/issues/641)) ([2255a11](https://github.com/googleads/videojs-ima/commit/2255a11)), closes [#639](https://github.com/googleads/videojs-ima/issues/639)
### Code Refactoring
* Deprecated id setting, instead get the id from Vjs player. ([#625](https://github.com/googleads/videojs-ima/issues/625)) ([f08408a](https://github.com/googleads/videojs-ima/commit/f08408a))
* Remove unused CSS classes and IDs in the example stylesheet. Fixes [#565](https://github.com/googleads/videojs-ima/issues/565). ([#632](https://github.com/googleads/videojs-ima/issues/632)) ([b6dbc62](https://github.com/googleads/videojs-ima/commit/b6dbc62))
<a name="1.4.0"></a>
# [1.4.0](https://github.com/googleads/videojs-ima/compare/v1.3.0...v1.4.0) (2018-05-16)
### Features
* Multilingual UI support for the adLabel "N of N" string ([#592](https://github.com/googleads/videojs-ima/issues/592)) ([4cba6d4](https://github.com/googleads/videojs-ima/commit/4cba6d4))
### Bug Fixes
* Updated samples to work on iOS. ([#613](https://github.com/googleads/videojs-ima/issues/613)) ([a21b544](https://github.com/googleads/videojs-ima/commit/a21b544))
### Tests
* Disable browserstack tests. To be re-enabled once we fix their flakiness. ([#615](https://github.com/googleads/videojs-ima/issues/615)) ([7d4b5a6](https://github.com/googleads/videojs-ima/commit/7d4b5a6))
* Enable browserstack network logs. ([#597](https://github.com/googleads/videojs-ima/issues/597)) ([9cfbd08](https://github.com/googleads/videojs-ima/commit/9cfbd08))
* Enable verbose browserstack logs. ([#614](https://github.com/googleads/videojs-ima/issues/614)) ([b87735f](https://github.com/googleads/videojs-ima/commit/b87735f))
<a name="1.3.0"></a>
# [1.3.0](https://github.com/googleads/videojs-ima/compare/v1.2.1...v1.3.0) (2018-03-29)
### Bug Fixes
* Add nopostroll trigger. ([#585](https://github.com/googleads/videojs-ima/issues/585)) ([e790e6d](https://github.com/googleads/videojs-ima/commit/e790e6d))
* Change source for examples to something that supports https. ([#566](https://github.com/googleads/videojs-ima/issues/566)) ([6810fb3](https://github.com/googleads/videojs-ima/commit/6810fb3))
* Fix locale and numRedirects settings ([#584](https://github.com/googleads/videojs-ima/issues/584)) ([e4de93d](https://github.com/googleads/videojs-ima/commit/e4de93d))
* Fix typo'd boundOnMouseMove property. ([#569](https://github.com/googleads/videojs-ima/issues/569)) ([4cc710b](https://github.com/googleads/videojs-ima/commit/4cc710b))
* Resize handler now resizes ([#555](https://github.com/googleads/videojs-ima/issues/555)) ([a10e82f](https://github.com/googleads/videojs-ima/commit/a10e82f)), closes [#554](https://github.com/googleads/videojs-ima/issues/554)
* Resolve dangling endLinearAdMode call in onAdBreakEnd. ([#574](https://github.com/googleads/videojs-ima/issues/574)) ([2158ba0](https://github.com/googleads/videojs-ima/commit/2158ba0))
* Use contentended instead of ended as trigger for post-rolls. ([#559](https://github.com/googleads/videojs-ima/issues/559)) ([5046440](https://github.com/googleads/videojs-ima/commit/5046440)), closes [#539](https://github.com/googleads/videojs-ima/issues/539)
### Code Refactoring
* Update autoplay sample and how we report adsWillAutoplay an… ([#562](https://github.com/googleads/videojs-ima/issues/562)) ([b580e21](https://github.com/googleads/videojs-ima/commit/b580e21)), closes [#341](https://github.com/googleads/videojs-ima/issues/341)
### Tests
* Remove unnecessary sleep in test. ([#580](https://github.com/googleads/videojs-ima/issues/580)) ([a82c421](https://github.com/googleads/videojs-ima/commit/a82c421))
<a name="1.2.1"></a>
## [1.2.1](https://github.com/googleads/videojs-ima/compare/v1.2.0...v1.2.1) (2018-03-06)
### Bug Fixes
* Fix setAdBreakReadyListener. ([#551](https://github.com/googleads/videojs-ima/issues/551)) ([a835fd8](https://github.com/googleads/videojs-ima/commit/a835fd8)), closes [#550](https://github.com/googleads/videojs-ima/issues/550)
### Tests
* Test against both video.js 5 and 6. ([#548](https://github.com/googleads/videojs-ima/issues/548)) ([60dabe5](https://github.com/googleads/videojs-ima/commit/60dabe5))
<a name="1.2.0"></a>
# [1.2.0](https://github.com/googleads/videojs-ima/compare/v1.1.1...v1.2.0) (2018-03-01)
### Features
* Add support for contrib-ads 6 and by extension VJS 6. ([#538](https://github.com/googleads/videojs-ima/issues/538)) ([d8edd05](https://github.com/googleads/videojs-ima/commit/d8edd05))
### Bug Fixes
* Fix undefined isMobile in sdk-impl. Fixes [#541](https://github.com/googleads/videojs-ima/issues/541) ([#542](https://github.com/googleads/videojs-ima/issues/542)) ([e7dd9c8](https://github.com/googleads/videojs-ima/commit/e7dd9c8))
### Documentation
* Move README badges to the top. It's what everyone else does. ([#540](https://github.com/googleads/videojs-ima/issues/540)) ([23d01fb](https://github.com/googleads/videojs-ima/commit/23d01fb))
<a name="1.1.1"></a>
## [1.1.1](https://github.com/googleads/videojs-ima/compare/v1.1.0...v1.1.1) (2018-02-27)
### Bug Fixes
* Fix redundant calculation of remainingTime for ad UI. ([#527](https://github.com/googleads/videojs-ima/issues/527)) ([d8d70a4](https://github.com/googleads/videojs-ima/commit/d8d70a4)), closes [#526](https://github.com/googleads/videojs-ima/issues/526)
### Tests
* removed pull request check ([#522](https://github.com/googleads/videojs-ima/issues/522)) ([e9b5490](https://github.com/googleads/videojs-ima/commit/e9b5490))
<a name="1.1.0"></a>
# [1.1.0](https://github.com/googleads/videojs-ima/compare/v1.0.4...v1.1.0) (2018-02-14)
### Features
* Add support for full slot ads by changing the default non-linear ad slot height from 1/3 player height to 100% player height. ([#501](https://github.com/googleads/videojs-ima/issues/501)) ([9532a7f](https://github.com/googleads/videojs-ima/commit/9532a7f))
* Auto-populate setAdWillPlayMuted if not provided in settings. ([b313873](https://github.com/googleads/videojs-ima/commit/b313873))
* Use font relative units in CSS instead of pixels. ([#503](https://github.com/googleads/videojs-ima/issues/503)) ([aff9e5e](https://github.com/googleads/videojs-ima/commit/aff9e5e)), closes [#492](https://github.com/googleads/videojs-ima/issues/492)
### Bug Fixes
* Actually use adWillPlayMuted variable I created. ([#520](https://github.com/googleads/videojs-ima/issues/520)) ([f2837c4](https://github.com/googleads/videojs-ima/commit/f2837c4))
* Fix preversion script. ([#516](https://github.com/googleads/videojs-ima/issues/516)) ([c370e72](https://github.com/googleads/videojs-ima/commit/c370e72))
### Tests
* **webdriver:** Adds browserstack config (local only). ([#510](https://github.com/googleads/videojs-ima/issues/510)) ([d7d7939](https://github.com/googleads/videojs-ima/commit/d7d7939))
* Added Travis CI credentials for browserstack. ([#511](https://github.com/googleads/videojs-ima/issues/511)) ([6b6f124](https://github.com/googleads/videojs-ima/commit/6b6f124))
* Fix error with BrowserStack tests. ([#519](https://github.com/googleads/videojs-ima/issues/519)) ([e4722d0](https://github.com/googleads/videojs-ima/commit/e4722d0))
<a name="1.0.4"></a>
## [1.0.4](https://github.com/googleads/videojs-ima/compare/v1.0.3...v1.0.4) (2018-01-17)
### Documentation
* Add keywords to package.json. This should list us on the videoj… ([#486](https://github.com/googleads/videojs-ima/issues/486)) ([7af46cf](https://github.com/googleads/videojs-ima/commit/7af46cf))
* Update README with new snippet and codepen link. ([#483](https://github.com/googleads/videojs-ima/issues/483)) ([2d40f74](https://github.com/googleads/videojs-ima/commit/2d40f74))
<a name="1.0.3"></a>
## [1.0.3](https://github.com/googleads/videojs-ima/compare/v1.0.2...v1.0.3) (2018-01-03)
<a name="1.0.2"></a>
## [1.0.2](https://github.com/googleads/videojs-ima/compare/v1.0.1...v1.0.2) (2018-01-03)
### Bug Fixes
* Added babel to build for ES2015, so older browsers are supported ([#478](https://github.com/googleads/videojs-ima/issues/478)) ([9b25179](https://github.com/googleads/videojs-ima/commit/9b25179))
* Fix advanced sample for mobile. ([#469](https://github.com/googleads/videojs-ima/issues/469)) ([c0c4bee](https://github.com/googleads/videojs-ima/commit/c0c4bee))
### Documentation
* Add commit message guidelines to CONTRIBUTING.md. ([#480](https://github.com/googleads/videojs-ima/issues/480)) ([f6a982a](https://github.com/googleads/videojs-ima/commit/f6a982a))
### Tests
* Added basic webdriver tests ([#464](https://github.com/googleads/videojs-ima/issues/464)) ([8786de9](https://github.com/googleads/videojs-ima/commit/8786de9)), closes [#445](https://github.com/googleads/videojs-ima/issues/445)
<a name="1.0.1"></a>
## [1.0.1](https://github.com/googleads/videojs-ima/compare/v1.0.0...v1.0.1) (2017-12-13)
### Bug Fixes
* Add src to package.json ([#461](https://github.com/googleads/videojs-ima/issues/461)) ([8a94908](https://github.com/googleads/videojs-ima/commit/8a94908))
* Fixed player version reporting. ([#459](https://github.com/googleads/videojs-ima/issues/459)) ([c176781](https://github.com/googleads/videojs-ima/commit/c176781))
<a name="1.0.0"></a>
# [1.0.0](https://github.com/googleads/videojs-ima/compare/0.8.0...v1.0.0) (2017-12-12)
### Code Refactoring
* Massive refactor of the plugin. ([a5cd819](https://github.com/googleads/videojs-ima/commit/a5cd819))
<a name="0.8.0"></a>
# [0.8.0](https://github.com/googleads/videojs-ima/compare/0.6.0...0.8.0) (2017-11-16)
<a name="0.5.0"></a>
# [0.5.0](https://github.com/googleads/videojs-ima/compare/0.4.0...0.5.0) (2016-09-20)

202
node_modules/videojs-ima/LICENSE generated vendored Normal file
View file

@ -0,0 +1,202 @@
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

226
node_modules/videojs-ima/README.md generated vendored Normal file
View file

@ -0,0 +1,226 @@
# IMA SDK Plugin for Video.js
[![Build Status](https://travis-ci.org/googleads/videojs-ima.svg?branch=master)](https://travis-ci.org/googleads/videojs-ima)
## Introduction
The IMA SDK Plugin for Video.js provides a quick and easy IMA SDK integration
for the Video.js player.
To see the plugin in action, check out our
[samples](//googleads.github.io/videojs-ima/).
## Features
- Easily integrate the Google IMA SDK into Video.js to enable advertising on
your video content.
## Requirements
- Your favorite text editor
- A JavaScript enabled browser
## Getting started
### ES6 Imports
The easiest way to get started is by using [npm](//www.npmjs.org/).
```
npm install videojs-ima
```
Your index.html should contain the video.js stylesheet (not included in the npm module),
a video player to be used for playback, and script tags for the IMA SDK and your own
javascript file.
```html
<html>
<head>
<!-- Load dependent stylesheets. -->
<link href="path/to/video-js.css" rel="stylesheet">
<link href="path/to/videojs.ima.css" rel="stylesheet"/>
</head>
<body>
<video id='content_video' class="video-js">
<p class='vjs-no-js'>
To view this video, please enable JavaScript and consider upgrading to a web browser that
<a href='https://videojs.com/html5-video-support/' target='_blank'>supports HTML5 video</a>
</p>
</video>
<!-- Load dependent scripts -->
<script src="//imasdk.googleapis.com/js/sdkloader/ima3.js"></script>
<script src="player.js"></script>
</body>
</html>
```
Three imports are required to use the videojs-ima module, as seen in the player.js example below.
```javascript
import videojs from 'video.js';
import 'videojs-contrib-ads';
import 'videojs-ima';
var videoOptions = {
controls: true,
sources: [{
src: 'PATH_TO_YOUR_CONTENT_VIDEO',
type: 'YOUR_CONTENT_VIDEO_TYPE',
}]
};
var player = videojs('content_video', videoOptions);
var imaOptions = {
adTagUrl: 'YOUR_AD_TAG'
};
player.ima(imaOptions);
// On mobile devices, you must call initializeAdDisplayContainer as the result
// of a user action (e.g. button click). If you do not make this call, the SDK
// will make it for you, but not as the result of a user action. For more info
// see our examples, all of which are set up to work on mobile devices.
// player.ima.initializeAdDisplayContainer();
```
### Alternative Setup
If you don't use npm, you can download the source from the dist/ folder and
include it directly in your project. You'll also need to download the source for
the [videojs-contrib-ads plugin](//github.com/videojs/videojs-contrib-ads).
In your index.html file, create a new video.js player and load a (currently
empty) javascript file:
```html
<html>
<head>
<!-- Load dependent stylesheets. -->
<link href="path/to/video-js.css" rel="stylesheet">
<link rel="stylesheet" href="path/to/videojs-contrib-ads.css" />
<link rel="stylesheet" href="path/to/videojs.ima.css" />
</head>
<body>
<video id="content_video" class="video-js vjs-default-skin"
controls preload="auto" width="YOUR_VIDEO_WIDTH" height="YOUR_VIDEO_HEIGHT">
<source src="PATH_TO_YOUR_CONTENT_VIDEO" type="YOUR_CONTENT_VIDEO_TYPE" />
</video>
<!-- Load dependent scripts -->
<script src="/path/to/video.js"></script>
<script src="//imasdk.googleapis.com/js/sdkloader/ima3.js"></script>
<script src="/path/to/videojs-contrib-ads.js"></script>
<script src="/path/to/videojs.ima.js"></script>
<script src="player.js"></script>
</body>
</html>
```
In player.js, load the ads library and set up the IMA plugin:
```javascript
var player = videojs('content_video');
var options = {
adTagUrl: 'YOUR_AD_TAG'
};
player.ima(options);
// On mobile devices, you must call initializeAdDisplayContainer as the result
// of a user action (e.g. button click). If you do not make this call, the SDK
// will make it for you, but not as the result of a user action. For more info
// see our examples, all of which are set up to work on mobile devices.
// player.ima.initializeAdDisplayContainer();
```
That's all there is to it!
## Playground
Check out the snippet above in-action [on CodePen](https://codepen.io/imasdk/pen/wpyQXP).
## Additional settings
The plugin accepts additional settings beyond the two required settings shown in
the previous snippet. A summary of all settings follows:
| Settings | Type | Description |
|----------|------|-------------|
| adLabel | string | Replaces the "Advertisement" text in the ad label. Added for multilingual UI support. |
| adLabelNofN | string | Replaces the "of" text in the ad label (e.g. ... (1 of 2) ...). Added for multilingual UI support. |
| adTagUrl | string | A URL which returns a VAST, VMAP or ad rules response. This will override adsResponse. |
| adsRenderingSettings | object | JSON object with ads rendering settings as defined in the IMA SDK Docs(1). |
| adsResponse | string | The VAST, VMAP, or ad rules response to use in lieu of fetching one an ad tag. This is overridden if adTagUrl is set. |
| adsRequest | object | JSON object with ads request properties defined in the IMA SDK Docs(2). Properties set here that can also be provided elsewhere (e.g. adTagUrl) will override those other settings. |
| autoPlayAdBreaks | boolean | Whether or not to automatically play VMAP or ad rules ad breaks. Defaults to true. |
| **deprecated** adWillPlayMuted | boolean | Notifies the SDK whether the player intends to start ad while muted. Changing this setting will have no impact on ad playback. Defaults to false. |
| contribAdsSettings | object | Additional settings to be passed to the contrib-ads plugin(3) used by this IMA plugin. |
| debug | boolean | True to load the debug version of the plugin, false to load the non-debug version. Defaults to false. |
| disableAdControls | boolean | True to hide the ad controls(play/pause, volume, and fullscreen buttons) during ad playback. Defaults to false. |
| disableCustomPlaybackForIOS10Plus | boolean | Sets whether to disable custom playback on iOS 10+ browsers. If true, ads will play inline if the content video is inline. Defaults to false. |
| disableFlashAds | boolean | True to disable Flash ads - Flash ads will be considered an unsupported ad type. Defaults to false. |
| featureFlags | object | Sets IMA SDK feature flags. |
| forceNonLinearFullSlot | boolean | True to force non-linear AdSense ads to render as linear fullslot. If set, the content video will be paused and the non-linear text or image ad will be rendered as fullslot. The content video will resume once the ad has been skipped or closed. |
| id | string | **DEPRECATED** as of v.1.5.0, no longer used or required. |
| locale | string | Locale for ad localization. The supported locale codes can be found in [Localizing for Language and Locale](//developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/localization)|
| nonLinearHeight | number | Desired height for non-linear ads. Defaults to 1/3 player height. |
| nonLinearWidth | number | Desired width of non-linear ads. Defaults to player width. |
| numRedirects | number | Maximum number of VAST redirects before the subsequent redirects will be denied and the ad load aborted. The number of redirects directly affects latency and thus user experience. This applies to all VAST wrapper ads. |
| omidMode | object | Sets and enables the Open Measurement SDK(4). Accepts an object with keys 'LIMITED', 'DOMAIN', and 'FULL'. The value pair for each key should be a dictionary that maps each access mode to a regular expression that matches the URLs to include. This API is currently in open beta and requires the following feature flag to be set: `{'enableOmidBeta': true}` |
| ppid | string | Sets the publisher provided ID |
| preventLateAdStart | boolean | Prevent ads from starting after the content has started if an adtimeout occurred (preroll, midroll, postroll). The default value is false
| sessionId | string | Sets the [session ID](//developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/reference/js/google.ima.ImaSdkSettings#setSessionId) |
| showControlsForJSAds | boolean | Whether or not to show the control bar for VPAID JavaScript ads. Defaults to true. |
| showCountdown | boolean | Whether or not to show the ad countdown timer. Defaults to true. |
| vastLoadTimeout | number | Override for default VAST load timeout in milliseconds for a single wrapper. The default timeout is 5000ms. |
| vpaidAllowed | boolean | **DEPRECATED**, please use vpaidMode. |
| vpaidMode | VpaidMode(5) | VPAID Mode. Defaults to ENABLED. This setting,overrides vpaidAllowed. |
(1) [AdsRenderingSettings](//developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/reference/js/google.ima.AdsRenderingSettings)
<br />
(2) [AdsRequest](//developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/reference/js/google.ima.AdsRequest)
<br />
(3) [contrib-ads plugin](//github.com/videojs/videojs-contrib-ads)
<br />
(4) [Open Measurement SDK guide](//developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/omsdk)
<br />
(5) [ImaSdkSettings.setVpaidMode](//developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/reference/js/google.ima.ImaSdkSettings#setVpaidMode)
## IMA Plugin Ad Events
The IMA Plugin will fire events that can be listened for. Ad lifecycle events can be listened for by following our [Advanced Example](https://github.com/googleads/videojs-ima/blob/master/examples/advanced/ads.js). Other events are emited from the videojs player. Please see the below example to set up listeners for these events.
```javascript
this.player = videojs('content_video');
this.player.on('ads-manager', function(response){
var adsManager = response.adsManager;
// Your code in response to the `ads-manager` event.
})
```
Below are the events added by the videojs-ima plugin to the videojs player.
| Event | Event String | Payload |
|-------|--------------|---------|
| Ad Started | 'ads-ad-started' | none |
| Ads Manager | 'ads-manager' | [google.ima.AdsManager](//developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/reference/js/google.ima.AdsManager) |
| Ads Loader | 'ads-loader' | [google.ima.AdsLoader](//developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/reference/js/google.ima.AdsLoader) |
| Ads Request | 'ads-request' | [google.ima.AdsRequest](//developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/reference/js/google.ima.AdsRequest) |
## Disable automatic ad break playback
In some circumstances you may want to prevent the SDK from playing ad breaks
until you're ready for them. In this scenario, you can disable automatic
playback of ad breaks in favor of letting the SDK know when you're ready for an
ad break to play. To do so:
1. Set ```autoPlayAdBreaks``` to false in the initial options.
2. Provide an ad break ready listener via ```setAdBreakReadyListener```.
3. Call ```player.ima.playAdBreak()``` in your ad break ready listener when
you're ready to play the ads.
## Where do I report issues?
Please report issues on the [issues page](../../issues).
## Terms of Service
The IMA SDK plugin for Video.js uses the IMA SDK, and as such is subject to the
[IMA SDK Terms of Service](//developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/terms).
## How do I contribute?
See [CONTRIBUTING.md](CONTRIBUTING.md) for details.

174
node_modules/videojs-ima/dist/videojs.ima.css generated vendored Normal file
View file

@ -0,0 +1,174 @@
/**
* Copyright 2014 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
.ima-ad-container {
top: 0em;
position: absolute;
display: none;
width: 100%;
height: 100%;
}
/* Move overlay if user fast-clicks play button. */
.video-js.vjs-playing .bumpable-ima-ad-container {
margin-top: -4em;
}
/* Move overlay when controls are active. */
.video-js.vjs-user-inactive.vjs-playing .bumpable-ima-ad-container {
margin-top: 0em;
}
.video-js.vjs-paused .bumpable-ima-ad-container,
.video-js.vjs-playing:hover .bumpable-ima-ad-container,
.video-js.vjs-user-active.vjs-playing .bumpable-ima-ad-container {
margin-top: -4em;
}
.ima-controls-div {
bottom: 0em;
height: 1.4em;
position: absolute;
overflow: hidden;
display: none;
opacity: 1;
background-color: rgba(7, 20, 30, .7);
background: -moz-linear-gradient(
bottom,
rgba(7, 20, 30, .7) 0%,
rgba(7, 20, 30, 0) 100%); /* FF3.6+ */
background: -webkit-gradient(
linear,
left bottom,
left top,
color-stop(0%,rgba(7, 20, 30, .7)),
color-stop(100%,rgba(7, 20, 30, 0))); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(
bottom,
rgba(7, 20, 30, .7) 0%,
rgba(7, 20, 30, 0) 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(bottom,
rgba(7, 20, 30, .7) 0%,
rgba(7, 20, 30, 0) 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(bottom,
rgba(7, 20, 30, .7) 0%,
rgba(7, 20, 30, 0) 100%); /* IE10+ */
background: linear-gradient(to top,
rgba(7, 20, 30, .7) 0%,
rgba(7, 20, 30, 0) 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient(
startColorstr='#0007141E',
endColorstr='#07141E',GradientType=0 ); /* IE6-9 */
}
.ima-controls-div.ima-controls-div-showing {
height: 3.7em;
}
.ima-countdown-div {
height: 1em;
color: #FFFFFF;
text-shadow: 0 0 0.2em #000;
cursor: default;
}
.ima-seek-bar-div {
top: 1.2em;
height: 0.3em;
position: absolute;
background: rgba(255, 255, 255, .4);
}
.ima-progress-div {
width: 0em;
height: 0.3em;
background-color: #ECC546;
}
.ima-play-pause-div, .ima-mute-div, .ima-slider-div, .ima-fullscreen-div {
width: 2.33em;
height: 1.33em;
top: 0.733em;
left: 0em;
position: absolute;
color: #CCCCCC;
font-size: 1.5em;
line-height: 2;
text-align: center;
font-family: VideoJS;
cursor: pointer;
}
.ima-mute-div {
left: auto;
right: 5.667em;
}
.ima-slider-div {
left: auto;
right: 2.33em;
width: 3.33em;
height: 0.667em;
top: 1.33em;
background-color: #555555;
}
.ima-slider-level-div {
width: 100%;
height: 0.667em;
background-color: #ECC546;
}
.ima-fullscreen-div {
left: auto;
right: 0em;
}
.ima-playing:before {
content: "\00f103";
}
.ima-paused:before {
content: "\00f101";
}
.ima-playing:hover:before, .ima-paused:hover:before {
text-shadow: 0 0 1em #fff;
}
.ima-non-muted:before {
content: "\00f107";
}
.ima-muted:before {
content: "\00f104";
}
.ima-non-muted:hover:before, .ima-muted:hover:before {
text-shadow: 0 0 1em #fff;
}
.ima-non-fullscreen:before {
content: "\00f108";
}
.ima-fullscreen:before {
content: "\00f109";
}
.ima-non-fullscreen:hover:before, .ima-fullscreen:hover:before {
text-shadow: 0 0 1em #fff;
}

2856
node_modules/videojs-ima/dist/videojs.ima.es.js generated vendored Normal file

File diff suppressed because it is too large Load diff

2864
node_modules/videojs-ima/dist/videojs.ima.js generated vendored Normal file

File diff suppressed because it is too large Load diff

1
node_modules/videojs-ima/dist/videojs.ima.min.js generated vendored Normal file

File diff suppressed because one or more lines are too long

174
node_modules/videojs-ima/dist/videojs.ima.scss generated vendored Normal file
View file

@ -0,0 +1,174 @@
/**
* Copyright 2014 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
.ima-ad-container {
top: 0em;
position: absolute;
display: none;
width: 100%;
height: 100%;
}
/* Move overlay if user fast-clicks play button. */
.video-js.vjs-playing .bumpable-ima-ad-container {
margin-top: -4em;
}
/* Move overlay when controls are active. */
.video-js.vjs-user-inactive.vjs-playing .bumpable-ima-ad-container {
margin-top: 0em;
}
.video-js.vjs-paused .bumpable-ima-ad-container,
.video-js.vjs-playing:hover .bumpable-ima-ad-container,
.video-js.vjs-user-active.vjs-playing .bumpable-ima-ad-container {
margin-top: -4em;
}
.ima-controls-div {
bottom: 0em;
height: 1.4em;
position: absolute;
overflow: hidden;
display: none;
opacity: 1;
background-color: rgba(7, 20, 30, .7);
background: -moz-linear-gradient(
bottom,
rgba(7, 20, 30, .7) 0%,
rgba(7, 20, 30, 0) 100%); /* FF3.6+ */
background: -webkit-gradient(
linear,
left bottom,
left top,
color-stop(0%,rgba(7, 20, 30, .7)),
color-stop(100%,rgba(7, 20, 30, 0))); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(
bottom,
rgba(7, 20, 30, .7) 0%,
rgba(7, 20, 30, 0) 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(bottom,
rgba(7, 20, 30, .7) 0%,
rgba(7, 20, 30, 0) 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(bottom,
rgba(7, 20, 30, .7) 0%,
rgba(7, 20, 30, 0) 100%); /* IE10+ */
background: linear-gradient(to top,
rgba(7, 20, 30, .7) 0%,
rgba(7, 20, 30, 0) 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient(
startColorstr='#0007141E',
endColorstr='#07141E',GradientType=0 ); /* IE6-9 */
}
.ima-controls-div.ima-controls-div-showing {
height: 3.7em;
}
.ima-countdown-div {
height: 1em;
color: #FFFFFF;
text-shadow: 0 0 0.2em #000;
cursor: default;
}
.ima-seek-bar-div {
top: 1.2em;
height: 0.3em;
position: absolute;
background: rgba(255, 255, 255, .4);
}
.ima-progress-div {
width: 0em;
height: 0.3em;
background-color: #ECC546;
}
.ima-play-pause-div, .ima-mute-div, .ima-slider-div, .ima-fullscreen-div {
width: 2.33em;
height: 1.33em;
top: 0.733em;
left: 0em;
position: absolute;
color: #CCCCCC;
font-size: 1.5em;
line-height: 2;
text-align: center;
font-family: VideoJS;
cursor: pointer;
}
.ima-mute-div {
left: auto;
right: 5.667em;
}
.ima-slider-div {
left: auto;
right: 2.33em;
width: 3.33em;
height: 0.667em;
top: 1.33em;
background-color: #555555;
}
.ima-slider-level-div {
width: 100%;
height: 0.667em;
background-color: #ECC546;
}
.ima-fullscreen-div {
left: auto;
right: 0em;
}
.ima-playing:before {
content: "\00f103";
}
.ima-paused:before {
content: "\00f101";
}
.ima-playing:hover:before, .ima-paused:hover:before {
text-shadow: 0 0 1em #fff;
}
.ima-non-muted:before {
content: "\00f107";
}
.ima-muted:before {
content: "\00f104";
}
.ima-non-muted:hover:before, .ima-muted:hover:before {
text-shadow: 0 0 1em #fff;
}
.ima-non-fullscreen:before {
content: "\00f108";
}
.ima-fullscreen:before {
content: "\00f109";
}
.ima-non-fullscreen:hover:before, .ima-fullscreen:hover:before {
text-shadow: 0 0 1em #fff;
}

123
node_modules/videojs-ima/package.json generated vendored Normal file
View file

@ -0,0 +1,123 @@
{
"_from": "videojs-ima",
"_id": "videojs-ima@1.11.0",
"_inBundle": false,
"_integrity": "sha512-ZRoWuGyJ75zamwZgpr0i/gZ6q7Evda/Q6R46gpW88WN7u0ORU7apw/lM1MSG4c3YDXW8LDENgzMAvMZUdifWhg==",
"_location": "/videojs-ima",
"_phantomChildren": {},
"_requested": {
"type": "tag",
"registry": true,
"raw": "videojs-ima",
"name": "videojs-ima",
"escapedName": "videojs-ima",
"rawSpec": "",
"saveSpec": null,
"fetchSpec": "latest"
},
"_requiredBy": [
"#USER",
"/"
],
"_resolved": "https://registry.npmjs.org/videojs-ima/-/videojs-ima-1.11.0.tgz",
"_shasum": "26ad385e388c3da72372298d7d755b001d05a91d",
"_spec": "videojs-ima",
"_where": "G:\\GDrive\\htdocs\\YouPHPTube",
"author": {
"name": "Google Inc."
},
"bugs": {
"url": "https://github.com/googleads/videojs-ima/issues"
},
"bundleDependencies": false,
"dependencies": {
"@hapi/cryptiles": "^5.1.0",
"can-autoplay": "^3.0.0",
"extend": ">=3.0.2",
"lodash": ">=4.17.19",
"lodash.template": ">=4.5.0",
"videojs-contrib-ads": "^6.6.5"
},
"deprecated": false,
"description": "[![Build Status](https://travis-ci.org/googleads/videojs-ima.svg?branch=master)](https://travis-ci.org/googleads/videojs-ima)",
"devDependencies": {
"axios": ">=0.21.1",
"babel-core": "^6.26.3",
"babel-preset-env": "^1.7.0",
"child_process": "^1.0.2",
"chromedriver": "^89.0.0",
"conventional-changelog-cli": "^2.0.31",
"conventional-changelog-videojs": "^3.0.1",
"ecstatic": ">=4.1.3",
"eslint": "^4.19.1",
"eslint-config-google": "^0.9.1",
"eslint-plugin-jsdoc": "^3.15.1",
"geckodriver": "^1.19.1",
"http-server": "^0.12.3",
"ini": ">=1.3.7",
"mocha": "^7.1.2",
"npm-run-all": "^4.1.5",
"path": "^0.12.7",
"protractor": "^7.0.0",
"rimraf": "^2.7.1",
"rollup": "^0.51.8",
"rollup-plugin-babel": "^3.0.7",
"rollup-plugin-copy": "^0.2.3",
"rollup-plugin-json": "^2.3.1",
"rollup-plugin-uglify": "^2.0.1",
"selenium-webdriver": "^3.6.0",
"uglify-es": "^3.3.9",
"video.js": "^5.19.2 || ^6 || ^7",
"watch": "^1.0.2",
"webdriver-manager": "^12.1.7",
"xmldom": ">=0.5.0"
},
"engines": {
"node": ">=0.8.0"
},
"files": [
"CHANGELOG.md",
"LICENSE",
"README.md",
"dist/",
"src/"
],
"homepage": "https://github.com/googleads/videojs-ima#readme",
"keywords": [
"videojs",
"videojs-plugin"
],
"license": "Apache-2.0",
"main": "./dist/videojs.ima.js",
"module": "./dist/videojs.ima.es.js",
"name": "videojs-ima",
"peerDependencies": {
"video.js": "^5.19.2 || ^6 || ^7"
},
"repository": {
"type": "git",
"url": "git+https://github.com/googleads/videojs-ima.git"
},
"scripts": {
"contBuild": "watch 'npm run rollup:max' src",
"devServer": "npm-run-all -p testServer contBuild",
"lint": "eslint \"src/*.js\"",
"postversion": "node scripts/postversion.js",
"predevServer": "echo \"Starting up server on localhost:8000.\"",
"pretest": "npm run rollup",
"preversion": "node scripts/preversion.js && npm run lint && npm test",
"rollup": "npm-run-all rollup:*",
"rollup:es": "rollup -c configs/rollup.config.es.js",
"rollup:max": "rollup -c configs/rollup.config.js",
"rollup:min": "rollup -c configs/rollup.config.min.js",
"start": "npm run devServer",
"test": "npm-run-all test:*",
"test:vjs5": "npm install video.js@5.19.2 --no-save && npm-run-all -p -r testServer webdriver",
"test:vjs6": "npm install video.js@6 --no-save && npm-run-all -p -r testServer webdriver",
"test:vjs7": "npm install video.js@7 --no-save && npm-run-all -p -r testServer webdriver",
"testServer": "http-server --cors -p 8000 --silent",
"version": "node scripts/version.js",
"webdriver": "mocha test/webdriver/*.js --no-timeouts"
},
"version": "1.11.0"
}

611
node_modules/videojs-ima/src/ad-ui.js generated vendored Normal file
View file

@ -0,0 +1,611 @@
/**
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* IMA SDK integration plugin for Video.js. For more information see
* https://www.github.com/googleads/videojs-ima
*/
/**
* Ad UI implementation.
*
* @param {Controller} controller Plugin controller.
* @constructor
* @struct
* @final
*/
const AdUi = function(controller) {
/**
* Plugin controller.
*/
this.controller = controller;
/**
* Div used as an ad container.
*/
this.adContainerDiv = document.createElement('div');
/**
* Div used to display ad controls.
*/
this.controlsDiv = document.createElement('div');
/**
* Div used to display ad countdown timer.
*/
this.countdownDiv = document.createElement('div');
/**
* Div used to display add seek bar.
*/
this.seekBarDiv = document.createElement('div');
/**
* Div used to display ad progress (in seek bar).
*/
this.progressDiv = document.createElement('div');
/**
* Div used to display ad play/pause button.
*/
this.playPauseDiv = document.createElement('div');
/**
* Div used to display ad mute button.
*/
this.muteDiv = document.createElement('div');
/**
* Div used by the volume slider.
*/
this.sliderDiv = document.createElement('div');
/**
* Volume slider level visuals
*/
this.sliderLevelDiv = document.createElement('div');
/**
* Div used to display ad fullscreen button.
*/
this.fullscreenDiv = document.createElement('div');
/**
* Bound event handler for onMouseUp.
*/
this.boundOnMouseUp = this.onMouseUp.bind(this);
/**
* Bound event handler for onMouseMove.
*/
this.boundOnMouseMove = this.onMouseMove.bind(this);
/**
* Stores data for the ad playhead tracker.
*/
this.adPlayheadTracker = {
'currentTime': 0,
'duration': 0,
'isPod': false,
'adPosition': 0,
'totalAds': 0,
};
/**
* Used to prefix videojs ima controls.
*/
this.controlPrefix = this.controller.getPlayerId() + '_';
/**
* Boolean flag to show or hide the ad countdown timer.
*/
this.showCountdown = true;
if (this.controller.getSettings().showCountdown === false) {
this.showCountdown = false;
}
/**
* Boolean flag if the current ad is nonlinear.
*/
this.isAdNonlinear = false;
this.createAdContainer();
};
/**
* Creates the ad container.
*/
AdUi.prototype.createAdContainer = function() {
this.assignControlAttributes(
this.adContainerDiv, 'ima-ad-container');
this.adContainerDiv.style.position = 'absolute';
this.adContainerDiv.style.zIndex = 1111;
this.adContainerDiv.addEventListener(
'mouseenter',
this.showAdControls.bind(this),
false);
this.adContainerDiv.addEventListener(
'mouseleave',
this.hideAdControls.bind(this),
false);
this.adContainerDiv.addEventListener(
'click',
this.onAdContainerClick.bind(this),
false);
this.createControls();
this.controller.injectAdContainerDiv(this.adContainerDiv);
};
/**
* Create the controls.
*/
AdUi.prototype.createControls = function() {
this.assignControlAttributes(this.controlsDiv, 'ima-controls-div');
this.controlsDiv.style.width = '100%';
if (!this.controller.getIsMobile()) {
this.assignControlAttributes(this.countdownDiv, 'ima-countdown-div');
this.countdownDiv.innerHTML = this.controller.getSettings().adLabel;
this.countdownDiv.style.display = this.showCountdown ? 'block' : 'none';
} else {
this.countdownDiv.style.display = 'none';
}
this.assignControlAttributes(this.seekBarDiv, 'ima-seek-bar-div');
this.seekBarDiv.style.width = '100%';
this.assignControlAttributes(this.progressDiv, 'ima-progress-div');
this.assignControlAttributes(this.playPauseDiv, 'ima-play-pause-div');
this.addClass(this.playPauseDiv, 'ima-playing');
this.playPauseDiv.addEventListener(
'click',
this.onAdPlayPauseClick.bind(this),
false);
this.assignControlAttributes(this.muteDiv, 'ima-mute-div');
this.addClass(this.muteDiv, 'ima-non-muted');
this.muteDiv.addEventListener(
'click',
this.onAdMuteClick.bind(this),
false);
this.assignControlAttributes(this.sliderDiv, 'ima-slider-div');
this.sliderDiv.addEventListener(
'mousedown',
this.onAdVolumeSliderMouseDown.bind(this),
false);
// Hide volume slider controls on iOS as they aren't supported.
if (this.controller.getIsIos()) {
this.sliderDiv.style.display = 'none';
}
this.assignControlAttributes(this.sliderLevelDiv, 'ima-slider-level-div');
this.assignControlAttributes(this.fullscreenDiv, 'ima-fullscreen-div');
this.addClass(this.fullscreenDiv, 'ima-non-fullscreen');
this.fullscreenDiv.addEventListener(
'click',
this.onAdFullscreenClick.bind(this),
false);
this.adContainerDiv.appendChild(this.controlsDiv);
this.controlsDiv.appendChild(this.countdownDiv);
this.controlsDiv.appendChild(this.seekBarDiv);
this.controlsDiv.appendChild(this.playPauseDiv);
this.controlsDiv.appendChild(this.muteDiv);
this.controlsDiv.appendChild(this.sliderDiv);
this.controlsDiv.appendChild(this.fullscreenDiv);
this.seekBarDiv.appendChild(this.progressDiv);
this.sliderDiv.appendChild(this.sliderLevelDiv);
};
/**
* Listener for clicks on the play/pause button during ad playback.
*/
AdUi.prototype.onAdPlayPauseClick = function() {
this.controller.onAdPlayPauseClick();
};
/**
* Listener for clicks on the play/pause button during ad playback.
*/
AdUi.prototype.onAdMuteClick = function() {
this.controller.onAdMuteClick();
};
/**
* Listener for clicks on the fullscreen button during ad playback.
*/
AdUi.prototype.onAdFullscreenClick = function() {
this.controller.toggleFullscreen();
};
/**
* Show pause and hide play button
*/
AdUi.prototype.onAdsPaused = function() {
this.controller.sdkImpl.adPlaying = false;
this.addClass(this.playPauseDiv, 'ima-paused');
this.removeClass(this.playPauseDiv, 'ima-playing');
this.showAdControls();
};
/**
* Show pause and hide play button
*/
AdUi.prototype.onAdsResumed = function() {
this.onAdsPlaying();
this.showAdControls();
};
/**
* Show play and hide pause button
*/
AdUi.prototype.onAdsPlaying = function() {
this.controller.sdkImpl.adPlaying = true;
this.addClass(this.playPauseDiv, 'ima-playing');
this.removeClass(this.playPauseDiv, 'ima-paused');
};
/**
* Takes data from the controller to update the UI.
*
* @param {number} currentTime Current time of the ad.
* @param {number} remainingTime Remaining time of the ad.
* @param {number} duration Duration of the ad.
* @param {number} adPosition Index of the ad in the pod.
* @param {number} totalAds Total number of ads in the pod.
*/
AdUi.prototype.updateAdUi =
function(currentTime, remainingTime, duration, adPosition, totalAds) {
// Update countdown timer data
const remainingMinutes = Math.floor(remainingTime / 60);
let remainingSeconds = Math.floor(remainingTime % 60);
if (remainingSeconds.toString().length < 2) {
remainingSeconds = '0' + remainingSeconds;
}
let podCount = ': ';
if (totalAds > 1) {
podCount = ' (' + adPosition + ' ' +
this.controller.getSettings().adLabelNofN + ' ' + totalAds + '): ';
}
this.countdownDiv.innerHTML =
this.controller.getSettings().adLabel + podCount +
remainingMinutes + ':' + remainingSeconds;
// Update UI
const playProgressRatio = currentTime / duration;
const playProgressPercent = playProgressRatio * 100;
this.progressDiv.style.width = playProgressPercent + '%';
};
/**
* Handles UI changes when the ad is unmuted.
*/
AdUi.prototype.unmute = function() {
this.addClass(this.muteDiv, 'ima-non-muted');
this.removeClass(this.muteDiv, 'ima-muted');
this.sliderLevelDiv.style.width =
this.controller.getPlayerVolume() * 100 + '%';
};
/**
* Handles UI changes when the ad is muted.
*/
AdUi.prototype.mute = function() {
this.addClass(this.muteDiv, 'ima-muted');
this.removeClass(this.muteDiv, 'ima-non-muted');
this.sliderLevelDiv.style.width = '0%';
};
/*
* Listener for mouse down events during ad playback. Used for volume.
*/
AdUi.prototype.onAdVolumeSliderMouseDown = function() {
document.addEventListener('mouseup', this.boundOnMouseUp, false);
document.addEventListener('mousemove', this.boundOnMouseMove, false);
};
/*
* Mouse movement listener used for volume slider.
*/
AdUi.prototype.onMouseMove = function(event) {
this.changeVolume(event);
};
/*
* Mouse release listener used for volume slider.
*/
AdUi.prototype.onMouseUp = function(event) {
this.changeVolume(event);
document.removeEventListener('mouseup', this.boundOnMouseUp);
document.removeEventListener('mousemove', this.boundOnMouseMove);
};
/*
* Utility function to set volume and associated UI
*/
AdUi.prototype.changeVolume = function(event) {
let percent =
(event.clientX - this.sliderDiv.getBoundingClientRect().left) /
this.sliderDiv.offsetWidth;
percent *= 100;
// Bounds value 0-100 if mouse is outside slider region.
percent = Math.min(Math.max(percent, 0), 100);
this.sliderLevelDiv.style.width = percent + '%';
if (this.percent == 0) {
this.addClass(this.muteDiv, 'ima-muted');
this.removeClass(this.muteDiv, 'ima-non-muted');
} else {
this.addClass(this.muteDiv, 'ima-non-muted');
this.removeClass(this.muteDiv, 'ima-muted');
}
this.controller.setVolume(percent / 100); // 0-1
};
/**
* Show the ad container.
*/
AdUi.prototype.showAdContainer = function() {
this.adContainerDiv.style.display = 'block';
};
/**
* Hide the ad container
*/
AdUi.prototype.hideAdContainer = function() {
this.adContainerDiv.style.display = 'none';
};
/**
* Handles clicks on the ad container
*/
AdUi.prototype.onAdContainerClick = function() {
if (this.isAdNonlinear) {
this.controller.togglePlayback();
}
};
/**
* Resets the state of the ad ui.
*/
AdUi.prototype.reset = function() {
this.hideAdContainer();
};
/**
* Handles ad errors.
*/
AdUi.prototype.onAdError = function() {
this.hideAdContainer();
};
/**
* Handles ad break starting.
*
* @param {Object} adEvent The event fired by the IMA SDK.
*/
AdUi.prototype.onAdBreakStart = function(adEvent) {
this.showAdContainer();
const contentType = adEvent.getAd().getContentType();
if ((contentType === 'application/javascript') &&
!this.controller.getSettings().showControlsForJSAds) {
this.controlsDiv.style.display = 'none';
} else {
this.controlsDiv.style.display = 'block';
}
this.onAdsPlaying();
// Start with the ad controls minimized.
this.hideAdControls();
};
/**
* Handles ad break ending.
*/
AdUi.prototype.onAdBreakEnd = function() {
const currentAd = this.controller.getCurrentAd();
if (currentAd == null || // hide for post-roll only playlist
currentAd.isLinear()) { // don't hide for non-linear ads
this.hideAdContainer();
}
this.controlsDiv.style.display = 'none';
this.countdownDiv.innerHTML = '';
};
/**
* Handles when all ads have finished playing.
*/
AdUi.prototype.onAllAdsCompleted = function() {
this.hideAdContainer();
};
/**
* Handles when a linear ad starts.
*/
AdUi.prototype.onLinearAdStart = function() {
// Don't bump container when controls are shown
this.removeClass(this.adContainerDiv, 'bumpable-ima-ad-container');
this.isAdNonlinear = false;
};
/**
* Handles when a non-linear ad starts.
*/
AdUi.prototype.onNonLinearAdLoad = function() {
// For non-linear ads that show after a linear ad. For linear ads, we show the
// ad container in onAdBreakStart to prevent blinking in pods.
this.adContainerDiv.style.display = 'block';
// Bump container when controls are shown
this.addClass(this.adContainerDiv, 'bumpable-ima-ad-container');
this.isAdNonlinear = true;
};
AdUi.prototype.onPlayerEnterFullscreen = function() {
this.addClass(this.fullscreenDiv, 'ima-fullscreen');
this.removeClass(this.fullscreenDiv, 'ima-non-fullscreen');
};
AdUi.prototype.onPlayerExitFullscreen = function() {
this.addClass(this.fullscreenDiv, 'ima-non-fullscreen');
this.removeClass(this.fullscreenDiv, 'ima-fullscreen');
};
/**
* Called when the player volume changes.
*
* @param {number} volume The new player volume.
*/
AdUi.prototype.onPlayerVolumeChanged = function(volume) {
if (volume == 0) {
this.addClass(this.muteDiv, 'ima-muted');
this.removeClass(this.muteDiv, 'ima-non-muted');
this.sliderLevelDiv.style.width = '0%';
} else {
this.addClass(this.muteDiv, 'ima-non-muted');
this.removeClass(this.muteDiv, 'ima-muted');
this.sliderLevelDiv.style.width = volume * 100 + '%';
}
};
/**
* Shows ad controls on mouseover.
*/
AdUi.prototype.showAdControls = function() {
const {disableAdControls} = this.controller.getSettings();
if (!disableAdControls) {
this.addClass(this.controlsDiv, 'ima-controls-div-showing');
}
};
/**
* Hide the ad controls.
*/
AdUi.prototype.hideAdControls = function() {
this.removeClass(this.controlsDiv, 'ima-controls-div-showing');
};
/**
* Assigns the unique id and class names to the given element as well as the
* style class.
* @param {HTMLElement} element Element that needs the controlName assigned.
* @param {string} controlName Control name to assign.
*/
AdUi.prototype.assignControlAttributes = function(element, controlName) {
element.id = this.controlPrefix + controlName;
element.className = this.controlPrefix + controlName + ' ' + controlName;
};
/**
* Returns a regular expression to test a string for the given className.
*
* @param {string} className The name of the class.
* @return {RegExp} The regular expression used to test for that class.
*/
AdUi.prototype.getClassRegexp = function(className) {
// Matches on
// (beginning of string OR NOT word char)
// classname
// (negative lookahead word char OR end of string)
return new RegExp('(^|[^A-Za-z-])' + className +
'((?![A-Za-z-])|$)', 'gi');
};
/**
* Returns whether or not the provided element has the provied class in its
* className.
* @param {HTMLElement} element Element to tes.t
* @param {string} className Class to look for.
* @return {boolean} True if element has className in class list. False
* otherwise.
*/
AdUi.prototype.elementHasClass = function(element, className) {
const classRegexp = this.getClassRegexp(className);
return classRegexp.test(element.className);
};
/**
* Adds a class to the given element if it doesn't already have the class
* @param {HTMLElement} element Element to which the class will be added.
* @param {string} classToAdd Class to add.
*/
AdUi.prototype.addClass = function(element, classToAdd) {
element.className = element.className.trim() + ' ' + classToAdd;
};
/**
* Removes a class from the given element if it has the given class
*
* @param {HTMLElement} element Element from which the class will be removed.
* @param {string} classToRemove Class to remove.
*/
AdUi.prototype.removeClass = function(element, classToRemove) {
const classRegexp = this.getClassRegexp(classToRemove);
element.className =
element.className.trim().replace(classRegexp, '');
};
/**
* @return {HTMLElement} The div for the ad container.
*/
AdUi.prototype.getAdContainerDiv = function() {
return this.adContainerDiv;
};
/**
* Changes the flag to show or hide the ad countdown timer.
*
* @param {boolean} showCountdownIn Show or hide the countdown timer.
*/
AdUi.prototype.setShowCountdown = function(showCountdownIn) {
this.showCountdown = showCountdownIn;
this.countdownDiv.style.display = this.showCountdown ? 'block' : 'none';
};
export default AdUi;

807
node_modules/videojs-ima/src/controller.js generated vendored Normal file
View file

@ -0,0 +1,807 @@
/**
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* IMA SDK integration plugin for Video.js. For more information see
* https://www.github.com/googleads/videojs-ima
*/
import PlayerWrapper from './player-wrapper.js';
import AdUi from './ad-ui.js';
import SdkImpl from './sdk-impl.js';
/**
* The grand coordinator of the plugin. Facilitates communication between all
* other plugin classes.
*
* @param {Object} player Instance of the video.js player.
* @param {Object} options Options provided by the implementation.
* @constructor
* @struct
* @final
*/
const Controller = function(player, options) {
/**
* Stores user-provided settings.
* @type {Object}
*/
this.settings = {};
/**
* Content and ads ended listeners passed by the publisher to the plugin.
* These will be called when the plugin detects that content *and all
* ads* have completed. This differs from the contentEndedListeners in that
* contentEndedListeners will fire between content ending and a post-roll
* playing, whereas the contentAndAdsEndedListeners will fire after the
* post-roll completes.
*/
this.contentAndAdsEndedListeners = [];
/**
* Whether or not we are running on a mobile platform.
*/
this.isMobile = (navigator.userAgent.match(/iPhone/i) ||
navigator.userAgent.match(/iPad/i) ||
navigator.userAgent.match(/Android/i));
/**
* Whether or not we are running on an iOS platform.
*/
this.isIos = (navigator.userAgent.match(/iPhone/i) ||
navigator.userAgent.match(/iPad/i));
this.initWithSettings(options);
/**
* Stores contrib-ads default settings.
*/
const contribAdsDefaults = {
debug: this.settings.debug,
timeout: this.settings.timeout,
prerollTimeout: this.settings.prerollTimeout,
};
const adsPluginSettings = this.extend(
{}, contribAdsDefaults, options.contribAdsSettings || {});
this.playerWrapper = new PlayerWrapper(player, adsPluginSettings, this);
this.adUi = new AdUi(this);
this.sdkImpl = new SdkImpl(this);
};
Controller.IMA_DEFAULTS = {
adLabel: 'Advertisement',
adLabelNofN: 'of',
debug: false,
disableAdControls: false,
prerollTimeout: 1000,
preventLateAdStart: false,
requestMode: 'onLoad',
showControlsForJSAds: true,
timeout: 5000,
};
/**
* Extends the settings to include user-provided settings.
*
* @param {Object} options Options to be used in initialization.
*/
Controller.prototype.initWithSettings = function(options) {
this.settings = this.extend({}, Controller.IMA_DEFAULTS, options || {});
this.warnAboutDeprecatedSettings();
// Default showing countdown timer to true.
this.showCountdown = true;
if (this.settings.showCountdown === false) {
this.showCountdown = false;
}
};
/**
* Logs console warnings when deprecated settings are used.
*/
Controller.prototype.warnAboutDeprecatedSettings = function() {
const deprecatedSettings = [
'adWillAutoplay',
'adsWillAutoplay',
'adWillPlayMuted',
'adsWillPlayMuted',
];
deprecatedSettings.forEach((setting) => {
if (this.settings[setting] !== undefined) {
console.warn(
'WARNING: videojs.ima setting ' + setting + ' is deprecated');
}
});
};
/**
* Return the settings object.
*
* @return {Object} The settings object.
*/
Controller.prototype.getSettings = function() {
return this.settings;
};
/**
* Return whether or not we're in a mobile environment.
*
* @return {boolean} True if running on mobile, false otherwise.
*/
Controller.prototype.getIsMobile = function() {
return this.isMobile;
};
/**
* Return whether or not we're in an iOS environment.
*
* @return {boolean} True if running on iOS, false otherwise.
*/
Controller.prototype.getIsIos = function() {
return this.isIos;
};
/**
* Inject the ad container div into the DOM.
*
* @param{HTMLElement} adContainerDiv The ad container div.
*/
Controller.prototype.injectAdContainerDiv = function(adContainerDiv) {
this.playerWrapper.injectAdContainerDiv(adContainerDiv);
};
/**
* @return {HTMLElement} The div for the ad container.
*/
Controller.prototype.getAdContainerDiv = function() {
return this.adUi.getAdContainerDiv();
};
/**
* @return {Object} The content player.
*/
Controller.prototype.getContentPlayer = function() {
return this.playerWrapper.getContentPlayer();
};
/**
* Returns the content playhead tracker.
*
* @return {Object} The content playhead tracker.
*/
Controller.prototype.getContentPlayheadTracker = function() {
return this.playerWrapper.getContentPlayheadTracker();
};
/**
* Requests ads.
*/
Controller.prototype.requestAds = function() {
this.sdkImpl.requestAds();
};
/**
* Add or modify a setting.
*
* @param {string} key Key to modify
* @param {Object} value Value to set at key.
*/
Controller.prototype.setSetting = function(key, value) {
this.settings[key] = value;
};
/**
* Called when there is an error loading ads.
*
* @param {Object} adErrorEvent The ad error event thrown by the IMA SDK.
*/
Controller.prototype.onErrorLoadingAds = function(adErrorEvent) {
this.adUi.onAdError();
this.playerWrapper.onAdError(adErrorEvent);
};
/**
* Called by the ad UI when the play/pause button is clicked.
*/
Controller.prototype.onAdPlayPauseClick = function() {
if (this.sdkImpl.isAdPlaying()) {
this.adUi.onAdsPaused();
this.sdkImpl.pauseAds();
} else {
this.adUi.onAdsPlaying();
this.sdkImpl.resumeAds();
}
};
/**
* Called by the ad UI when the mute button is clicked.
*
*/
Controller.prototype.onAdMuteClick = function() {
if (this.sdkImpl.isAdMuted()) {
this.playerWrapper.unmute();
this.adUi.unmute();
this.sdkImpl.unmute();
} else {
this.playerWrapper.mute();
this.adUi.mute();
this.sdkImpl.mute();
}
};
/**
* Set the volume of the player and ads. 0-1.
*
* @param {number} volume The new volume.
*/
Controller.prototype.setVolume = function(volume) {
this.playerWrapper.setVolume(volume);
this.sdkImpl.setVolume(volume);
};
/**
* @return {number} The volume of the content player.
*/
Controller.prototype.getPlayerVolume = function() {
return this.playerWrapper.getVolume();
};
/**
* Toggle fullscreen state.
*/
Controller.prototype.toggleFullscreen = function() {
this.playerWrapper.toggleFullscreen();
};
/**
* Relays ad errors to the player wrapper.
*
* @param {Object} adErrorEvent The ad error event thrown by the IMA SDK.
*/
Controller.prototype.onAdError = function(adErrorEvent) {
this.adUi.onAdError();
this.playerWrapper.onAdError(adErrorEvent);
};
/**
* Handles ad break starting.
*
* @param {Object} adEvent The event fired by the IMA SDK.
*/
Controller.prototype.onAdBreakStart = function(adEvent) {
this.playerWrapper.onAdBreakStart();
this.adUi.onAdBreakStart(adEvent);
};
/**
* Show the ad container.
*/
Controller.prototype.showAdContainer = function() {
this.adUi.showAdContainer();
};
/**
* Handles ad break ending.
*/
Controller.prototype.onAdBreakEnd = function() {
this.playerWrapper.onAdBreakEnd();
this.adUi.onAdBreakEnd();
};
/**
* Handles when all ads have finished playing.
*/
Controller.prototype.onAllAdsCompleted = function() {
this.adUi.onAllAdsCompleted();
this.playerWrapper.onAllAdsCompleted();
};
/**
* Handles the SDK firing an ad paused event.
*/
Controller.prototype.onAdsPaused = function() {
this.adUi.onAdsPaused();
};
/**
* Handles the SDK firing an ad resumed event.
*/
Controller.prototype.onAdsResumed = function() {
this.adUi.onAdsResumed();
};
/**
* Takes data from the sdk impl and passes it to the ad UI to update the UI.
*
* @param {number} currentTime Current time of the ad.
* @param {number} remainingTime Remaining time of the ad.
* @param {number} duration Duration of the ad.
* @param {number} adPosition Index of the ad in the pod.
* @param {number} totalAds Total number of ads in the pod.
*/
Controller.prototype.onAdPlayheadUpdated =
function(currentTime, remainingTime, duration, adPosition, totalAds) {
this.adUi.updateAdUi(
currentTime, remainingTime, duration, adPosition, totalAds);
};
/**
* Handles ad log messages.
* @param {google.ima.AdEvent} adEvent The AdEvent thrown by the IMA SDK.
*/
Controller.prototype.onAdLog = function(adEvent) {
this.playerWrapper.onAdLog(adEvent);
};
/**
* @return {Object} The current ad.
*/
Controller.prototype.getCurrentAd = function() {
return this.sdkImpl.getCurrentAd();
};
/**
* Play content.
*/
Controller.prototype.playContent = function() {
this.playerWrapper.play();
};
/**
* Handles when a linear ad starts.
*/
Controller.prototype.onLinearAdStart = function() {
this.adUi.onLinearAdStart();
this.playerWrapper.onAdStart();
};
/**
* Handles when a non-linear ad loads.
*/
Controller.prototype.onNonLinearAdLoad = function() {
this.adUi.onNonLinearAdLoad();
};
/**
* Handles when a non-linear ad starts.
*/
Controller.prototype.onNonLinearAdStart = function() {
this.adUi.onNonLinearAdLoad();
this.playerWrapper.onAdStart();
};
/**
* Get the player width.
*
* @return {number} The width of the player.
*/
Controller.prototype.getPlayerWidth = function() {
return this.playerWrapper.getPlayerWidth();
};
/**
* Get the player height.
*
* @return {number} The height of the player.
*/
Controller.prototype.getPlayerHeight = function() {
return this.playerWrapper.getPlayerHeight();
};
/**
* Tells the player wrapper that ads are ready.
*/
Controller.prototype.onAdsReady = function() {
this.playerWrapper.onAdsReady();
};
/**
* Called when the player wrapper detects that the player has been resized.
*
* @param {number} width The post-resize width of the player.
* @param {number} height The post-resize height of the player.
*/
Controller.prototype.onPlayerResize = function(width, height) {
this.sdkImpl.onPlayerResize(width, height);
};
/**
* Called by the player wrapper when content completes.
*/
Controller.prototype.onContentComplete = function() {
this.sdkImpl.onContentComplete();
};
/**
* Called by the player wrapper when it's time to play a post-roll but we don't
* have one to play.
*/
Controller.prototype.onNoPostroll = function() {
this.playerWrapper.onNoPostroll();
};
/**
* Called when content and all ads have completed.
*/
Controller.prototype.onContentAndAdsCompleted = function() {
for (let index in this.contentAndAdsEndedListeners) {
if (typeof this.contentAndAdsEndedListeners[index] === 'function') {
this.contentAndAdsEndedListeners[index]();
}
}
};
/**
* Called when the player is disposed.
*/
Controller.prototype.onPlayerDisposed = function() {
this.contentAndAdsEndedListeners = [];
this.sdkImpl.onPlayerDisposed();
};
/**
* Called when the player is ready to play a pre-roll.
*/
Controller.prototype.onPlayerReadyForPreroll = function() {
this.sdkImpl.onPlayerReadyForPreroll();
};
/**
* Called if the ad times out.
*/
Controller.prototype.onAdTimeout = function() {
this.sdkImpl.onAdTimeout();
};
/**
* Called when the player is ready.
*/
Controller.prototype.onPlayerReady = function() {
this.sdkImpl.onPlayerReady();
};
/**
* Called when the player enters fullscreen.
*/
Controller.prototype.onPlayerEnterFullscreen = function() {
this.adUi.onPlayerEnterFullscreen();
this.sdkImpl.onPlayerEnterFullscreen();
};
/**
* Called when the player exits fullscreen.
*/
Controller.prototype.onPlayerExitFullscreen = function() {
this.adUi.onPlayerExitFullscreen();
this.sdkImpl.onPlayerExitFullscreen();
};
/**
* Called when the player volume changes.
*
* @param {number} volume The new player volume.
*/
Controller.prototype.onPlayerVolumeChanged = function(volume) {
this.adUi.onPlayerVolumeChanged(volume);
this.sdkImpl.onPlayerVolumeChanged(volume);
};
/**
* Sets the content of the video player. You should use this method instead
* of setting the content src directly to ensure the proper ad tag is
* requested when the video content is loaded.
* @param {?string} contentSrc The URI for the content to be played. Leave
* blank to use the existing content.
* @param {?string} adTag The ad tag to be requested when the content loads.
* Leave blank to use the existing ad tag.
*/
Controller.prototype.setContentWithAdTag =
function(contentSrc, adTag) {
this.reset();
this.settings.adTagUrl = adTag ? adTag : this.settings.adTagUrl;
this.playerWrapper.changeSource(contentSrc);
};
/**
* Sets the content of the video player. You should use this method instead
* of setting the content src directly to ensure the proper ads response is
* used when the video content is loaded.
* @param {?string} contentSrc The URI for the content to be played. Leave
* blank to use the existing content.
* @param {?string} adsResponse The ads response to be requested when the
* content loads. Leave blank to use the existing ads response.
*/
Controller.prototype.setContentWithAdsResponse =
function(contentSrc, adsResponse) {
this.reset();
this.settings.adsResponse =
adsResponse ? adsResponse : this.settings.adsResponse;
this.playerWrapper.changeSource(contentSrc);
};
/**
* Sets the content of the video player. You should use this method instead
* of setting the content src directly to ensure the proper ads request is
* used when the video content is loaded.
* @param {?string} contentSrc The URI for the content to be played. Leave
* blank to use the existing content.
* @param {?Object} adsRequest The ads request to be requested when the
* content loads. Leave blank to use the existing ads request.
*/
Controller.prototype.setContentWithAdsRequest =
function(contentSrc, adsRequest) {
this.reset();
this.settings.adsRequest =
adsRequest ? adsRequest : this.settings.adsRequest;
this.playerWrapper.changeSource(contentSrc);
};
/**
* Resets the state of the plugin.
*/
Controller.prototype.reset = function() {
this.sdkImpl.reset();
this.playerWrapper.reset();
this.adUi.reset();
};
/**
* Listener JSDoc for ESLint. This listener can be passed to
* (add|remove)ContentEndedListener.
* @callback listener
*/
/**
* Adds a listener for the 'contentended' event of the video player. This should
* be used instead of setting an 'contentended' listener directly to ensure that
* the ima can do proper cleanup of the SDK before other event listeners are
* called.
* @param {listener} listener The listener to be called when content
* completes.
*/
Controller.prototype.addContentEndedListener = function(listener) {
this.playerWrapper.addContentEndedListener(listener);
};
/**
* Adds a listener that will be called when content and all ads have
* finished playing.
* @param {listener} listener The listener to be called when content and ads
* complete.
*/
Controller.prototype.addContentAndAdsEndedListener = function(listener) {
this.contentAndAdsEndedListeners.push(listener);
};
/**
* Sets the listener to be called to trigger manual ad break playback.
* @param {listener} listener The listener to be called to trigger manual ad
* break playback.
*/
Controller.prototype.setAdBreakReadyListener = function(listener) {
this.sdkImpl.setAdBreakReadyListener(listener);
};
/**
* Changes the flag to show or hide the ad countdown timer.
*
* @param {boolean} showCountdownIn Show or hide the countdown timer.
*/
Controller.prototype.setShowCountdown = function(showCountdownIn) {
this.adUi.setShowCountdown(showCountdownIn);
this.showCountdown = showCountdownIn;
this.adUi.countdownDiv.style.display = this.showCountdown ? 'block' : 'none';
};
/**
* Initializes the AdDisplayContainer. On mobile, this must be done as a
* result of user action.
*/
Controller.prototype.initializeAdDisplayContainer = function() {
this.sdkImpl.initializeAdDisplayContainer();
};
/**
* Called by publishers in manual ad break playback mode to start an ad
* break.
*/
Controller.prototype.playAdBreak = function() {
this.sdkImpl.playAdBreak();
};
/**
* Callback JSDoc for ESLint. This callback can be passed to addEventListener.
* @callback callback
*/
/**
* Ads an EventListener to the AdsManager. For a list of available events,
* see
* https://developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/reference/js/google.ima.AdEvent#.Type
* @param {google.ima.AdEvent.Type} event The AdEvent.Type for which to
* listen.
* @param {callback} callback The method to call when the event is fired.
*/
Controller.prototype.addEventListener = function(event, callback) {
this.sdkImpl.addEventListener(event, callback);
};
/**
* Returns the instance of the AdsManager.
* @return {google.ima.AdsManager} The AdsManager being used by the plugin.
*/
Controller.prototype.getAdsManager = function() {
return this.sdkImpl.getAdsManager();
};
/**
* Returns the instance of the player id.
* @return {string} The player id.
*/
Controller.prototype.getPlayerId = function() {
return this.playerWrapper.getPlayerId();
};
/**
* Changes the ad tag. You will need to call requestAds after this method
* for the new ads to be requested.
* @param {?string} adTag The ad tag to be requested the next time
* requestAds is called.
*/
Controller.prototype.changeAdTag = function(adTag) {
this.reset();
this.settings.adTagUrl = adTag;
};
/**
* Pauses the ad.
*/
Controller.prototype.pauseAd = function() {
this.adUi.onAdsPaused();
this.sdkImpl.pauseAds();
};
/**
* Resumes the ad.
*/
Controller.prototype.resumeAd = function() {
this.adUi.onAdsPlaying();
this.sdkImpl.resumeAds();
};
/**
* Toggles video/ad playback.
*/
Controller.prototype.togglePlayback = function() {
this.playerWrapper.togglePlayback();
};
/**
* @return {boolean} true if we expect that ads will autoplay. false otherwise.
*/
Controller.prototype.adsWillAutoplay = function() {
if (this.settings.adsWillAutoplay !== undefined) {
return this.settings.adsWillAutoplay;
} else if (this.settings.adWillAutoplay !== undefined) {
return this.settings.adWillAutoplay;
} else {
return !!this.playerWrapper.getPlayerOptions().autoplay;
}
};
/**
* @return {boolean} true if we expect that ads will autoplay. false otherwise.
*/
Controller.prototype.adsWillPlayMuted = function() {
if (this.settings.adsWillPlayMuted !== undefined) {
return this.settings.adsWillPlayMuted;
} else if (this.settings.adWillPlayMuted !== undefined) {
return this.settings.adWillPlayMuted;
} else if (this.playerWrapper.getPlayerOptions().muted !== undefined) {
return this.playerWrapper.getPlayerOptions().muted;
} else {
return this.playerWrapper.getVolume() == 0;
}
};
/**
* Triggers an event on the VJS player
* @param {string} name The event name.
* @param {Object} data The event data.
*/
Controller.prototype.triggerPlayerEvent = function(name, data) {
this.playerWrapper.triggerPlayerEvent(name, data);
};
/**
* Extends an object to include the contents of objects at parameters 2 onward.
*
* @param {Object} obj The object onto which the subsequent objects' parameters
* will be extended. This object will be modified.
* @param {...Object} var_args The objects whose properties are to be extended
* onto obj.
* @return {Object} The extended object.
*/
Controller.prototype.extend = function(obj, ...args) {
let arg;
let index;
let key;
for (index = 0; index < args.length; index++) {
arg = args[index];
for (key in arg) {
if (arg.hasOwnProperty(key)) {
obj[key] = arg[key];
}
}
}
return obj;
};
export default Controller;

174
node_modules/videojs-ima/src/css/videojs.ima.css generated vendored Normal file
View file

@ -0,0 +1,174 @@
/**
* Copyright 2014 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
.ima-ad-container {
top: 0em;
position: absolute;
display: none;
width: 100%;
height: 100%;
}
/* Move overlay if user fast-clicks play button. */
.video-js.vjs-playing .bumpable-ima-ad-container {
margin-top: -4em;
}
/* Move overlay when controls are active. */
.video-js.vjs-user-inactive.vjs-playing .bumpable-ima-ad-container {
margin-top: 0em;
}
.video-js.vjs-paused .bumpable-ima-ad-container,
.video-js.vjs-playing:hover .bumpable-ima-ad-container,
.video-js.vjs-user-active.vjs-playing .bumpable-ima-ad-container {
margin-top: -4em;
}
.ima-controls-div {
bottom: 0em;
height: 1.4em;
position: absolute;
overflow: hidden;
display: none;
opacity: 1;
background-color: rgba(7, 20, 30, .7);
background: -moz-linear-gradient(
bottom,
rgba(7, 20, 30, .7) 0%,
rgba(7, 20, 30, 0) 100%); /* FF3.6+ */
background: -webkit-gradient(
linear,
left bottom,
left top,
color-stop(0%,rgba(7, 20, 30, .7)),
color-stop(100%,rgba(7, 20, 30, 0))); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(
bottom,
rgba(7, 20, 30, .7) 0%,
rgba(7, 20, 30, 0) 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(bottom,
rgba(7, 20, 30, .7) 0%,
rgba(7, 20, 30, 0) 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(bottom,
rgba(7, 20, 30, .7) 0%,
rgba(7, 20, 30, 0) 100%); /* IE10+ */
background: linear-gradient(to top,
rgba(7, 20, 30, .7) 0%,
rgba(7, 20, 30, 0) 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient(
startColorstr='#0007141E',
endColorstr='#07141E',GradientType=0 ); /* IE6-9 */
}
.ima-controls-div.ima-controls-div-showing {
height: 3.7em;
}
.ima-countdown-div {
height: 1em;
color: #FFFFFF;
text-shadow: 0 0 0.2em #000;
cursor: default;
}
.ima-seek-bar-div {
top: 1.2em;
height: 0.3em;
position: absolute;
background: rgba(255, 255, 255, .4);
}
.ima-progress-div {
width: 0em;
height: 0.3em;
background-color: #ECC546;
}
.ima-play-pause-div, .ima-mute-div, .ima-slider-div, .ima-fullscreen-div {
width: 2.33em;
height: 1.33em;
top: 0.733em;
left: 0em;
position: absolute;
color: #CCCCCC;
font-size: 1.5em;
line-height: 2;
text-align: center;
font-family: VideoJS;
cursor: pointer;
}
.ima-mute-div {
left: auto;
right: 5.667em;
}
.ima-slider-div {
left: auto;
right: 2.33em;
width: 3.33em;
height: 0.667em;
top: 1.33em;
background-color: #555555;
}
.ima-slider-level-div {
width: 100%;
height: 0.667em;
background-color: #ECC546;
}
.ima-fullscreen-div {
left: auto;
right: 0em;
}
.ima-playing:before {
content: "\00f103";
}
.ima-paused:before {
content: "\00f101";
}
.ima-playing:hover:before, .ima-paused:hover:before {
text-shadow: 0 0 1em #fff;
}
.ima-non-muted:before {
content: "\00f107";
}
.ima-muted:before {
content: "\00f104";
}
.ima-non-muted:hover:before, .ima-muted:hover:before {
text-shadow: 0 0 1em #fff;
}
.ima-non-fullscreen:before {
content: "\00f108";
}
.ima-fullscreen:before {
content: "\00f109";
}
.ima-non-fullscreen:hover:before, .ima-fullscreen:hover:before {
text-shadow: 0 0 1em #fff;
}

221
node_modules/videojs-ima/src/ima-plugin.js generated vendored Normal file
View file

@ -0,0 +1,221 @@
/**
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* IMA SDK integration plugin for Video.js. For more information see
* https://www.github.com/googleads/videojs-ima
*/
import Controller from './controller.js';
import videojs from 'video.js';
/**
* Exposes the ImaPlugin to a publisher implementation.
*
* @param {Object} player Instance of the video.js player to which this plugin
* will be added.
* @param {Object} options Options provided by the implementation.
* @constructor
* @struct
* @final
*/
const ImaPlugin = function(player, options) {
this.controller = new Controller(player, options);
/**
* Listener JSDoc for ESLint. This listener can be passed to
* addContent(AndAds)EndedListener.
* @callback listener
*/
/**
* Adds a listener that will be called when content and all ads have
* finished playing.
* @param {listener} listener The listener to be called when content and ads
* complete.
*/
this.addContentAndAdsEndedListener = function(listener) {
this.controller.addContentAndAdsEndedListener(listener);
}.bind(this);
/**
* Adds a listener for the 'contentended' event of the video player. This
* should be used instead of setting an 'contentended' listener directly to
* ensure that the ima can do proper cleanup of the SDK before other event
* listeners are called.
* @param {listener} listener The listener to be called when content
* completes.
*/
this.addContentEndedListener = function(listener) {
this.controller.addContentEndedListener(listener);
}.bind(this);
/**
* Callback JSDoc for ESLint. This callback can be passed to addEventListener.
* @callback callback
*/
/**
* Ads an EventListener to the AdsManager. For a list of available events,
* see
* https://developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/reference/js/google.ima.AdEvent#.Type
* @param {google.ima.AdEvent.Type} event The AdEvent.Type for which to
* listen.
* @param {callback} callback The method to call when the event is fired.
*/
this.addEventListener = function(event, callback) {
this.controller.addEventListener(event, callback);
}.bind(this);
/**
* Changes the ad tag. You will need to call requestAds after this method
* for the new ads to be requested.
* @param {?string} adTag The ad tag to be requested the next time requestAds
* is called.
*/
this.changeAdTag = function(adTag) {
this.controller.changeAdTag(adTag);
}.bind(this);
/**
* Returns the instance of the AdsManager.
* @return {google.ima.AdsManager} The AdsManager being used by the plugin.
*/
this.getAdsManager = function() {
return this.controller.getAdsManager();
}.bind(this);
/**
* Initializes the AdDisplayContainer. On mobile, this must be done as a
* result of user action.
*/
this.initializeAdDisplayContainer = function() {
this.controller.initializeAdDisplayContainer();
}.bind(this);
/**
* Pauses the ad.
*/
this.pauseAd = function() {
this.controller.pauseAd();
}.bind(this);
/**
* Called by publishers in manual ad break playback mode to start an ad
* break.
*/
this.playAdBreak = function() {
this.controller.playAdBreak();
}.bind(this);
/**
* Creates the AdsRequest and request ads through the AdsLoader.
*/
this.requestAds = function() {
this.controller.requestAds();
}.bind(this);
/**
* Resumes the ad.
*/
this.resumeAd = function() {
this.controller.resumeAd();
}.bind(this);
/**
* Sets the listener to be called to trigger manual ad break playback.
* @param {listener} listener The listener to be called to trigger manual ad
* break playback.
*/
this.setAdBreakReadyListener = function(listener) {
this.controller.setAdBreakReadyListener(listener);
}.bind(this);
/**
* Sets the content of the video player. You should use this method instead
* of setting the content src directly to ensure the proper ad tag is
* requested when the video content is loaded.
* @param {?string} contentSrc The URI for the content to be played. Leave
* blank to use the existing content.
* @param {?string} adTag The ad tag to be requested when the content loads.
* Leave blank to use the existing ad tag.
*/
this.setContentWithAdTag = function(contentSrc, adTag) {
this.controller.setContentWithAdTag(contentSrc, adTag);
}.bind(this);
/**
* Sets the content of the video player. You should use this method instead
* of setting the content src directly to ensure the proper ads response is
* used when the video content is loaded.
* @param {?string} contentSrc The URI for the content to be played. Leave
* blank to use the existing content.
* @param {?string} adsResponse The ads response to be requested when the
* content loads. Leave blank to use the existing ads response.
*/
this.setContentWithAdsResponse =
function(contentSrc, adsResponse) {
this.controller.setContentWithAdsResponse(
contentSrc, adsResponse);
}.bind(this);
/**
* Sets the content of the video player. You should use this method instead
* of setting the content src directly to ensure the proper ads request is
* used when the video content is loaded.
* @param {?string} contentSrc The URI for the content to be played. Leave
* blank to use the existing content.
* @param {?Object} adsRequest The ads request to be requested when the
* content loads. Leave blank to use the existing ads request.
*/
this.setContentWithAdsRequest =
function(contentSrc, adsRequest) {
this.controller.setContentWithAdsRequest(
contentSrc, adsRequest);
}.bind(this);
/**
* Changes the flag to show or hide the ad countdown timer.
*
* @param {boolean} showCountdownIn Show or hide the countdown timer.
*/
this.setShowCountdown = function(showCountdownIn) {
this.controller.setShowCountdown(showCountdownIn);
}.bind(this);
};
const init = function(options) {
/* eslint no-invalid-this: 'off' */
this.ima = new ImaPlugin(this, options);
};
const registerPlugin = videojs.registerPlugin || videojs.plugin;
registerPlugin('ima', init);
export default ImaPlugin;

641
node_modules/videojs-ima/src/player-wrapper.js generated vendored Normal file
View file

@ -0,0 +1,641 @@
/**
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* IMA SDK integration plugin for Video.js. For more information see
* https://www.github.com/googleads/videojs-ima
*/
/**
* Wraps the video.js player for the plugin.
*
* @param {Object} player Video.js player instance.
* @param {Object} adsPluginSettings Settings for the contrib-ads plugin.
* @param {Controller} controller Reference to the parent controller.
*/
const PlayerWrapper = function(player, adsPluginSettings, controller) {
/**
* Instance of the video.js player.
*/
this.vjsPlayer = player;
/**
* Plugin controller.
*/
this.controller = controller;
/**
* Timer used to track content progress.
*/
this.contentTrackingTimer = null;
/**
* True if our content video has completed, false otherwise.
*/
this.contentComplete = false;
/**
* Handle to interval that repeatedly updates current time.
*/
this.updateTimeIntervalHandle = null;
/**
* Interval (ms) to check for player resize for fluid support.
*/
this.updateTimeInterval = 1000;
/**
* Handle to interval that repeatedly checks for seeking.
*/
this.seekCheckIntervalHandle = null;
/**
* Interval (ms) on which to check if the user is seeking through the
* content.
*/
this.seekCheckInterval = 1000;
/**
* Handle to interval that repeatedly checks for player resize.
*/
this.resizeCheckIntervalHandle = null;
/**
* Interval (ms) to check for player resize for fluid support.
*/
this.resizeCheckInterval = 250;
/**
* Threshold by which to judge user seeking. We check every 1000 ms to see
* if the user is seeking. In order for us to decide that they are *not*
* seeking, the content video playhead must only change by 900-1100 ms
* between checks. Any greater change and we assume the user is seeking
* through the video.
*/
this.seekThreshold = 100;
/**
* Content ended listeners passed by the publisher to the plugin. Publishers
* should allow the plugin to handle content ended to ensure proper support
* of custom ad playback.
*/
this.contentEndedListeners = [];
/**
* Stores the content source so we can re-populate it manually after a
* post-roll on iOS.
*/
this.contentSource = '';
/**
* Stores the content source type so we can re-populate it manually after a
* post-roll.
*/
this.contentSourceType = '';
/**
* Stores data for the content playhead tracker.
*/
this.contentPlayheadTracker = {
currentTime: 0,
previousTime: 0,
seeking: false,
duration: 0,
};
/**
* Player dimensions. Used in our resize check.
*/
this.vjsPlayerDimensions = {
width: this.getPlayerWidth(),
height: this.getPlayerHeight(),
};
/**
* Video.js control bar.
*/
this.vjsControls = this.vjsPlayer.getChild('controlBar');
/**
* Vanilla HTML5 video player underneath the video.js player.
*/
this.h5Player = null;
this.vjsPlayer.one('play', this.setUpPlayerIntervals.bind(this));
this.boundContentEndedListener = this.localContentEndedListener.bind(this);
this.vjsPlayer.on('contentended', this.boundContentEndedListener);
this.vjsPlayer.on('dispose', this.playerDisposedListener.bind(this));
this.vjsPlayer.on('readyforpreroll', this.onReadyForPreroll.bind(this));
this.vjsPlayer.on('adtimeout', this.onAdTimeout.bind(this));
this.vjsPlayer.ready(this.onPlayerReady.bind(this));
if (this.controller.getSettings().requestMode === 'onPlay') {
this.vjsPlayer.one('play',
this.controller.requestAds.bind(this.controller));
}
this.vjsPlayer.ads(adsPluginSettings);
};
/**
* Set up the intervals we use on the player.
*/
PlayerWrapper.prototype.setUpPlayerIntervals = function() {
this.updateTimeIntervalHandle =
setInterval(this.updateCurrentTime.bind(this), this.updateTimeInterval);
this.seekCheckIntervalHandle =
setInterval(this.checkForSeeking.bind(this), this.seekCheckInterval);
this.resizeCheckIntervalHandle =
setInterval(this.checkForResize.bind(this), this.resizeCheckInterval);
};
/**
* Updates the current time of the video
*/
PlayerWrapper.prototype.updateCurrentTime = function() {
if (!this.contentPlayheadTracker.seeking) {
this.contentPlayheadTracker.currentTime = this.vjsPlayer.currentTime();
}
};
/**
* Detects when the user is seeking through a video.
* This is used to prevent mid-rolls from playing while a user is seeking.
*
* There *is* a seeking property of the HTML5 video element, but it's not
* properly implemented on all platforms (e.g. mobile safari), so we have to
* check ourselves to be sure.
*/
PlayerWrapper.prototype.checkForSeeking = function() {
const tempCurrentTime = this.vjsPlayer.currentTime();
const diff =
(tempCurrentTime - this.contentPlayheadTracker.previousTime) * 1000;
if (Math.abs(diff) > this.seekCheckInterval + this.seekThreshold) {
this.contentPlayheadTracker.seeking = true;
} else {
this.contentPlayheadTracker.seeking = false;
}
this.contentPlayheadTracker.previousTime = this.vjsPlayer.currentTime();
};
/**
* Detects when the player is resized (for fluid support) and resizes the
* ads manager to match.
*/
PlayerWrapper.prototype.checkForResize = function() {
const currentWidth = this.getPlayerWidth();
const currentHeight = this.getPlayerHeight();
if (currentWidth != this.vjsPlayerDimensions.width ||
currentHeight != this.vjsPlayerDimensions.height) {
this.vjsPlayerDimensions.width = currentWidth;
this.vjsPlayerDimensions.height = currentHeight;
this.controller.onPlayerResize(currentWidth, currentHeight);
}
};
/**
* Local content ended listener for contentComplete.
*/
PlayerWrapper.prototype.localContentEndedListener = function() {
if (!this.contentComplete) {
this.contentComplete = true;
this.controller.onContentComplete();
}
for (let index in this.contentEndedListeners) {
if (typeof this.contentEndedListeners[index] === 'function') {
this.contentEndedListeners[index]();
}
}
clearInterval(this.updateTimeIntervalHandle);
clearInterval(this.seekCheckIntervalHandle);
clearInterval(this.resizeCheckIntervalHandle);
if (this.vjsPlayer.el()) {
this.vjsPlayer.one('play', this.setUpPlayerIntervals.bind(this));
}
};
/**
* Called when it's time to play a post-roll but we don't have one to play.
*/
PlayerWrapper.prototype.onNoPostroll = function() {
this.vjsPlayer.trigger('nopostroll');
};
/**
* Detects when the video.js player has been disposed.
*/
PlayerWrapper.prototype.playerDisposedListener = function() {
this.contentEndedListeners = [];
this.controller.onPlayerDisposed();
this.contentComplete = true;
this.vjsPlayer.off('contentended', this.boundContentEndedListener);
// Bug fix: https://github.com/googleads/videojs-ima/issues/306
if (this.vjsPlayer.ads.adTimeoutTimeout) {
clearTimeout(this.vjsPlayer.ads.adTimeoutTimeout);
}
const intervalsToClear = [
this.updateTimeIntervalHandle,
this.seekCheckIntervalHandle,
this.resizeCheckIntervalHandle];
for (let index in intervalsToClear) {
if (intervalsToClear[index]) {
clearInterval(intervalsToClear[index]);
}
}
};
/**
* Start ad playback, or content video playback in the absence of a
* pre-roll.
*/
PlayerWrapper.prototype.onReadyForPreroll = function() {
this.controller.onPlayerReadyForPreroll();
};
/**
* Detects if the ad has timed out.
*/
PlayerWrapper.prototype.onAdTimeout = function() {
this.controller.onAdTimeout();
};
/**
* Called when the player fires its 'ready' event.
*/
PlayerWrapper.prototype.onPlayerReady = function() {
this.h5Player =
document.getElementById(
this.getPlayerId()).getElementsByClassName(
'vjs-tech')[0];
// Detect inline options
if (this.h5Player.hasAttribute('autoplay')) {
this.controller.setSetting('adWillAutoPlay', true);
}
// Sync ad volume with player volume.
this.onVolumeChange();
this.vjsPlayer.on('fullscreenchange', this.onFullscreenChange.bind(this));
this.vjsPlayer.on('volumechange', this.onVolumeChange.bind(this));
this.controller.onPlayerReady();
};
/**
* Listens for the video.js player to change its fullscreen status. This
* keeps the fullscreen-ness of the AdContainer in sync with the player.
*/
PlayerWrapper.prototype.onFullscreenChange = function() {
if (this.vjsPlayer.isFullscreen()) {
this.controller.onPlayerEnterFullscreen();
} else {
this.controller.onPlayerExitFullscreen();
}
};
/**
* Listens for the video.js player to change its volume. This keeps the ad
* volume in sync with the content volume if the volume of the player is
* changed while content is playing.
*/
PlayerWrapper.prototype.onVolumeChange = function() {
const newVolume = this.vjsPlayer.muted() ? 0 : this.vjsPlayer.volume();
this.controller.onPlayerVolumeChanged(newVolume);
};
/**
* Inject the ad container div into the DOM.
*
* @param{HTMLElement} adContainerDiv The ad container div.
*/
PlayerWrapper.prototype.injectAdContainerDiv = function(adContainerDiv) {
this.vjsControls.el().parentNode.appendChild(adContainerDiv);
};
/**
* @return {Object} The content player.
*/
PlayerWrapper.prototype.getContentPlayer = function() {
return this.h5Player;
};
/**
* @return {number} The volume, 0-1.
*/
PlayerWrapper.prototype.getVolume = function() {
return this.vjsPlayer.muted() ? 0 : this.vjsPlayer.volume();
};
/**
* Set the volume of the player. 0-1.
*
* @param {number} volume The new volume.
*/
PlayerWrapper.prototype.setVolume = function(volume) {
this.vjsPlayer.volume(volume);
if (volume == 0) {
this.vjsPlayer.muted(true);
} else {
this.vjsPlayer.muted(false);
}
};
/**
* Ummute the player.
*/
PlayerWrapper.prototype.unmute = function() {
this.vjsPlayer.muted(false);
};
/**
* Mute the player.
*/
PlayerWrapper.prototype.mute = function() {
this.vjsPlayer.muted(true);
};
/**
* Play the video.
*/
PlayerWrapper.prototype.play = function() {
this.vjsPlayer.play();
};
/**
* Toggles playback of the video.
*/
PlayerWrapper.prototype.togglePlayback = function() {
if (this.vjsPlayer.paused()) {
this.vjsPlayer.play();
} else {
this.vjsPlayer.pause();
}
};
/**
* Get the player width.
*
* @return {number} The player's width.
*/
PlayerWrapper.prototype.getPlayerWidth = function() {
let width = (getComputedStyle(this.vjsPlayer.el()) || {}).width;
if (!width || parseFloat(width) === 0) {
width = (this.vjsPlayer.el().getBoundingClientRect() || {}).width;
}
return parseFloat(width) || this.vjsPlayer.width();
};
/**
* Get the player height.
*
* @return {number} The player's height.
*/
PlayerWrapper.prototype.getPlayerHeight = function() {
let height = (getComputedStyle(this.vjsPlayer.el()) || {}).height;
if (!height || parseFloat(height) === 0) {
height = (this.vjsPlayer.el().getBoundingClientRect() || {}).height;
}
return parseFloat(height) || this.vjsPlayer.height();
};
/**
* @return {Object} The vjs player's options object.
*/
PlayerWrapper.prototype.getPlayerOptions = function() {
return this.vjsPlayer.options_;
};
/**
* Returns the instance of the player id.
* @return {string} The player id.
*/
PlayerWrapper.prototype.getPlayerId = function() {
return this.vjsPlayer.id();
};
/**
* Toggle fullscreen state.
*/
PlayerWrapper.prototype.toggleFullscreen = function() {
if (this.vjsPlayer.isFullscreen()) {
this.vjsPlayer.exitFullscreen();
} else {
this.vjsPlayer.requestFullscreen();
}
};
/**
* Returns the content playhead tracker.
*
* @return {Object} The content playhead tracker.
*/
PlayerWrapper.prototype.getContentPlayheadTracker = function() {
return this.contentPlayheadTracker;
};
/**
* Handles ad errors.
*
* @param {Object} adErrorEvent The ad error event thrown by the IMA SDK.
*/
PlayerWrapper.prototype.onAdError = function(adErrorEvent) {
this.vjsControls.show();
const errorMessage =
adErrorEvent.getError !== undefined ?
adErrorEvent.getError() : adErrorEvent.stack;
this.vjsPlayer.trigger({type: 'adserror', data: {
AdError: errorMessage,
AdErrorEvent: adErrorEvent,
}});
};
/**
* Handles ad log messages.
* @param {google.ima.AdEvent} adEvent The AdEvent thrown by the IMA SDK.
*/
PlayerWrapper.prototype.onAdLog = function(adEvent) {
const adData = adEvent.getAdData();
const errorMessage =
adData['adError'] !== undefined ?
adData['adError'].getMessage() : undefined;
this.vjsPlayer.trigger({type: 'adslog', data: {
AdError: errorMessage,
AdEvent: adEvent,
}});
};
/**
* Handles ad break starting.
*/
PlayerWrapper.prototype.onAdBreakStart = function() {
this.contentSource = this.vjsPlayer.currentSrc();
this.contentSourceType = this.vjsPlayer.currentType();
this.vjsPlayer.off('contentended', this.boundContentEndedListener);
this.vjsPlayer.ads.startLinearAdMode();
this.vjsControls.hide();
this.vjsPlayer.pause();
};
/**
* Handles ad break ending.
*/
PlayerWrapper.prototype.onAdBreakEnd = function() {
this.vjsPlayer.on('contentended', this.boundContentEndedListener);
if (this.vjsPlayer.ads.inAdBreak()) {
this.vjsPlayer.ads.endLinearAdMode();
}
this.vjsControls.show();
};
/**
* Handles an individual ad start.
*/
PlayerWrapper.prototype.onAdStart = function() {
this.vjsPlayer.trigger('ads-ad-started');
};
/**
* Handles when all ads have finished playing.
*/
PlayerWrapper.prototype.onAllAdsCompleted = function() {
if (this.contentComplete == true) {
// The null check on this.contentSource was added to fix
// an error when the post-roll was an empty VAST tag.
if (this.contentSource &&
this.vjsPlayer.currentSrc() != this.contentSource) {
this.vjsPlayer.src({
src: this.contentSource,
type: this.contentSourceType,
});
}
this.controller.onContentAndAdsCompleted();
}
};
/**
* Triggers adsready for contrib-ads.
*/
PlayerWrapper.prototype.onAdsReady = function() {
this.vjsPlayer.trigger('adsready');
};
/**
* Changes the player source.
* @param {?string} contentSrc The URI for the content to be played. Leave
* blank to use the existing content.
*/
PlayerWrapper.prototype.changeSource = function(contentSrc) {
// Only try to pause the player when initialised with a source already
if (this.vjsPlayer.currentSrc()) {
this.vjsPlayer.currentTime(0);
this.vjsPlayer.pause();
}
if (contentSrc) {
this.vjsPlayer.src(contentSrc);
}
this.vjsPlayer.one('loadedmetadata', this.seekContentToZero.bind(this));
};
/**
* Seeks content to 00:00:00. This is used as an event handler for the
* loadedmetadata event, since seeking is not possible until that event has
* fired.
*/
PlayerWrapper.prototype.seekContentToZero = function() {
this.vjsPlayer.currentTime(0);
};
/**
* Triggers an event on the VJS player
* @param {string} name The event name.
* @param {Object} data The event data.
*/
PlayerWrapper.prototype.triggerPlayerEvent = function(name, data) {
this.vjsPlayer.trigger(name, data);
};
/**
* Listener JSDoc for ESLint. This listener can be passed to
* addContentEndedListener.
* @callback listener
*/
/**
* Adds a listener for the 'contentended' event of the video player. This should
* be used instead of setting an 'contentended' listener directly to ensure that
* the ima can do proper cleanup of the SDK before other event listeners are
* called.
* @param {listener} listener The listener to be called when content
* completes.
*/
PlayerWrapper.prototype.addContentEndedListener = function(listener) {
this.contentEndedListeners.push(listener);
};
/**
* Reset the player.
*/
PlayerWrapper.prototype.reset = function() {
// Attempts to remove the contentEndedListener before adding it.
// This is to prevent an error where an erroring video caused multiple
// contentEndedListeners to be added.
this.vjsPlayer.off('contentended', this.boundContentEndedListener);
this.vjsPlayer.on('contentended', this.boundContentEndedListener);
this.vjsControls.show();
if (this.vjsPlayer.ads.inAdBreak()) {
this.vjsPlayer.ads.endLinearAdMode();
}
// Reset the content time we give the SDK. Fixes an issue where requesting
// VMAP followed by VMAP would play the second mid-rolls as pre-rolls if
// the first playthrough of the video passed the second response's
// mid-roll time.
this.contentPlayheadTracker.currentTime = 0;
this.contentComplete = false;
};
export default PlayerWrapper;

844
node_modules/videojs-ima/src/sdk-impl.js generated vendored Normal file
View file

@ -0,0 +1,844 @@
/**
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* IMA SDK integration plugin for Video.js. For more information see
* https://www.github.com/googleads/videojs-ima
*/
import pkg from '../package.json';
/**
* Implementation of the IMA SDK for the plugin.
*
* @param {Object} controller Reference to the parent controller.
*
* @constructor
* @struct
* @final
*/
const SdkImpl = function(controller) {
/**
* Plugin controller.
*/
this.controller = controller;
/**
* IMA SDK AdDisplayContainer.
*/
this.adDisplayContainer = null;
/**
* True if the AdDisplayContainer has been initialized. False otherwise.
*/
this.adDisplayContainerInitialized = false;
/**
* IMA SDK AdsLoader
*/
this.adsLoader = null;
/**
* IMA SDK AdsManager
*/
this.adsManager = null;
/**
* IMA SDK AdsRenderingSettings.
*/
this.adsRenderingSettings = null;
/**
* VAST, VMAP, or ad rules response. Used in lieu of fetching a response
* from an ad tag URL.
*/
this.adsResponse = null;
/**
* Current IMA SDK Ad.
*/
this.currentAd = null;
/**
* Timer used to track ad progress.
*/
this.adTrackingTimer = null;
/**
* True if ALL_ADS_COMPLETED has fired, false until then.
*/
this.allAdsCompleted = false;
/**
* True if ads are currently displayed, false otherwise.
* True regardless of ad pause state if an ad is currently being displayed.
*/
this.adsActive = false;
/**
* True if ad is currently playing, false if ad is paused or ads are not
* currently displayed.
*/
this.adPlaying = false;
/**
* True if the ad is muted, false otherwise.
*/
this.adMuted = false;
/**
* Listener to be called to trigger manual ad break playback.
*/
this.adBreakReadyListener = undefined;
/**
* Tracks whether or not we have already called adsLoader.contentComplete().
*/
this.contentCompleteCalled = false;
/**
* True if the ad has timed out.
*/
this.isAdTimedOut = false;
/**
* Stores the dimensions for the ads manager.
*/
this.adsManagerDimensions = {
width: 0,
height: 0,
};
/**
* Boolean flag to enable manual ad break playback.
*/
this.autoPlayAdBreaks = true;
if (this.controller.getSettings().autoPlayAdBreaks === false) {
this.autoPlayAdBreaks = false;
}
// Set SDK settings from plugin settings.
if (this.controller.getSettings().locale) {
/* eslint no-undef: 'error' */
/* global google */
google.ima.settings.setLocale(this.controller.getSettings().locale);
}
if (this.controller.getSettings().disableFlashAds) {
google.ima.settings.setDisableFlashAds(
this.controller.getSettings().disableFlashAds);
}
if (this.controller.getSettings().disableCustomPlaybackForIOS10Plus) {
google.ima.settings.setDisableCustomPlaybackForIOS10Plus(
this.controller.getSettings().disableCustomPlaybackForIOS10Plus);
}
if (this.controller.getSettings().ppid) {
google.ima.settings.setPpid(this.controller.getSettings().ppid);
}
if (this.controller.getSettings().featureFlags) {
google.ima.settings
.setFeatureFlags(this.controller.getSettings().featureFlags);
}
};
/**
* Creates and initializes the IMA SDK objects.
*/
SdkImpl.prototype.initAdObjects = function() {
this.adDisplayContainer = new google.ima.AdDisplayContainer(
this.controller.getAdContainerDiv(),
this.controller.getContentPlayer());
this.adsLoader = new google.ima.AdsLoader(this.adDisplayContainer);
this.adsLoader.getSettings().setVpaidMode(
google.ima.ImaSdkSettings.VpaidMode.ENABLED);
if (this.controller.getSettings().vpaidAllowed == false) {
this.adsLoader.getSettings().setVpaidMode(
google.ima.ImaSdkSettings.VpaidMode.DISABLED);
}
if (this.controller.getSettings().vpaidMode !== undefined) {
this.adsLoader.getSettings().setVpaidMode(
this.controller.getSettings().vpaidMode);
}
if (this.controller.getSettings().locale) {
this.adsLoader.getSettings().setLocale(
this.controller.getSettings().locale);
}
if (this.controller.getSettings().numRedirects) {
this.adsLoader.getSettings().setNumRedirects(
this.controller.getSettings().numRedirects);
}
if (this.controller.getSettings().sessionId) {
this.adsLoader.getSettings().setSessionId(
this.controller.getSettings().sessionId);
}
this.adsLoader.getSettings().setPlayerType('videojs-ima');
this.adsLoader.getSettings().setPlayerVersion(pkg.version);
this.adsLoader.getSettings().setAutoPlayAdBreaks(this.autoPlayAdBreaks);
this.adsLoader.addEventListener(
google.ima.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED,
this.onAdsManagerLoaded.bind(this),
false);
this.adsLoader.addEventListener(
google.ima.AdErrorEvent.Type.AD_ERROR,
this.onAdsLoaderError.bind(this),
false);
this.controller.playerWrapper.vjsPlayer.trigger({
type: 'ads-loader',
adsLoader: this.adsLoader,
});
};
/**
* Creates the AdsRequest and request ads through the AdsLoader.
*/
SdkImpl.prototype.requestAds = function() {
const adsRequest = new google.ima.AdsRequest();
if (this.controller.getSettings().adTagUrl) {
adsRequest.adTagUrl = this.controller.getSettings().adTagUrl;
} else {
adsRequest.adsResponse = this.controller.getSettings().adsResponse;
}
if (this.controller.getSettings().forceNonLinearFullSlot) {
adsRequest.forceNonLinearFullSlot = true;
}
if (this.controller.getSettings().vastLoadTimeout) {
adsRequest.vastLoadTimeout = this.controller.getSettings().vastLoadTimeout;
}
if (this.controller.getSettings().omidMode) {
adsRequest.omidAccessModeRules = {};
const omidValues = this.controller.getSettings().omidMode;
if (omidValues.FULL) {
adsRequest.omidAccessModeRules[google.ima.OmidAccessMode.FULL] =
omidValues.FULL;
}
if (omidValues.DOMAIN) {
adsRequest.omidAccessModeRules[google.ima.OmidAccessMode.DOMAIN] =
omidValues.DOMAIN;
}
if (omidValues.LIMITED) {
adsRequest.omidAccessModeRules[google.ima.OmidAccessMode.LIMITED] =
omidValues.LIMITED;
}
}
adsRequest.linearAdSlotWidth = this.controller.getPlayerWidth();
adsRequest.linearAdSlotHeight = this.controller.getPlayerHeight();
adsRequest.nonLinearAdSlotWidth =
this.controller.getSettings().nonLinearWidth ||
this.controller.getPlayerWidth();
adsRequest.nonLinearAdSlotHeight =
this.controller.getSettings().nonLinearHeight ||
this.controller.getPlayerHeight();
adsRequest.setAdWillAutoPlay(this.controller.adsWillAutoplay());
adsRequest.setAdWillPlayMuted(this.controller.adsWillPlayMuted());
// Populate the adsRequestproperties with those provided in the AdsRequest
// object in the settings.
let providedAdsRequest = this.controller.getSettings().adsRequest;
if (providedAdsRequest && typeof providedAdsRequest === 'object') {
Object.keys(providedAdsRequest).forEach((key) => {
adsRequest[key] = providedAdsRequest[key];
});
}
this.adsLoader.requestAds(adsRequest);
this.controller.playerWrapper.vjsPlayer.trigger({
type: 'ads-request',
AdsRequest: adsRequest,
});
};
/**
* Listener for the ADS_MANAGER_LOADED event. Creates the AdsManager,
* sets up event listeners, and triggers the 'adsready' event for
* videojs-ads-contrib.
*
* @param {google.ima.AdsManagerLoadedEvent} adsManagerLoadedEvent Fired when
* the AdsManager loads.
*/
SdkImpl.prototype.onAdsManagerLoaded = function(adsManagerLoadedEvent) {
this.createAdsRenderingSettings();
this.adsManager = adsManagerLoadedEvent.getAdsManager(
this.controller.getContentPlayheadTracker(), this.adsRenderingSettings);
this.adsManager.addEventListener(
google.ima.AdErrorEvent.Type.AD_ERROR,
this.onAdError.bind(this));
this.adsManager.addEventListener(
google.ima.AdEvent.Type.AD_BREAK_READY,
this.onAdBreakReady.bind(this));
this.adsManager.addEventListener(
google.ima.AdEvent.Type.CONTENT_PAUSE_REQUESTED,
this.onContentPauseRequested.bind(this));
this.adsManager.addEventListener(
google.ima.AdEvent.Type.CONTENT_RESUME_REQUESTED,
this.onContentResumeRequested.bind(this));
this.adsManager.addEventListener(
google.ima.AdEvent.Type.ALL_ADS_COMPLETED,
this.onAllAdsCompleted.bind(this));
this.adsManager.addEventListener(
google.ima.AdEvent.Type.LOADED,
this.onAdLoaded.bind(this));
this.adsManager.addEventListener(
google.ima.AdEvent.Type.STARTED,
this.onAdStarted.bind(this));
this.adsManager.addEventListener(
google.ima.AdEvent.Type.COMPLETE,
this.onAdComplete.bind(this));
this.adsManager.addEventListener(
google.ima.AdEvent.Type.SKIPPED,
this.onAdComplete.bind(this));
this.adsManager.addEventListener(
google.ima.AdEvent.Type.LOG,
this.onAdLog.bind(this));
this.adsManager.addEventListener(
google.ima.AdEvent.Type.PAUSED,
this.onAdPaused.bind(this));
this.adsManager.addEventListener(
google.ima.AdEvent.Type.RESUMED,
this.onAdResumed.bind(this));
this.controller.playerWrapper.vjsPlayer.trigger({
type: 'ads-manager',
adsManager: this.adsManager,
});
if (!this.autoPlayAdBreaks) {
this.initAdsManager();
}
const {preventLateAdStart} = this.controller.getSettings();
if (!preventLateAdStart) {
this.controller.onAdsReady();
} else if (preventLateAdStart &&
!this.isAdTimedOut) {
this.controller.onAdsReady();
}
if (this.controller.getSettings().adsManagerLoadedCallback) {
this.controller.getSettings().adsManagerLoadedCallback();
}
};
/**
* Listener for errors fired by the AdsLoader.
* @param {google.ima.AdErrorEvent} event The error event thrown by the
* AdsLoader. See
* https://developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/reference/js/google.ima.AdError#.Type
*/
SdkImpl.prototype.onAdsLoaderError = function(event) {
window.console.warn('AdsLoader error: ' + event.getError());
this.controller.onErrorLoadingAds(event);
if (this.adsManager) {
this.adsManager.destroy();
}
};
/**
* Initialize the ads manager.
*/
SdkImpl.prototype.initAdsManager = function() {
try {
const initWidth = this.controller.getPlayerWidth();
const initHeight = this.controller.getPlayerHeight();
this.adsManagerDimensions.width = initWidth;
this.adsManagerDimensions.height = initHeight;
this.adsManager.init(
initWidth,
initHeight,
google.ima.ViewMode.NORMAL);
this.adsManager.setVolume(this.controller.getPlayerVolume());
this.initializeAdDisplayContainer();
} catch (adError) {
this.onAdError(adError);
}
};
/**
* Create AdsRenderingSettings for the IMA SDK.
*/
SdkImpl.prototype.createAdsRenderingSettings = function() {
this.adsRenderingSettings = new google.ima.AdsRenderingSettings();
this.adsRenderingSettings.restoreCustomPlaybackStateOnAdBreakComplete =
true;
if (this.controller.getSettings().adsRenderingSettings) {
for (let setting in this.controller.getSettings().adsRenderingSettings) {
if (setting !== '') {
this.adsRenderingSettings[setting] =
this.controller.getSettings().adsRenderingSettings[setting];
}
}
}
};
/**
* Listener for errors thrown by the AdsManager.
* @param {google.ima.AdErrorEvent} adErrorEvent The error event thrown by
* the AdsManager.
*/
SdkImpl.prototype.onAdError = function(adErrorEvent) {
const errorMessage =
adErrorEvent.getError !== undefined ?
adErrorEvent.getError() : adErrorEvent.stack;
window.console.warn('Ad error: ' + errorMessage);
this.adsManager.destroy();
this.controller.onAdError(adErrorEvent);
// reset these so consumers don't think we are still in an ad break,
// but reset them after any prior cleanup happens
this.adsActive = false;
this.adPlaying = false;
};
/**
* Listener for AD_BREAK_READY. Passes event on to publisher's listener.
* @param {google.ima.AdEvent} adEvent AdEvent thrown by the AdsManager.
*/
SdkImpl.prototype.onAdBreakReady = function(adEvent) {
this.adBreakReadyListener(adEvent);
};
/**
* Pauses the content video and displays the ad container so ads can play.
* @param {google.ima.AdEvent} adEvent The AdEvent thrown by the AdsManager.
*/
SdkImpl.prototype.onContentPauseRequested = function(adEvent) {
this.adsActive = true;
this.adPlaying = true;
this.controller.onAdBreakStart(adEvent);
};
/**
* Resumes content video and hides the ad container.
* @param {google.ima.AdEvent} adEvent The AdEvent thrown by the AdsManager.
*/
SdkImpl.prototype.onContentResumeRequested = function(adEvent) {
this.adsActive = false;
this.adPlaying = false;
this.controller.onAdBreakEnd();
// Hide controls in case of future non-linear ads. They'll be unhidden in
// content_pause_requested.
};
/**
* Records that ads have completed and calls contentAndAdsEndedListeners
* if content is also complete.
* @param {google.ima.AdEvent} adEvent The AdEvent thrown by the AdsManager.
*/
SdkImpl.prototype.onAllAdsCompleted = function(adEvent) {
this.allAdsCompleted = true;
this.controller.onAllAdsCompleted();
};
/**
* Starts the content video when a non-linear ad is loaded.
* @param {google.ima.AdEvent} adEvent The AdEvent thrown by the AdsManager.
*/
SdkImpl.prototype.onAdLoaded = function(adEvent) {
if (!adEvent.getAd().isLinear()) {
this.controller.onNonLinearAdLoad();
this.controller.playContent();
}
};
/**
* Starts the interval timer to check the current ad time when an ad starts
* playing.
* @param {google.ima.AdEvent} adEvent The AdEvent thrown by the AdsManager.
*/
SdkImpl.prototype.onAdStarted = function(adEvent) {
this.currentAd = adEvent.getAd();
if (this.currentAd.isLinear()) {
this.adTrackingTimer = setInterval(
this.onAdPlayheadTrackerInterval.bind(this), 250);
this.controller.onLinearAdStart();
} else {
this.controller.onNonLinearAdStart();
}
};
/**
* Handles an ad click. Puts the player UI in a paused state.
*/
SdkImpl.prototype.onAdPaused = function() {
this.controller.onAdsPaused();
};
/**
* Syncs controls when an ad resumes.
* @param {google.ima.AdEvent} adEvent The AdEvent thrown by the AdsManager.
*/
SdkImpl.prototype.onAdResumed = function(adEvent) {
this.controller.onAdsResumed();
};
/**
* Clears the interval timer for current ad time when an ad completes.
*/
SdkImpl.prototype.onAdComplete = function() {
if (this.currentAd.isLinear()) {
clearInterval(this.adTrackingTimer);
}
};
/**
* Handles ad log messages.
* @param {google.ima.AdEvent} adEvent The AdEvent thrown by the AdsManager.
*/
SdkImpl.prototype.onAdLog = function(adEvent) {
this.controller.onAdLog(adEvent);
};
/**
* Gets the current time and duration of the ad and calls the method to
* update the ad UI.
*/
SdkImpl.prototype.onAdPlayheadTrackerInterval = function() {
if (this.adsManager === null) return;
const remainingTime = this.adsManager.getRemainingTime();
const duration = this.currentAd.getDuration();
let currentTime = duration - remainingTime;
currentTime = currentTime > 0 ? currentTime : 0;
let totalAds = 0;
let adPosition;
if (this.currentAd.getAdPodInfo()) {
adPosition = this.currentAd.getAdPodInfo().getAdPosition();
totalAds = this.currentAd.getAdPodInfo().getTotalAds();
}
this.controller.onAdPlayheadUpdated(
currentTime, remainingTime, duration, adPosition, totalAds);
};
/**
* Called by the player wrapper when content completes.
*/
SdkImpl.prototype.onContentComplete = function() {
if (this.adsLoader) {
this.adsLoader.contentComplete();
this.contentCompleteCalled = true;
}
if ((this.adsManager &&
this.adsManager.getCuePoints() &&
!this.adsManager.getCuePoints().includes(-1))
||
!this.adsManager) {
this.controller.onNoPostroll();
}
if (this.allAdsCompleted) {
this.controller.onContentAndAdsCompleted();
}
};
/**
* Called when the player is disposed.
*/
SdkImpl.prototype.onPlayerDisposed = function() {
if (this.adTrackingTimer) {
clearInterval(this.adTrackingTimer);
}
if (this.adsManager) {
this.adsManager.destroy();
this.adsManager = null;
}
};
SdkImpl.prototype.onPlayerReadyForPreroll = function() {
if (this.autoPlayAdBreaks) {
this.initAdsManager();
try {
this.controller.showAdContainer();
// Sync ad volume with content volume.
this.adsManager.setVolume(this.controller.getPlayerVolume());
this.adsManager.start();
} catch (adError) {
this.onAdError(adError);
}
}
};
SdkImpl.prototype.onAdTimeout = function() {
this.isAdTimedOut = true;
};
SdkImpl.prototype.onPlayerReady = function() {
this.initAdObjects();
if ((this.controller.getSettings().adTagUrl ||
this.controller.getSettings().adsResponse) &&
this.controller.getSettings().requestMode === 'onLoad') {
this.requestAds();
}
};
SdkImpl.prototype.onPlayerEnterFullscreen = function() {
if (this.adsManager) {
this.adsManager.resize(
window.screen.width,
window.screen.height,
google.ima.ViewMode.FULLSCREEN);
}
};
SdkImpl.prototype.onPlayerExitFullscreen = function() {
if (this.adsManager) {
this.adsManager.resize(
this.controller.getPlayerWidth(),
this.controller.getPlayerHeight(),
google.ima.ViewMode.NORMAL);
}
};
/**
* Called when the player volume changes.
*
* @param {number} volume The new player volume.
*/
SdkImpl.prototype.onPlayerVolumeChanged = function(volume) {
if (this.adsManager) {
this.adsManager.setVolume(volume);
}
if (volume == 0) {
this.adMuted = true;
} else {
this.adMuted = false;
}
};
/**
* Called when the player wrapper detects that the player has been resized.
*
* @param {number} width The post-resize width of the player.
* @param {number} height The post-resize height of the player.
*/
SdkImpl.prototype.onPlayerResize = function(width, height) {
if (this.adsManager) {
this.adsManagerDimensions.width = width;
this.adsManagerDimensions.height = height;
/* global google */
/* eslint no-undef: 'error' */
this.adsManager.resize(width, height, google.ima.ViewMode.NORMAL);
}
};
/**
* @return {Object} The current ad.
*/
SdkImpl.prototype.getCurrentAd = function() {
return this.currentAd;
};
/**
* Listener JSDoc for ESLint. This listener can be passed to
* setAdBreakReadyListener.
* @callback listener
*/
/**
* Sets the listener to be called to trigger manual ad break playback.
* @param {listener} listener The listener to be called to trigger manual ad
* break playback.
*/
SdkImpl.prototype.setAdBreakReadyListener = function(listener) {
this.adBreakReadyListener = listener;
};
/**
* @return {boolean} True if an ad is currently playing. False otherwise.
*/
SdkImpl.prototype.isAdPlaying = function() {
return this.adPlaying;
};
/**
* @return {boolean} True if an ad is currently playing. False otherwise.
*/
SdkImpl.prototype.isAdMuted = function() {
return this.adMuted;
};
/**
* Pause ads.
*/
SdkImpl.prototype.pauseAds = function() {
this.adsManager.pause();
this.adPlaying = false;
};
/**
* Resume ads.
*/
SdkImpl.prototype.resumeAds = function() {
this.adsManager.resume();
this.adPlaying = true;
};
/**
* Unmute ads.
*/
SdkImpl.prototype.unmute = function() {
this.adsManager.setVolume(1);
this.adMuted = false;
};
/**
* Mute ads.
*/
SdkImpl.prototype.mute = function() {
this.adsManager.setVolume(0);
this.adMuted = true;
};
/**
* Set the volume of the ads. 0-1.
*
* @param {number} volume The new volume.
*/
SdkImpl.prototype.setVolume = function(volume) {
this.adsManager.setVolume(volume);
if (volume == 0) {
this.adMuted = true;
} else {
this.adMuted = false;
}
};
/**
* Initializes the AdDisplayContainer. On mobile, this must be done as a
* result of user action.
*/
SdkImpl.prototype.initializeAdDisplayContainer = function() {
if (this.adDisplayContainer) {
if (!this.adDisplayContainerInitialized) {
this.adDisplayContainer.initialize();
this.adDisplayContainerInitialized = true;
}
}
};
/**
* Called by publishers in manual ad break playback mode to start an ad
* break.
*/
SdkImpl.prototype.playAdBreak = function() {
if (!this.autoPlayAdBreaks) {
this.controller.showAdContainer();
// Sync ad volume with content volume.
this.adsManager.setVolume(this.controller.getPlayerVolume());
this.adsManager.start();
}
};
/**
* Callback JSDoc for ESLint. This callback can be passed to addEventListener.
* @callback callback
*/
/**
* Ads an EventListener to the AdsManager. For a list of available events,
* see
* https://developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/reference/js/google.ima.AdEvent#.Type
* @param {google.ima.AdEvent.Type} event The AdEvent.Type for which to
* listen.
* @param {callback} callback The method to call when the event is fired.
*/
SdkImpl.prototype.addEventListener = function(event, callback) {
if (this.adsManager) {
this.adsManager.addEventListener(event, callback);
}
};
/**
* Returns the instance of the AdsManager.
* @return {google.ima.AdsManager} The AdsManager being used by the plugin.
*/
SdkImpl.prototype.getAdsManager = function() {
return this.adsManager;
};
/**
* Reset the SDK implementation.
*/
SdkImpl.prototype.reset = function() {
this.adsActive = false;
this.adPlaying = false;
if (this.adTrackingTimer) {
// If this is called while an ad is playing, stop trying to get that
// ad's current time.
clearInterval(this.adTrackingTimer);
}
if (this.adsManager) {
this.adsManager.destroy();
this.adsManager = null;
}
if (this.adsLoader && !this.contentCompleteCalled) {
this.adsLoader.contentComplete();
}
this.contentCompleteCalled = false;
this.allAdsCompleted = false;
};
export default SdkImpl;