Skip to content

Commit

Permalink
✨ amp-video-iframe integration: global jwplayer() singleton by default (
Browse files Browse the repository at this point in the history
ampproject#26969)

`jwplayer()` will return the singleton instance, which makes sense as a default for a single iframed video.

Otherwise passed in explicitly like in: https://glitch.com/edit/#!/amp-video-iframe-jwplayer?path=jwplayer.html
  • Loading branch information
alanorozco authored Feb 27, 2020
1 parent 59d5517 commit 4847c7f
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 18 deletions.
28 changes: 21 additions & 7 deletions extensions/amp-video-iframe/amp-video-iframe.md
Original file line number Diff line number Diff line change
Expand Up @@ -250,15 +250,29 @@ You can additionally use [custom integration methods](#custom-integrations) if y

**Default supported methods:** `pause`/`play`, `mute`/`unmute`, `hidecontrols`/`showcontrols`, `fullscreenenter`/`fullscreenexit`

Pass in your [`jwplayer` instance object](https://developer.jwplayer.com/jw-player/docs/javascript-api-reference/)
through the signature `ampIntegration.listenTo('jwplayer', myJwplayer)`. The `ampIntegration` object then knows how
to setup the player through the instance API.
The `amp` object knows how to setup a JwPlayer instance by using `listenTo('jwplayer')`.
If you're embedding your player [using a video-specific script](https://support.jwplayer.com/articles/how-to-embed-a-jwplayer), you only need to register Jwplayer usage:

```html
<script src="https://cdn.jwplayer.com/players/UVQWMA4o-kGWxh33Q.js"></script>
<script>
(window.AmpVideoIframe = window.AmpVideoIframe || []).push(function(
ampIntegration
) {
ampIntegration.listenTo('jwplayer');
});
</script>
```

Otherwise, pass in your [JwPlayer instance](https://developer.jwplayer.com/jwplayer/docs/jw8-javascript-api-reference)
through the signature `amp.listenTo('jwplayer', instance)`:

```js
function onAmpIntegrationReady(ampIntegration) {
var myJwplayer = jwplayer('my-video');
ampIntegration.listenTo('jwplayer', myJwplayer);
}
(window.AmpVideoIframe = window.AmpVideoIframe || []).push(function(
ampIntegration
) {
ampIntegration.listenTo('jwplayer', jwplayer('my-video'));
});
```

##### For Video.js
Expand Down
44 changes: 33 additions & 11 deletions src/video-iframe-integration.js
Original file line number Diff line number Diff line change
Expand Up @@ -190,30 +190,32 @@ export class AmpVideoIntegration {

/**
* @param {string} type
* @param {*} obj
* @param {*=} opt_obj
* @param {function()=} opt_initializer For VideoJS, this optionally takes a
* reference to the `videojs` function. If not provided, this reference
* will be taken from the `window` object.
* reference to the `videojs` function. If not provided, this reference
* will be taken from the `window` object.
*/
listenTo(type, obj, opt_initializer) {
listenTo(type, opt_obj, opt_initializer) {
userAssert(
!this.usedListenToHelper_,
'`listenTo` is meant to be used once per page.'
);
const types = {
'jwplayer': () => {
userAssert(
obj.on,
'jwplayer integration takes a jwplayer instance as first argument.'
);
userAssert(
!opt_initializer,
'jwplayer integration does not take an initializer.'
"listenTo('jwplayer', opt_instance) does not take an initializer."
);
this.listenToJwPlayer_(obj);
this.listenToJwPlayer_(this.getJwplayer_(opt_obj));
},
'videojs': () => {
this.listenToVideoJs_(obj, opt_initializer);
this.listenToVideoJs_(
userAssert(
opt_obj,
"listenTo('videojs', element) expects a second argument"
),
opt_initializer
);
},
};
userAssert(
Expand All @@ -224,6 +226,26 @@ export class AmpVideoIntegration {
this.usedListenToHelper_ = true;
}

/**
* Checks comformity for opt_player, or obtains global singleton instance.
* @param {?JwplayerPartialInterfaceDef=} opt_player
* @return {!JwplayerPartialInterfaceDef}
*/
getJwplayer_(opt_player) {
if (opt_player) {
userAssert(
opt_player.on,
"listenTo('jwplayer', myjwplayer) takes a jwplayer instance as ",
'second argument'
);
return opt_player;
}
return userAssert(
this.win_.jwplayer,
"listenTo('jwplayer') expects a global jwplayer() in window."
)(); // notice the call here ;)
}

/**
* @param {!JwplayerPartialInterfaceDef} player
* @private
Expand Down
7 changes: 7 additions & 0 deletions test/unit/test-video-iframe-integration.js
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,13 @@ describes.realWin('video-iframe-integration', {amp: false}, env => {
});
});

it('uses global jwplayer() to get instance when not passed in', () => {
const instance = {on: env.sandbox.spy()};
env.win.jwplayer = env.sandbox.stub().returns(instance);
new AmpVideoIntegration(env.win).listenTo('jwplayer');
expect(instance.on).to.have.been.called;
});

function mockVideoJsPlayer() {
return {
ready(fn) {
Expand Down

0 comments on commit 4847c7f

Please sign in to comment.