Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add amp-hulu element for Hulu videos. #5993

Merged
merged 1 commit into from Nov 11, 2016
Merged

Conversation

unbug
Copy link
Contributor

@unbug unbug commented Nov 3, 2016

Intent to use amp-hulu element in Hulu website.

@googlebot
Copy link

We found a Contributor License Agreement for you (the sender of this pull request), but were unable to find agreements for the commit author(s). If you authored these, maybe you used a different email address in the git commits than was used to sign the CLA (login here to double check)? If these were authored by someone else, then they will need to sign a CLA as well, and confirm that they're okay with these being contributed to Google.

@googlebot
Copy link

CLAs look good, thanks!

@cramforce
Copy link
Member

@unbug Out of curiosity: Are you working for Hulu?

@unbug
Copy link
Contributor Author

unbug commented Nov 3, 2016

@cramforce I am :)
Check out our profile https://github.com/hulu

@aghassemi
Copy link
Contributor

@unbug, thanks for the PR.

Couple of questions before the code review:

1- Is any publisher allowed to use <amp-hulu> embeds or is it meant to only be used by Hulu's own AMP pages? ( 'https://secure.hulu.com` seems to be refusing origins other than http://*.hulu.com https://*.hulu.com *.optimizely.com)

2- Does the Hulu's iframe embed have a postMessage API that would allow <amp-hulu> to send commands such as pause, play, mute, unmute and receive events such as played, paused? We are requesting all new video players to implement our video-interface which would require such functionality.

@unbug
Copy link
Contributor Author

unbug commented Nov 4, 2016

@aghassemi Thanks for your time.

  1. <amp-hulu/> currently only servers Hulu's own AMP pages, but we do have a white list domain for publishers.
  2. Hulu's iframe embed doesn't have any postMessage API yet.

@aghassemi
Copy link
Contributor

@unbug Any reason <amp-iframe> does not fit your needs? We normally don't allow components that are meant for a single site.

@unbug
Copy link
Contributor Author

unbug commented Nov 6, 2016

@aghassemi Thanks for your time :)

  1. <amp-hulu/> will be used on Hulu's own sites first, and we have some partner publishers, they will try it too.
  2. We don't use <amp-iframe> because we think <amp-hulu/> is more easer for us to maintain and update, and it's more easer for our partners to keep it up to date.
  3. We just made a plan for the postMessage API, it's belong to Hulu Player Project, but we don't want to leave <amp-hulu/> behind, so we'd like to lunch <amp-hulu/> ASAP for our site team and partners.

iframe.setAttribute('allowfullscreen', 'true');
iframe.src = 'https://secure.hulu.com/dash/mobile_embed.html?eid=' + encodeURIComponent(eid);
this.applyFillContent(iframe);
iframe.width = width;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Setting the width and height on the iframe shouldn't be necessary as it's "fill-content".

@aghassemi
Copy link
Contributor

@unbug

  1. will be used on Hulu's own sites first, and we have some partner publishers, they will try it too.

