Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
12d320a
Implemented hasAudio from monti
mszylkowski Oct 7, 2021
e938155
Use promises for hasVideoWithAudio
mszylkowski Oct 8, 2021
f41baab
Added tests
mszylkowski Oct 8, 2021
9c2ac35
Merge branch 'main' of github.com:ampproject/amphtml into monti_hasaudio
mszylkowski Oct 11, 2021
2a89621
Use waitForPlaybackMediaLayout
mszylkowski Oct 13, 2021
bd7e44f
Use waitForMediaLayout
mszylkowski Oct 13, 2021
2cb5033
Use load signal on visual test
mszylkowski Oct 13, 2021
bd65c15
Added return
mszylkowski Oct 14, 2021
155beb7
Merge branch 'main' of github.com:ampproject/amphtml into monti_hasaudio
mszylkowski Oct 14, 2021
adf1f83
Merge branch 'main' of github.com:ampproject/amphtml into monti_hasaudio
mszylkowski Oct 14, 2021
b361875
Remove consolelog
mszylkowski Oct 14, 2021
3527acd
Revert flaky tests
mszylkowski Oct 18, 2021
cb32266
Strict equality check
mszylkowski Oct 18, 2021
5c71d58
Added console logs meanwhile
mszylkowski Oct 26, 2021
7adc100
Wait on story for elements that resolve on runtime
mszylkowski Oct 26, 2021
93193fd
Remove unused const
mszylkowski Oct 26, 2021
14a680a
Revert logs
mszylkowski Oct 26, 2021
05ec95a
Move wait promise to audio.js
mszylkowski Oct 26, 2021
0502963
Streamline has videos with audio
mszylkowski Oct 26, 2021
3b27499
Clean comments
mszylkowski Oct 26, 2021
4bb20b9
Merge branch 'main' of github.com:ampproject/amphtml into monti_hasaudio
mszylkowski Oct 27, 2021
b9657eb
Merge branch 'main' of github.com:ampproject/amphtml into monti_hasaudio
mszylkowski Dec 15, 2021
9935ac8
Fixed merge errors
mszylkowski Dec 15, 2021
a04aa88
Merge branch 'main' of github.com:ampproject/amphtml into monti_hasaudio
mszylkowski Jan 18, 2022
715896d
Added missing import
mszylkowski Jan 18, 2022
0d8acea
Linting
mszylkowski Jan 18, 2022
5a5787a
Linting added comma
mszylkowski Jan 18, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 29 additions & 2 deletions examples/amp-story/videos-google-cache.html
Original file line number Diff line number Diff line change
Expand Up @@ -61,15 +61,42 @@
<amp-story-page id="page-3">
<amp-story-grid-layer template="fill">
<amp-video autoplay loop cache="google"
id="video2"
id="video3"
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-grid-layer><span class="page-num">3</span></amp-story-grid-layer>
</amp-story-page>

<amp-story-page id="page-4">
<amp-story-grid-layer template="fill">
<amp-video autoplay loop cache="google"
id="video4"
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">4</span></amp-story-grid-layer>
</amp-story-page>
<amp-story-page id="page-5">
<amp-story-grid-layer template="fill">
<amp-video autoplay loop cache="google"
id="video5"
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">5</span></amp-story-grid-layer>
</amp-story-page>
</amp-story>
</body>
Expand Down
34 changes: 22 additions & 12 deletions extensions/amp-story/1.0/amp-story-page.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,10 @@ import {
getStoreService,
} from './amp-story-store-service';
import {AnimationManager, hasAnimations} from './animation';
import {upgradeBackgroundAudio} from './audio';
import {
upgradeBackgroundAudio,
waitForElementsWithUnresolvedAudio,
} from './audio';
import {EventType, dispatch} from './events';
import {renderLoadingSpinner, toggleLoadingSpinner} from './loading-spinner';
import {getMediaPerformanceMetricsService} from './media-performance-metrics-service';
Expand Down Expand Up @@ -520,7 +523,7 @@ export class AmpStoryPage extends AMP.BaseElement {

return Promise.all([
this.beforeVisible(),
this.waitForMediaLayout_(),
this.waitForMediaLayout_().then(() => this.markPageAsLoaded_()),
this.mediaPoolPromise_,
]);
}
Expand Down Expand Up @@ -592,7 +595,7 @@ export class AmpStoryPage extends AMP.BaseElement {
mediaEl.addEventListener('error', resolve, true /* useCapture */);
});
});
return Promise.all(mediaPromises).then(() => this.markPageAsLoaded_());
return Promise.all(mediaPromises);
Comment thread
mszylkowski marked this conversation as resolved.
}

/**
Expand Down Expand Up @@ -1284,28 +1287,35 @@ export class AmpStoryPage extends AMP.BaseElement {
}

/**
* Checks if the page has any audio.
* Checks if the page has audio elements or video elements with audio.
* @private
*/
checkPageHasAudio_() {
const pageHasAudio =
const hasAudioElements =
this.element.hasAttribute('background-audio') ||
this.element.querySelector('amp-audio') ||
this.hasVideoWithAudio_();
this.element.querySelector('amp-audio');

const hasAudioPromise = hasAudioElements
? Promise.resolve(true)
: this.hasVideoWithAudio_();

this.storeService_.dispatch(Action.TOGGLE_PAGE_HAS_AUDIO, pageHasAudio);
hasAudioPromise.then((hasAudio) =>
this.storeService_.dispatch(Action.TOGGLE_PAGE_HAS_AUDIO, hasAudio)
);
}

/**
* Checks if the page has any videos with audio.
* @return {boolean}
* @return {!Promise<boolean>}
* @private
*/
hasVideoWithAudio_() {
const ampVideoEls = this.element.querySelectorAll('amp-video');
return Array.prototype.some.call(
ampVideoEls,
(video) => !video.hasAttribute('noaudio')
return waitForElementsWithUnresolvedAudio(this.element).then(() =>
Array.prototype.some.call(
ampVideoEls,
(video) => !video.hasAttribute('noaudio')
)
);
}

Expand Down
13 changes: 13 additions & 0 deletions extensions/amp-story/1.0/audio.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,16 @@ export function upgradeBackgroundAudio(element, loop = true) {

return audioEl;
}

/**
* Waits for elements that can resolve their audio status on runtime.
* @param {!Element} element the root
* @return {!Promise}
*/
export function waitForElementsWithUnresolvedAudio(element) {
return Promise.all(
Array.from(element.querySelectorAll('amp-video[cache]:not([noaudio])')).map(
(el) => el.getImpl()
Comment thread
mszylkowski marked this conversation as resolved.
)
);
}
49 changes: 49 additions & 0 deletions extensions/amp-video/0.1/test/test-video-cache.js
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,55 @@ describes.realWin('amp-video cached-sources', {amp: true}, (env) => {
});
});

describe('has_audio field', async () => {
it('should set noaudio if the cache responds with has_audio: false', async () => {
env.sandbox.stub(xhrService, 'fetch').resolves({
json: () =>
Promise.resolve({
'has_audio': false,
'sources': [
{'url': 'video.mp4', 'bitrate_kbps': 700, 'type': 'video/mp4'},
],
}),
});
const videoEl = createVideo([{src: 'video.mp4'}]);
await fetchCachedSources(videoEl, env.ampdoc);

expect(videoEl).to.have.attribute('noaudio');
});

it('should not set noaudio if the cache responds with has_audio: true', async () => {
env.sandbox.stub(xhrService, 'fetch').resolves({
json: () =>
Promise.resolve({
'has_audio': true,
'sources': [
{'url': 'video.mp4', 'bitrate_kbps': 700, 'type': 'video/mp4'},
],
}),
});
const videoEl = createVideo([{src: 'video.mp4'}]);
await fetchCachedSources(videoEl, env.ampdoc);

expect(videoEl).to.not.have.attribute('noaudio');
});

it('should not set noaudio if the cache responds without has_audio', 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.ampdoc);

expect(videoEl).to.not.have.attribute('noaudio');
});
});

function createVideo(children) {
const videoEl = createElementWithAttributes(env.win.document, 'amp-video', {
'cache': 'google',
Expand Down
17 changes: 14 additions & 3 deletions extensions/amp-video/0.1/video-cache.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,10 @@ export function fetchCachedSources(
return Services.xhrFor(win).fetch(requestUrl, {prerenderSafe: true});
})
.then((response) => response.json())
.then((jsonResponse) =>
applySourcesToVideo(videoEl, jsonResponse['sources'], maxBitrate)
)
.then((jsonResponse) => {
applySourcesToVideo(videoEl, jsonResponse['sources'], maxBitrate);
applyAudioInfoToVideo(videoEl, jsonResponse['has_audio']);
})
.catch(() => {
// If cache fails, video should still load properly.
});
Expand Down Expand Up @@ -162,6 +163,16 @@ function applySourcesToVideo(videoEl, sources, maxBitrate) {
});
}

/**
* @param {!Element} videoEl
* @param {boolean|undefined} hasAudio
*/
function applyAudioInfoToVideo(videoEl, hasAudio) {
if (hasAudio === false) {
videoEl.setAttribute('noaudio', '');
}
}

/**
* If present, moves the src attribute to a source element to enable playing
* from multiple sources: the cached ones and the fallback initial src.
Expand Down