-
Notifications
You must be signed in to change notification settings - Fork 3.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
✨ [Story Video] Connect CacheUrl service to amp-video and load sources (
#33466) * Added canonical to videos example * Started video cache * Use cdn url from url-impl * Remove unnecessary | null * Undo videos.html * Remove console.log * Using ternary operator for reduce * Account for cached docs * Update logic with toolbox * Added service * Undo amp-video * Added cache url service * Added owners * Cache url to video * Simplified cache example * Updated title * Changed name to amp-cache-url of folder * Update readme * Update comments * Remove example * Updated readme * Added code * Fixed tests * Removed comment * Added some more tests * Fixed cdnurl * Update names of docSupports * Fix cacheUrl not replacing * updated cacheDomain param name * Check not cached doc to add cache sources * improved implementation from comments * added tests * Added gregable file on examples * Added warning * Uppercase user error * Updated opt in * Fix response.json is promise * Updated test * Fixed toArray import * Fixed visibilityState * Use helper functions * Added tests to amp-cache-url * Update extensions/amp-cache-url/0.1/test/test-amp-cache-url.js Co-authored-by: Ryan Cebulko <ryan@cebulko.com> * Using extensionScriptInNode with win * Updated tests to match comments * Not export applySources Co-authored-by: Gabriel Majoulet <gmajoulet@google.com> Co-authored-by: Ryan Cebulko <ryan@cebulko.com> Co-authored-by: Gabriel Majoulet <gmajoulet@google.com>
- Loading branch information
1 parent
0c4e5aa
commit efd8b56
Showing
10 changed files
with
438 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
<!doctype html> | ||
<html ⚡ lang="en"> | ||
<head> | ||
<meta charset="utf-8"> | ||
<link rel="canonical" href="https://amp.dev/hello/ampconf.html"> | ||
<meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1"> | ||
<script async src="https://cdn.ampproject.org/v0.js"></script> | ||
<title>Example story with Google cache videos</title> | ||
|
||
<script async custom-element="amp-story" src="https://cdn.ampproject.org/v0/amp-story-1.0.js"></script> | ||
<script async custom-element="amp-video" src="https://cdn.ampproject.org/v0/amp-video-0.1.js"></script> | ||
<script async custom-element="amp-cache-url" src="https://cdn.ampproject.org/v0/amp-cache-url-0.1.js"></script> | ||
|
||
<style amp-boilerplate>body{-webkit-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-moz-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-ms-animation:-amp-start 8s steps(1,end) 0s 1 normal both;animation:-amp-start 8s steps(1,end) 0s 1 normal both}@-webkit-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-moz-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-ms-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-o-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}</style><noscript><style amp-boilerplate>body{-webkit-animation:none;-moz-animation:none;-ms-animation:none;animation:none}</style></noscript> | ||
<style amp-custom> | ||
.page-num { | ||
display: block; | ||
position: absolute; | ||
left: 30px; | ||
top: 30px; | ||
width: 30px; | ||
text-align: center; | ||
font-family: sans-serif; | ||
background-color: white; | ||
border-radius: 50%; | ||
} | ||
</style> | ||
</head> | ||
<body> | ||
<amp-story standalone id="cats" | ||
title="Key Highlights of AMP Conf 2018" publisher="The AMP team"> | ||
|
||
<amp-story-page id="page-1"> | ||
<amp-story-grid-layer template="fill"> | ||
<amp-video autoplay loop cache="google" | ||
id="video1" | ||
width="400" | ||
height="750" | ||
poster="img-city1.jpeg#1" | ||
layout="fill"> | ||
<source src="./video/stamp.mp4" type="video/mp4"> | ||
</amp-video> | ||
</amp-story-grid-layer> | ||
<amp-story-grid-layer><span class="page-num">1</span></amp-story-grid-layer> | ||
</amp-story-page> | ||
|
||
<amp-story-page id="page-2"> | ||
<amp-story-grid-layer template="fill"> | ||
<amp-video autoplay loop cache="google" | ||
id="video2" | ||
width="400" | ||
height="750" | ||
poster="img-city1.jpeg#2" | ||
layout="fill"> | ||
<source src="./video/stamp-animation.mp4" type="video/mp4"> | ||
</amp-video> | ||
</amp-story-grid-layer> | ||
<amp-story-grid-layer><span class="page-num">2</span></amp-story-grid-layer> | ||
</amp-story-page> | ||
|
||
<amp-story-page id="page-3"> | ||
<amp-story-grid-layer template="fill"> | ||
<amp-video autoplay loop cache="google" | ||
id="video2" | ||
width="400" | ||
height="750" | ||
poster="img-city1.jpeg#2" | ||
layout="fill"> | ||
<source src="https://gregable.com/re2ae3Ei/sample-mp4-file.mp4?amp_video_host_url=gregable.com" type="video/mp4"> | ||
</amp-video> | ||
</amp-story-grid-layer> | ||
<amp-story-grid-layer><span class="page-num">2</span></amp-story-grid-layer> | ||
</amp-story-page> | ||
</amp-story> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,190 @@ | ||
/** | ||
* Copyright 2021 The AMP HTML Authors. All Rights Reserved. | ||
* | ||
* 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. | ||
*/ | ||
|
||
import {AmpCacheUrlService} from '../../../amp-cache-url/0.1/amp-cache-url'; | ||
import {Services} from '../../../../src/services'; | ||
import {createElementWithAttributes} from '../../../../src/dom'; | ||
import {createExtensionScript} from '../../../../src/service/extension-script'; | ||
import {fetchCachedSources} from '../video-cache'; | ||
import {xhrServiceForTesting} from '../../../../src/service/xhr-impl'; | ||
|
||
describes.realWin('amp-video cached-sources', {amp: true}, (env) => { | ||
let xhrService; | ||
let cacheUrlService; | ||
|
||
beforeEach(() => { | ||
xhrService = xhrServiceForTesting(env.win); | ||
env.sandbox.stub(Services, 'xhrFor').returns(xhrService); | ||
|
||
cacheUrlService = new AmpCacheUrlService(); | ||
env.sandbox | ||
.stub(Services, 'cacheUrlServicePromiseForDoc') | ||
.resolves(cacheUrlService); | ||
env.win.document.head.appendChild( | ||
createExtensionScript(env.win, 'amp-cache-url', '0.1') | ||
); | ||
env.sandbox | ||
.stub(Services, 'documentInfoForDoc') | ||
.returns({sourceUrl: 'https://example.com'}); | ||
}); | ||
|
||
describe('select sources', () => { | ||
it('should select the source if there is only one source', async () => { | ||
const videoEl = createVideo([{src: 'video1.mp4'}]); | ||
const xhrSpy = env.sandbox.spy(xhrService, 'fetch'); | ||
|
||
await fetchCachedSources(videoEl, env.win); | ||
|
||
expect(xhrSpy).to.have.been.calledWith( | ||
'https://example-com.cdn.ampproject.org/mbv/s/example.com/video1.mp4' | ||
); | ||
}); | ||
|
||
it('should select the first source if there are similar sources', async () => { | ||
const videoEl = createVideo([{src: 'video1.mp4'}, {src: 'video2.mp4'}]); | ||
const xhrSpy = env.sandbox.spy(xhrService, 'fetch'); | ||
|
||
await fetchCachedSources(videoEl, env.win); | ||
|
||
expect(xhrSpy).to.have.been.calledWith( | ||
'https://example-com.cdn.ampproject.org/mbv/s/example.com/video1.mp4' | ||
); | ||
}); | ||
|
||
it('should select the mp4 source if there are many sources', async () => { | ||
const videoEl = createVideo([ | ||
{src: 'video1.mp4'}, | ||
{src: 'video2.mp4', type: 'video/mp4'}, | ||
]); | ||
const xhrSpy = env.sandbox.spy(xhrService, 'fetch'); | ||
|
||
await fetchCachedSources(videoEl, env.win); | ||
|
||
expect(xhrSpy).to.have.been.calledWith( | ||
'https://example-com.cdn.ampproject.org/mbv/s/example.com/video2.mp4' | ||
); | ||
}); | ||
}); | ||
|
||
describe('url forming', () => { | ||
it('should send the request to the correct address if the video has an absolute url', async () => { | ||
const videoEl = createVideo([{'src': 'https://website.com/video.html'}]); | ||
const xhrSpy = env.sandbox.spy(xhrService, 'fetch'); | ||
|
||
await fetchCachedSources(videoEl, env.win); | ||
|
||
expect(xhrSpy).to.have.been.calledWith( | ||
'https://website-com.cdn.ampproject.org/mbv/s/website.com/video.html' | ||
); | ||
}); | ||
|
||
it('should send the request to the correct address if the video has a relative url', async () => { | ||
const videoEl = createVideo([{'src': 'video.html'}]); | ||
const xhrSpy = env.sandbox.spy(xhrService, 'fetch'); | ||
|
||
await fetchCachedSources(videoEl, env.win); | ||
|
||
expect(xhrSpy).to.have.been.calledWith( | ||
'https://example-com.cdn.ampproject.org/mbv/s/example.com/video.html' | ||
); | ||
}); | ||
}); | ||
|
||
describe('add sources', () => { | ||
it('should set the correct attributes on the source added', async () => { | ||
env.sandbox.stub(xhrService, 'fetch').resolves({ | ||
json: () => | ||
Promise.resolve({ | ||
sources: [ | ||
{'url': 'video1.mp4', 'bitrate_kbps': 700, type: 'video/mp4'}, | ||
], | ||
}), | ||
}); | ||
|
||
const videoEl = createVideo([{src: 'video.mp4'}]); | ||
await fetchCachedSources(videoEl, env.win); | ||
|
||
const addedSource = videoEl.querySelector('source'); | ||
expect(addedSource.getAttribute('src')).to.equal('video1.mp4'); | ||
expect(addedSource.getAttribute('data-bitrate')).to.equal('700'); | ||
expect(addedSource.getAttribute('type')).to.equal('video/mp4'); | ||
}); | ||
|
||
it('should add the sources sorted by bitrate', async () => { | ||
env.sandbox.stub(xhrService, 'fetch').resolves({ | ||
json: () => | ||
Promise.resolve({ | ||
sources: [ | ||
{'url': 'video1.mp4', 'bitrate_kbps': 700, type: 'video/mp4'}, | ||
{'url': 'video2.mp4', 'bitrate_kbps': 2000, type: 'video/mp4'}, | ||
{'url': 'video3.mp4', 'bitrate_kbps': 1500, type: 'video/mp4'}, | ||
], | ||
}), | ||
}); | ||
|
||
const videoEl = createVideo([{src: 'video.mp4'}]); | ||
|
||
await fetchCachedSources(videoEl, env.win); | ||
|
||
const addedSources = videoEl.querySelectorAll('source'); | ||
expect(addedSources[0].getAttribute('data-bitrate')).to.equal('2000'); | ||
expect(addedSources[1].getAttribute('data-bitrate')).to.equal('1500'); | ||
expect(addedSources[2].getAttribute('data-bitrate')).to.equal('700'); | ||
}); | ||
}); | ||
|
||
describe('end to end', () => { | ||
it('should create the sources from the request with the correct attributes', async () => { | ||
env.sandbox.stub(xhrService, 'fetch').resolves({ | ||
json: () => | ||
Promise.resolve({ | ||
sources: [ | ||
{'url': 'video.mp4', 'bitrate_kbps': 700, 'type': 'video/mp4'}, | ||
], | ||
}), | ||
}); | ||
|
||
const videoEl = createVideo([{src: 'video.mp4'}]); | ||
|
||
await fetchCachedSources(videoEl, env.win); | ||
|
||
expect(videoEl.querySelector('source[data-bitrate]')).to.not.be.null; | ||
}); | ||
it('should not create the sources if there is amp-orig-src attribute', async () => { | ||
const videoEl = createVideo([{'src': 'video.mp4', 'amp-orig-src': ''}]); | ||
await fetchCachedSources(videoEl, env.win); | ||
|
||
expect(videoEl.querySelector('source[data-bitrate]')).to.be.null; | ||
}); | ||
}); | ||
|
||
function createVideo(children) { | ||
const videoEl = createElementWithAttributes(env.win.document, 'amp-video', { | ||
'cache': 'google', | ||
'layout': 'fill', | ||
}); | ||
children.forEach((childJson) => { | ||
const sourceEl = createElementWithAttributes( | ||
env.win.document, | ||
'source', | ||
childJson | ||
); | ||
videoEl.appendChild(sourceEl); | ||
}); | ||
env.win.document.body.appendChild(videoEl); | ||
return videoEl; | ||
} | ||
}); |
Oops, something went wrong.