That's fine but keep in mind that AMP pages can be served from caches such as cdn.ampproject.org. Whitelisting cdn.ampproject.org would allow any AMP page to embed <amp-hulu>, if that's not desired:

  • We are working on allowing publishers to get their own subdomain e.g. publisher.cdn.ampproject.org but that's not launched yet.
  • For now, to accurately validate access based on origin, you would need to rely on the __amp_source_origin param in addition to the referrer. So:
    1. pass the your iframe src to getCorsUrl in url.js that would add a new query string param __amp_source_origin with the true origin of the AMP document to your Url.
    2. Have hulu's server-side code allow access if referrer is cdn.ampproject.org AND __amp_source_origin's value is your whitelisted publisher.
    3. Note that relying on __amp_source_origin is safe if referrer is cdn.ampproject.org since AMP validation does not allow __amp_source_origin to be manually set by anyonem, so AMP pages can't hack
      your access protection by adding __amp_source_origin to any src or href (they won't pass validation)

We just made a plan for the postMessage API, it's belong to Hulu Player Project,

Good to hear, please implement the video-interface as soon as you have the necessary hooks. Implementing the video-interface will automatically enable features such as AMP-managed autoplay for your player.

I will send out the code review soon.

Copy link
Contributor

@aghassemi aghassemi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additional requests:
1- Validation file (validator-amp-hulu.protoascii) is missing. Please take a look at <amp-youtube> or other amp components for reference.

2- amp-hulu needs to be added to gulpfile.js to be built.

3- Please only submit when cdn.ampproject.org as referrer works as per previous comment.


/** @override */
createdCallback() {
this.preconnect.url('https://secure.hulu.com/dash/mobile_embed.html');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move to preconnectCallback override.


/** @override */
createdCallback() {
this.preconnect.url('https://secure.hulu.com/dash/mobile_embed.html');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just preconnect to https://secure.hulu.com, the path segment is not useful.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'https://secure.hulu.com` is refusing origins other than http://.hulu.com https://.hulu.com *.optimizely.com, but any request's referer is https://secure.hulu.com/dash/mobile_embed.html will not.
Should we preconnect to https://secure.hulu.com/dash/mobile_embed.html?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that's fine then, I did not realize 'https://secure.hulu.com` and tps://secure.hulu.com/dash/mobile_embed.html have different access policies.

import {user} from '../../../src/log';

class AmpHulu extends AMP.BaseElement {

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add constructor where iframe_ is defined.

  /** @param {!AmpElement} element */
  constructor(element) {
    super(element);

    /** @private {?Element} */
    this.iframe_ = null;
  }

iframe.width = width;
iframe.height = height;
this.element.appendChild(iframe);
/** @private {?Element} */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove this type annotation (since it will be annotated in the constructor per request above))

/** @override */
pauseCallback() {
if (this.iframe_ && this.iframe_.contentWindow) {
this.iframe_.contentWindow./*OK*/postMessage('pause', '*');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does this actually work? I thought there is no postMessage API. If this does not work yet, please remove the pauseCallaback and set

/** @override */
  unlayoutOnPause() {
    return true;
  }

until you have postMessage support.

<td class="col-fourty"><strong><a href="https://www.ampproject.org/docs/guides/responsive/control_layout.html">Supported Layouts</a></strong></td>
<td>fill, fixed, fixed-height, flex-item, nodisplay, responsive</td>
</tr>
<tr>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove it instead of a TODO, add back when example is there.

<td>(TODO) <a href="https://ampbyexample.com/components/amp-hulu/">Annotated code example for amp-hulu</a></td>
</tr>
</table>

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please mention the restrictions (in bold warning) and instructions on how publishers can signup for whitelisting.

## Example

```html
<amp-hulu width="400" height="400"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add layout="responsive" to the example


/** @override */
layoutCallback() {
const width = this.element.getAttribute('width');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as per @jridgewell's comment, no need to read the width/height values.

## Example

```html
<amp-hulu width="400" height="400"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use correct aspect ratio for this video ( width="412" height="231" ?)

@unbug
Copy link
Contributor Author

unbug commented Nov 8, 2016

@aghassemi Thanks for your time :)

AMP pages can be served from caches such as cdn.ampproject.org

I just talked to my team about the Content-Security-Policy issue. Yes, 'https://secure.hulu.com` is refusing origins other than http://*.hulu.com https://*.hulu.com *.optimizely.com, but any request's referer is https://secure.hulu.com/dash/mobile_embed.html will not.

  • But I don't understand for https://secure.hulu.com/dash/mobile_embed.html why any AMP pages can't be served from caches such as cdn.ampproject.org?
  • And why other websites can't use <amp-hulu>?
  • If we implement the video-interface will all these issues gone?

@aghassemi
Copy link
Contributor

But I don't understand for https://secure.hulu.com/dash/mobile_embed.html why any AMP pages can't be served from caches such as cdn.ampproject.org?
And why other websites can't use ?

I was under the impression that Hulu only allows certain origins to be able to embed Hulu videos, if that's not the case and any origin can embed Hulu videos, then it is not an issue at all.

# limitations under the license.
#

tags: { # amp-hulu
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Gregable @powdercloud @honeybadgerdontcare can somebody review this? seems to be causing a failure on the validator tests

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please rename the file to validator-amp-hulu.protoascii.

@aghassemi
Copy link
Contributor

@unbug Please let me know when this is ready for review again. Thanks!

attrs: {
name: "src"
mandatory: true
value_regex: "https://cdn\\.ampproject\\.org/v0/amp-hulu-(latest|0\\.1).js"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please escape the last "." e.g. \\.js

tags: { # <amp-hulu>
html_format: AMP
html_format: AMP4ADS
tag_name: "AMP-VINE"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tag_name should be AMP-HULU not AMP-VINE

tag_name: "AMP-VINE"
disallowed_ancestor: "AMP-SIDEBAR"
also_requires_tag: "amp-hulu extension .js script"
# data-* is generally allowed, but it's not generally mandatory.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need for this comment here.

disallowed_ancestor: "AMP-SIDEBAR"
also_requires_tag: "amp-hulu extension .js script"
# data-* is generally allowed, but it's not generally mandatory.
attrs: { name: "data-eid" mandatory: true }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit, please expand to multi-line.

attrs: {
name: "data-eid"
mandatory: true
}

supported_layouts: FIXED
supported_layouts: FIXED_HEIGHT
supported_layouts: FLEX_ITEM
supported_layouts: NODISPLAY
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Somewhat surprised to see nodisplay. Is that intentional? Wouldn't a video player want to be seen?

@@ -106,6 +106,7 @@ declareExtension('amp-viz-vega', '0.1', true);
declareExtension('amp-google-vrview-image', '0.1', false, 'NO_TYPE_CHECK');
declareExtension('amp-viewer-integration', '0.1', false);
declareExtension('amp-youtube', '0.1', false);
declareExtension('amp-hulu', '0.1', false, 'NO_TYPE_CHECK');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit, please put this in alphabetical order (even though some are not, lets try to keep it consistent).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@unbug
Copy link
Contributor Author

unbug commented Nov 10, 2016

Thanks @honeybadgerdontcare , I was wordering why it can't pass the travis. I had no idea about the validator rules, so I just followed vine's file, and it failed, so I talked to @erwinmombay in slack, it's not ready to reviewed yet. You're very helping, I'll make it right and re-summit again :)

@unbug
Copy link
Contributor Author

unbug commented Nov 10, 2016

@aghassemi It's ready, thanks 👍

@honeybadgerdontcare
Copy link
Contributor

@unbug validator rules look good. thanks!

Copy link
Contributor

@aghassemi aghassemi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @unbug. Two small requests and then we should be good to merge this.

iframe.src = 'https://secure.hulu.com/dash/mobile_embed.html?eid=' + encodeURIComponent(eid);
this.applyFillContent(iframe);
this.element.appendChild(iframe);
/** @private {?Element} */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove the type annotation, it is redundant at this point.

@@ -72,6 +72,7 @@ declareExtension('amp-form', '0.1', true);
declareExtension('amp-fresh', '0.1', true);
declareExtension('amp-fx-flying-carpet', '0.1', true);
declareExtension('amp-gfycat', '0.1', false);
declareExtension('amp-hulu', '0.1', false, 'NO_TYPE_CHECK');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove NO_TYPE_CHECK and allow the component to be type checked. Please run gulp check-types locally to ensure it passes type checking.


/** @override */
preconnectCallback() {
this.preconnect.url('https://secure.hulu.com/dash/mobile_embed.html');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be Preconnect#preload? The path won't be useful for #url.

Copy link
Contributor

@aghassemi aghassemi Nov 10, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@unbug Signature of this method is preconnectCallback(onLayout) and onLayout needs to be passed to this.preconnect.url as the last arg.

@jridgewell I had the same question but apparently https://secure.hulu.com/dash/mobile_embed.html and https://secure.hulu.com/ return different Content-Security-Policy response headers. I don't know if preconnect logic still keeps the connections if Content-Security-Policy is not met.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not #preload then? That'll get the right security headers and we won't have this question again. 😁

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@unbug let's do @jridgewell's suggestion for preload but you need to have the eid= appended to the Url before preloading. I suggest the following:

1- introduce a new instance variable this.eid_ in the cosntrcutor.
2- in buildCallback do the this.eid_ = user().assert(this.element.getAttribute('data-eid'), 'The data-eid attribute is required for <amp-hulu> %s', this.element); instead of in the layoutCallback as it does now.
3- Create a new getVideoIframeSrc_() which returns the Url with correct eid query string appended.
4- Use getVideoIframeSrc_() in preconnectCallback and layoutCallback

}

/** @override */
unlayoutOnPause() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@unbug
Copy link
Contributor Author

unbug commented Nov 11, 2016

@aghassemi @jridgewell Sorry for so much troubles, 👍 and thanks for your patience. I hope this time everything is ready :)

use es6 syntax

use const instead of let

added validator file

remove size expect

code reviewed

some updated

added amp-hulu

reviewd validator

code reviewed, remove NO_TYPE_CHECK, added getVideoIframeSrc_

syntax fixed
Copy link
Contributor

@jridgewell jridgewell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

/** @return {string} */
getVideoIframeSrc_() {
dev().assert(this.eid_);
return `https://secure.hulu.com/dash/mobile_embed.html?eid=${encodeURIComponent(this.eid_ || '')}`;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The || '' will never occur, since we've asserted #eid is truthy.

@aghassemi
Copy link
Contributor

@unbug LGTM.
Please keep in mind to implement the video-interface as soon as you have the necessary postMessage hooks. Implementing the video-interface will automatically enable features such as AMP-managed autoplay for your player.

@aghassemi aghassemi merged commit e4900fc into ampproject:master Nov 11, 2016
@unbug
Copy link
Contributor Author

unbug commented Nov 11, 2016

@aghassemi Thanks, my team already created a ticket forvideo-interface, we'll keep that in mind :)
Anyway when I'll see https://cdn.ampproject.org/v0/amp-hulu-0.1.js online?

dreamofabear pushed a commit to dreamofabear/amphtml that referenced this pull request Nov 15, 2016
Lith pushed a commit to Lith/amphtml that referenced this pull request Dec 22, 2016
Lith pushed a commit to Lith/amphtml that referenced this pull request Dec 22, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants