-
Notifications
You must be signed in to change notification settings - Fork 3.9k
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 audio support for amp-story #11509
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bunch of stylistic comments. Deferring main logic review to @aghassemi . However, should there be tests here?
extensions/amp-story/0.1/audio.js
Outdated
|
||
|
||
/** @typedef {{ source: AudioBufferSourceNode, gainNode: GainNode }} */ | ||
let AudioSource; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be suffixed with Def
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed entirely; it's actually unused now.
extensions/amp-story/0.1/audio.js
Outdated
const VOLUME_CHANGE_DURATION_MS = 500; | ||
|
||
/** | ||
* @const {!function(number): number} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove !
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
extensions/amp-story/0.1/audio.js
Outdated
* @const {string} | ||
*/ | ||
const PLAYABLE_ID_PREFIX = 'i-amphtml-playable-'; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: remove extra line. Just one-line separator b/w constants.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
extensions/amp-story/0.1/audio.js
Outdated
|
||
|
||
export class AudioManager { | ||
constructor(win, rootElement) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
jsdoc for args
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
extensions/amp-story/0.1/audio.js
Outdated
* represented by the specified sourceElement. | ||
*/ | ||
createPlayable_(sourceElement) { | ||
if (!(sourceElement instanceof Element)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
User assertElement
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
extensions/amp-story/0.1/audio.js
Outdated
} | ||
|
||
|
||
nowPlayingChanged_() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
jsdoc
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
extensions/amp-story/0.1/audio.js
Outdated
|
||
|
||
class Playable { | ||
constructor(win, sourceElement) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
jsdoc
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
extensions/amp-story/0.1/audio.js
Outdated
*/ | ||
this.sourceElement_ = sourceElement; | ||
|
||
this.depth_ = Playable.calculateDepthForElement(sourceElement); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
jsdoc
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
extensions/amp-story/0.1/audio.js
Outdated
* An HTMLMediaElement that potentially has audio. | ||
*/ | ||
class MediaElementPlayable extends Playable { | ||
constructor(win, element) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
jsdoc
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Deferred to super constructor
extensions/amp-story/0.1/audio.js
Outdated
class MediaElementPlayable extends Playable { | ||
constructor(win, element) { | ||
super(win, element); | ||
this.element_ = element; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
jsdoc
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Deferred to sourceElement
in super class
extensions/amp-story/0.1/audio.js
Outdated
/** | ||
* @const {string} | ||
*/ | ||
const PLAYABLE_ID_PREFIX = 'i-amphtml-playable-'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: maybe i-amphtml-playable-audio-
to account for other playable types later given nextId_
is scoped to audio.js
only?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
extensions/amp-story/0.1/audio.js
Outdated
export function upgradeBackgroundAudio(element) { | ||
if (element.hasAttribute('background-audio')) { | ||
const audioEl = element.ownerDocument.createElement('audio'); | ||
const audioSrc = element.getAttribute('background-audio'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do one of assertHttpsUrl
or assertAbsoluteHttpOrHttpsUrl
on audioSrc
depending on your requirements.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
extensions/amp-story/0.1/audio.js
Outdated
audioEl.setAttribute('src', audioSrc); | ||
audioEl.setAttribute('preload', 'auto'); | ||
audioEl.setAttribute('loop', ''); | ||
audioEl.setAttribute('autoplay', ''); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is there a point in adding autoplay
given mobile ignores it and desktop will soon ignore it too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They only ignore it if it's unmuted, right? Added muted
attribute.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not sure what they do for "audio", autoplay for muted audio is sort of strange although you may get some preloading advantages by using autoplay attr? regardless, this looks fine to me.
extensions/amp-story/0.1/audio.js
Outdated
*/ | ||
load(sourceElement) { | ||
const playable = this.getPlayable_(sourceElement) || | ||
this.createPlayable_(sourceElement); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: alternative pattern that I slightly prefer : getOrCreatePlayable_
|
||
/** | ||
* @param {!Element} sourceElement The element causing audio to be played. | ||
* @return {!Playable} The {@link Playable} instance to play the audio |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
!Playable
is not correct since this can return undefined
. How about making it throw (by using dev().assert
) if sourceElement
is not Element
or HTMLMediaElement
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. It actually has to be Element
AND HTMLMediaElement
, but since HTMLMediaElement
implies Element
, I only checked for HTMLMediaElement
.
extensions/amp-story/0.1/audio.js
Outdated
/** | ||
* Loads the audio for the specified. | ||
* @param {!Element} sourceElement The element whose audio should be loaded. | ||
*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
document return param
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
extensions/amp-story/0.1/audio.js
Outdated
} | ||
|
||
/** @private */ | ||
getMediaElementChildren_(element) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
doesn't seem to be used in this file (and is private
) is used outside, make public
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed
extensions/amp-story/0.1/audio.js
Outdated
* @private | ||
*/ | ||
addToNowPlaying_(playable) { | ||
const index = this.nowPlaying_.indexOf(playable); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: .includes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
prioritiesByDepth[depth] = depthCount - iteration; | ||
}); | ||
|
||
// Set volumes on each of the playables that is currently playing, based on |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
very cool!
extensions/amp-story/0.1/audio.js
Outdated
} | ||
|
||
/** @override */ | ||
setVolume(volume, durationMs, unusedEasingFn) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's document somewhere the iOS's restriction on setting volume and how that's handled.
Filed #11546 to track the unit tests. |
This is utility class to help manage playback of audio for the
amp-story
component.